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 893// imm0_31 predicate - True if the immediate is in the range [0,31] 894def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 895 return ((uint64_t)Imm) < 32; 896}]> { 897 let ParserMatchClass = Imm0_31Operand; 898} 899 900// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 901// instead of Constant (ImmLeaf) 902def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 903 return ((uint64_t)Imm) < 32; 904}]> { 905 let ParserMatchClass = Imm0_31Operand; 906} 907 908// True if the 32-bit immediate is in the range [0,31] 909def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 910 return ((uint64_t)Imm) < 32; 911}]> { 912 let ParserMatchClass = Imm0_31Operand; 913} 914 915// imm0_1 predicate - True if the immediate is in the range [0,1] 916def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 917 return ((uint64_t)Imm) < 2; 918}]> { 919 let ParserMatchClass = Imm0_1Operand; 920} 921 922// timm0_1 - as above, but use TargetConstant (TImmLeaf) 923def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 924 return ((uint64_t)Imm) < 2; 925}]> { 926 let ParserMatchClass = Imm0_1Operand; 927} 928 929// imm0_15 predicate - True if the immediate is in the range [0,15] 930def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 931 return ((uint64_t)Imm) < 16; 932}]> { 933 let ParserMatchClass = Imm0_15Operand; 934} 935 936// imm0_7 predicate - True if the immediate is in the range [0,7] 937def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 938 return ((uint64_t)Imm) < 8; 939}]> { 940 let ParserMatchClass = Imm0_7Operand; 941} 942 943// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 944def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 945 return ((uint32_t)Imm) < 8; 946}]> { 947 let ParserMatchClass = Imm0_7Operand; 948} 949 950// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 951def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 952 return ((uint32_t)Imm) < 16; 953}]> { 954 let ParserMatchClass = Imm0_15Operand; 955} 956 957// An arithmetic shifter operand: 958// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 959// {5-0} - imm6 960class arith_shift<ValueType Ty, int width> : Operand<Ty> { 961 let PrintMethod = "printShifter"; 962 let ParserMatchClass = !cast<AsmOperandClass>( 963 "ArithmeticShifterOperand" # width); 964} 965 966def arith_shift32 : arith_shift<i32, 32>; 967def arith_shift64 : arith_shift<i64, 64>; 968 969class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 970 : Operand<Ty>, 971 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 972 let PrintMethod = "printShiftedRegister"; 973 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 974} 975 976def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 977def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 978 979def gi_arith_shifted_reg32 : 980 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 981 GIComplexPatternEquiv<arith_shifted_reg32>; 982 983def gi_arith_shifted_reg64 : 984 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 985 GIComplexPatternEquiv<arith_shifted_reg64>; 986 987// An arithmetic shifter operand: 988// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 989// {5-0} - imm6 990class logical_shift<int width> : Operand<i32> { 991 let PrintMethod = "printShifter"; 992 let ParserMatchClass = !cast<AsmOperandClass>( 993 "LogicalShifterOperand" # width); 994} 995 996def logical_shift32 : logical_shift<32>; 997def logical_shift64 : logical_shift<64>; 998 999class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1000 : Operand<Ty>, 1001 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1002 let PrintMethod = "printShiftedRegister"; 1003 let MIOperandInfo = (ops regclass, shiftop); 1004} 1005 1006def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1007def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1008 1009def gi_logical_shifted_reg32 : 1010 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1011 GIComplexPatternEquiv<logical_shifted_reg32>; 1012 1013def gi_logical_shifted_reg64 : 1014 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1015 GIComplexPatternEquiv<logical_shifted_reg64>; 1016 1017// A logical vector shifter operand: 1018// {7-6} - shift type: 00 = lsl 1019// {5-0} - imm6: #0, #8, #16, or #24 1020def logical_vec_shift : Operand<i32> { 1021 let PrintMethod = "printShifter"; 1022 let EncoderMethod = "getVecShifterOpValue"; 1023 let ParserMatchClass = LogicalVecShifterOperand; 1024} 1025 1026// A logical vector half-word shifter operand: 1027// {7-6} - shift type: 00 = lsl 1028// {5-0} - imm6: #0 or #8 1029def logical_vec_hw_shift : Operand<i32> { 1030 let PrintMethod = "printShifter"; 1031 let EncoderMethod = "getVecShifterOpValue"; 1032 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1033} 1034 1035// A vector move shifter operand: 1036// {0} - imm1: #8 or #16 1037def move_vec_shift : Operand<i32> { 1038 let PrintMethod = "printShifter"; 1039 let EncoderMethod = "getMoveVecShifterOpValue"; 1040 let ParserMatchClass = MoveVecShifterOperand; 1041} 1042 1043let DiagnosticType = "AddSubSecondSource" in { 1044 def AddSubImmOperand : AsmOperandClass { 1045 let Name = "AddSubImm"; 1046 let ParserMethod = "tryParseImmWithOptionalShift"; 1047 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1048 } 1049 def AddSubImmNegOperand : AsmOperandClass { 1050 let Name = "AddSubImmNeg"; 1051 let ParserMethod = "tryParseImmWithOptionalShift"; 1052 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1053 } 1054} 1055// An ADD/SUB immediate shifter operand: 1056// second operand: 1057// {7-6} - shift type: 00 = lsl 1058// {5-0} - imm6: #0 or #12 1059class addsub_shifted_imm<ValueType Ty> 1060 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1061 let PrintMethod = "printAddSubImm"; 1062 let EncoderMethod = "getAddSubImmOpValue"; 1063 let ParserMatchClass = AddSubImmOperand; 1064 let MIOperandInfo = (ops i32imm, i32imm); 1065} 1066 1067class addsub_shifted_imm_neg<ValueType Ty> 1068 : Operand<Ty> { 1069 let EncoderMethod = "getAddSubImmOpValue"; 1070 let ParserMatchClass = AddSubImmNegOperand; 1071 let MIOperandInfo = (ops i32imm, i32imm); 1072} 1073 1074def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1075def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1076def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1077def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1078 1079def gi_addsub_shifted_imm32 : 1080 GIComplexOperandMatcher<s32, "selectArithImmed">, 1081 GIComplexPatternEquiv<addsub_shifted_imm32>; 1082 1083def gi_addsub_shifted_imm64 : 1084 GIComplexOperandMatcher<s64, "selectArithImmed">, 1085 GIComplexPatternEquiv<addsub_shifted_imm64>; 1086 1087class neg_addsub_shifted_imm<ValueType Ty> 1088 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1089 let PrintMethod = "printAddSubImm"; 1090 let EncoderMethod = "getAddSubImmOpValue"; 1091 let ParserMatchClass = AddSubImmOperand; 1092 let MIOperandInfo = (ops i32imm, i32imm); 1093} 1094 1095def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1096def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1097 1098def gi_neg_addsub_shifted_imm32 : 1099 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1100 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1101 1102def gi_neg_addsub_shifted_imm64 : 1103 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1104 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1105 1106// An extend operand: 1107// {5-3} - extend type 1108// {2-0} - imm3 1109def arith_extend : Operand<i32> { 1110 let PrintMethod = "printArithExtend"; 1111 let ParserMatchClass = ExtendOperand; 1112} 1113def arith_extend64 : Operand<i32> { 1114 let PrintMethod = "printArithExtend"; 1115 let ParserMatchClass = ExtendOperand64; 1116} 1117 1118// 'extend' that's a lsl of a 64-bit register. 1119def arith_extendlsl64 : Operand<i32> { 1120 let PrintMethod = "printArithExtend"; 1121 let ParserMatchClass = ExtendOperandLSL64; 1122} 1123 1124class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1125 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1126 let PrintMethod = "printExtendedRegister"; 1127 let MIOperandInfo = (ops GPR32, arith_extend); 1128} 1129 1130class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1131 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1132 let PrintMethod = "printExtendedRegister"; 1133 let MIOperandInfo = (ops GPR32, arith_extend64); 1134} 1135 1136def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1137def gi_arith_extended_reg32_i32 : 1138 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1139 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1140 1141def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1142def gi_arith_extended_reg32_i64 : 1143 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1144 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1145 1146def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1147def gi_arith_extended_reg32to64_i64 : 1148 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1149 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1150 1151// Floating-point immediate. 1152def fpimm16 : Operand<f16>, 1153 FPImmLeaf<f16, [{ 1154 return AArch64_AM::getFP16Imm(Imm) != -1; 1155 }], SDNodeXForm<fpimm, [{ 1156 APFloat InVal = N->getValueAPF(); 1157 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1158 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1159 }]>> { 1160 let ParserMatchClass = FPImmOperand; 1161 let PrintMethod = "printFPImmOperand"; 1162} 1163def fpimm32 : Operand<f32>, 1164 FPImmLeaf<f32, [{ 1165 return AArch64_AM::getFP32Imm(Imm) != -1; 1166 }], SDNodeXForm<fpimm, [{ 1167 APFloat InVal = N->getValueAPF(); 1168 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1169 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1170 }]>> { 1171 let ParserMatchClass = FPImmOperand; 1172 let PrintMethod = "printFPImmOperand"; 1173} 1174def fpimm64 : Operand<f64>, 1175 FPImmLeaf<f64, [{ 1176 return AArch64_AM::getFP64Imm(Imm) != -1; 1177 }], SDNodeXForm<fpimm, [{ 1178 APFloat InVal = N->getValueAPF(); 1179 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1180 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1181 }]>> { 1182 let ParserMatchClass = FPImmOperand; 1183 let PrintMethod = "printFPImmOperand"; 1184} 1185 1186def fpimm8 : Operand<i32> { 1187 let ParserMatchClass = FPImmOperand; 1188 let PrintMethod = "printFPImmOperand"; 1189} 1190 1191def fpimm0 : FPImmLeaf<fAny, [{ 1192 return Imm.isExactlyValue(+0.0); 1193}]>; 1194 1195// Vector lane operands 1196class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1197 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1198 let DiagnosticType = "Invalid" # Name; 1199 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1200 let RenderMethod = "addVectorIndexOperands"; 1201} 1202 1203class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1204 : Operand<ty> { 1205 let ParserMatchClass = mc; 1206 let PrintMethod = "printVectorIndex"; 1207} 1208 1209multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1210 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1211 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1212} 1213 1214def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1215def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1216def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1217def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1218def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1219 1220defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1221 [{ return ((uint64_t)Imm) == 1; }]>; 1222defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1223 [{ return ((uint64_t)Imm) < 16; }]>; 1224defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1225 [{ return ((uint64_t)Imm) < 8; }]>; 1226defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1227 [{ return ((uint64_t)Imm) < 4; }]>; 1228defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1229 [{ return ((uint64_t)Imm) < 2; }]>; 1230 1231defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1232 [{ return ((uint64_t)Imm) == 1; }]>; 1233defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1234 [{ return ((uint64_t)Imm) < 16; }]>; 1235defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1236 [{ return ((uint64_t)Imm) < 8; }]>; 1237defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1238 [{ return ((uint64_t)Imm) < 4; }]>; 1239defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1240 [{ return ((uint64_t)Imm) < 2; }]>; 1241 1242def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1243def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1244def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1245def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1246def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1247 1248defm sve_elm_idx_extdup_b 1249 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1250 [{ return ((uint64_t)Imm) < 64; }]>; 1251defm sve_elm_idx_extdup_h 1252 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1253 [{ return ((uint64_t)Imm) < 32; }]>; 1254defm sve_elm_idx_extdup_s 1255 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1256 [{ return ((uint64_t)Imm) < 16; }]>; 1257defm sve_elm_idx_extdup_d 1258 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1259 [{ return ((uint64_t)Imm) < 8; }]>; 1260defm sve_elm_idx_extdup_q 1261 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1262 [{ return ((uint64_t)Imm) < 4; }]>; 1263 1264// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1265// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1266// are encoded as the eight bit value 'abcdefgh'. 1267def simdimmtype10 : Operand<i32>, 1268 FPImmLeaf<f64, [{ 1269 return AArch64_AM::isAdvSIMDModImmType10( 1270 Imm.bitcastToAPInt().getZExtValue()); 1271 }], SDNodeXForm<fpimm, [{ 1272 APFloat InVal = N->getValueAPF(); 1273 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1274 .bitcastToAPInt() 1275 .getZExtValue()); 1276 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1277 }]>> { 1278 let ParserMatchClass = SIMDImmType10Operand; 1279 let PrintMethod = "printSIMDType10Operand"; 1280} 1281 1282 1283//--- 1284// System management 1285//--- 1286 1287// Base encoding for system instruction operands. 1288let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1289class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1290 list<dag> pattern = []> 1291 : I<oops, iops, asm, operands, "", pattern> { 1292 let Inst{31-22} = 0b1101010100; 1293 let Inst{21} = L; 1294} 1295 1296// System instructions which do not have an Rt register. 1297class SimpleSystemI<bit L, dag iops, string asm, string operands, 1298 list<dag> pattern = []> 1299 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1300 let Inst{4-0} = 0b11111; 1301} 1302 1303// System instructions which have an Rt register. 1304class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1305 list<dag> pattern = []> 1306 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1307 Sched<[WriteSys]> { 1308 bits<5> Rt; 1309 let Inst{4-0} = Rt; 1310} 1311 1312// System instructions for transactional memory extension 1313class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1314 string asm, string operands, list<dag> pattern> 1315 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1316 Sched<[WriteSys]> { 1317 let Inst{20-12} = 0b000110011; 1318 let Inst{11-8} = CRm; 1319 let Inst{7-5} = op2; 1320 let DecoderMethod = ""; 1321 1322 let mayLoad = 1; 1323 let mayStore = 1; 1324} 1325 1326// System instructions for transactional memory - single input operand 1327class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1328 : TMBaseSystemI<0b1, CRm, 0b011, 1329 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1330 bits<5> Rt; 1331 let Inst{4-0} = Rt; 1332} 1333 1334// System instructions that pass a register argument 1335// This class assumes the register is for input rather than output. 1336class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1337 list<dag> pattern = []> 1338 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1339 let Inst{20-12} = 0b000110001; 1340 let Inst{11-8} = CRm; 1341 let Inst{7-5} = Op2; 1342} 1343 1344// System instructions for transactional memory - no operand 1345class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1346 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1347 let Inst{4-0} = 0b11111; 1348} 1349 1350// System instructions for exit from transactions 1351class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1352 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1353 Sched<[WriteSys]> { 1354 bits<16> imm; 1355 let Inst{31-24} = 0b11010100; 1356 let Inst{23-21} = op1; 1357 let Inst{20-5} = imm; 1358 let Inst{4-0} = 0b00000; 1359} 1360 1361// Hint instructions that take both a CRm and a 3-bit immediate. 1362// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1363// model patterns with sufficiently fine granularity 1364let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1365 class HintI<string mnemonic> 1366 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1367 [(int_aarch64_hint imm0_127:$imm)]>, 1368 Sched<[WriteHint]> { 1369 bits <7> imm; 1370 let Inst{20-12} = 0b000110010; 1371 let Inst{11-5} = imm; 1372 } 1373 1374// System instructions taking a single literal operand which encodes into 1375// CRm. op2 differentiates the opcodes. 1376def BarrierAsmOperand : AsmOperandClass { 1377 let Name = "Barrier"; 1378 let ParserMethod = "tryParseBarrierOperand"; 1379} 1380def barrier_op : Operand<i32> { 1381 let PrintMethod = "printBarrierOption"; 1382 let ParserMatchClass = BarrierAsmOperand; 1383} 1384def BarriernXSAsmOperand : AsmOperandClass { 1385 let Name = "BarriernXS"; 1386 let ParserMethod = "tryParseBarriernXSOperand"; 1387} 1388def barrier_nxs_op : Operand<i32> { 1389 let PrintMethod = "printBarriernXSOption"; 1390 let ParserMatchClass = BarriernXSAsmOperand; 1391} 1392class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1393 list<dag> pattern = []> 1394 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1395 Sched<[WriteBarrier]> { 1396 bits<4> CRm; 1397 let Inst{20-12} = 0b000110011; 1398 let Inst{11-8} = CRm; 1399 let Inst{7-5} = opc; 1400} 1401 1402class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1403 : SimpleSystemI<0, (ins), asm, "", pattern>, 1404 Sched<[]> { 1405 bits<4> CRm; 1406 let CRm = 0b0011; 1407 let Inst{31-12} = 0b11010101000000110010; 1408 let Inst{11-8} = CRm; 1409 let Inst{7-5} = op2; 1410 let Inst{4-0} = 0b11111; 1411} 1412 1413// MRS/MSR system instructions. These have different operand classes because 1414// a different subset of registers can be accessed through each instruction. 1415def MRSSystemRegisterOperand : AsmOperandClass { 1416 let Name = "MRSSystemRegister"; 1417 let ParserMethod = "tryParseSysReg"; 1418 let DiagnosticType = "MRS"; 1419} 1420// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1421def mrs_sysreg_op : Operand<i32> { 1422 let ParserMatchClass = MRSSystemRegisterOperand; 1423 let DecoderMethod = "DecodeMRSSystemRegister"; 1424 let PrintMethod = "printMRSSystemRegister"; 1425} 1426 1427def MSRSystemRegisterOperand : AsmOperandClass { 1428 let Name = "MSRSystemRegister"; 1429 let ParserMethod = "tryParseSysReg"; 1430 let DiagnosticType = "MSR"; 1431} 1432def msr_sysreg_op : Operand<i32> { 1433 let ParserMatchClass = MSRSystemRegisterOperand; 1434 let DecoderMethod = "DecodeMSRSystemRegister"; 1435 let PrintMethod = "printMSRSystemRegister"; 1436} 1437 1438def PSBHintOperand : AsmOperandClass { 1439 let Name = "PSBHint"; 1440 let ParserMethod = "tryParsePSBHint"; 1441} 1442def psbhint_op : Operand<i32> { 1443 let ParserMatchClass = PSBHintOperand; 1444 let PrintMethod = "printPSBHintOp"; 1445 let MCOperandPredicate = [{ 1446 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1447 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1448 if (!MCOp.isImm()) 1449 return false; 1450 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1451 }]; 1452} 1453 1454def BTIHintOperand : AsmOperandClass { 1455 let Name = "BTIHint"; 1456 let ParserMethod = "tryParseBTIHint"; 1457} 1458def btihint_op : Operand<i32> { 1459 let ParserMatchClass = BTIHintOperand; 1460 let PrintMethod = "printBTIHintOp"; 1461 let MCOperandPredicate = [{ 1462 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1463 if (!MCOp.isImm()) 1464 return false; 1465 return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr; 1466 }]; 1467} 1468 1469class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1470 "mrs", "\t$Rt, $systemreg"> { 1471 bits<16> systemreg; 1472 let Inst{20-5} = systemreg; 1473 let DecoderNamespace = "Fallback"; 1474} 1475 1476// FIXME: Some of these def NZCV, others don't. Best way to model that? 1477// Explicitly modeling each of the system register as a register class 1478// would do it, but feels like overkill at this point. 1479class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1480 "msr", "\t$systemreg, $Rt"> { 1481 bits<16> systemreg; 1482 let Inst{20-5} = systemreg; 1483 let DecoderNamespace = "Fallback"; 1484} 1485 1486def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1487 let Name = "SystemPStateFieldWithImm0_15"; 1488 let ParserMethod = "tryParseSysReg"; 1489} 1490def pstatefield4_op : Operand<i32> { 1491 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1492 let PrintMethod = "printSystemPStateField"; 1493} 1494 1495// Instructions to modify PSTATE, no input reg 1496let Defs = [NZCV] in 1497class PstateWriteSimple<dag iops, string asm, string operands> 1498 : SimpleSystemI<0, iops, asm, operands> { 1499 1500 let Inst{20-19} = 0b00; 1501 let Inst{15-12} = 0b0100; 1502} 1503 1504class MSRpstateImm0_15 1505 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1506 "\t$pstatefield, $imm">, 1507 Sched<[WriteSys]> { 1508 1509 bits<6> pstatefield; 1510 bits<4> imm; 1511 let Inst{18-16} = pstatefield{5-3}; 1512 let Inst{11-8} = imm; 1513 let Inst{7-5} = pstatefield{2-0}; 1514 1515 let DecoderMethod = "DecodeSystemPStateInstruction"; 1516 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1517 // Fail the decoder should attempt to decode the instruction as MSRI. 1518 let hasCompleteDecoder = 0; 1519} 1520 1521def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1522 let Name = "SystemPStateFieldWithImm0_1"; 1523 let ParserMethod = "tryParseSysReg"; 1524} 1525def pstatefield1_op : Operand<i32> { 1526 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1527 let PrintMethod = "printSystemPStateField"; 1528} 1529 1530class MSRpstateImm0_1 1531 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1532 "\t$pstatefield, $imm">, 1533 Sched<[WriteSys]> { 1534 1535 bits<6> pstatefield; 1536 bit imm; 1537 let Inst{18-16} = pstatefield{5-3}; 1538 let Inst{11-9} = 0b000; 1539 let Inst{8} = imm; 1540 let Inst{7-5} = pstatefield{2-0}; 1541 1542 let DecoderMethod = "DecodeSystemPStateInstruction"; 1543 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1544 // Fail the decoder should attempt to decode the instruction as MSRI. 1545 let hasCompleteDecoder = 0; 1546} 1547 1548// SYS and SYSL generic system instructions. 1549def SysCRAsmOperand : AsmOperandClass { 1550 let Name = "SysCR"; 1551 let ParserMethod = "tryParseSysCROperand"; 1552} 1553 1554def sys_cr_op : Operand<i32> { 1555 let PrintMethod = "printSysCROperand"; 1556 let ParserMatchClass = SysCRAsmOperand; 1557} 1558 1559class SystemXtI<bit L, string asm> 1560 : RtSystemI<L, (outs), 1561 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1562 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1563 bits<3> op1; 1564 bits<4> Cn; 1565 bits<4> Cm; 1566 bits<3> op2; 1567 let Inst{20-19} = 0b01; 1568 let Inst{18-16} = op1; 1569 let Inst{15-12} = Cn; 1570 let Inst{11-8} = Cm; 1571 let Inst{7-5} = op2; 1572} 1573 1574class SystemLXtI<bit L, string asm> 1575 : RtSystemI<L, (outs), 1576 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1577 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1578 bits<3> op1; 1579 bits<4> Cn; 1580 bits<4> Cm; 1581 bits<3> op2; 1582 let Inst{20-19} = 0b01; 1583 let Inst{18-16} = op1; 1584 let Inst{15-12} = Cn; 1585 let Inst{11-8} = Cm; 1586 let Inst{7-5} = op2; 1587} 1588 1589 1590// Branch (register) instructions: 1591// 1592// case opc of 1593// 0001 blr 1594// 0000 br 1595// 0101 dret 1596// 0100 eret 1597// 0010 ret 1598// otherwise UNDEFINED 1599class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1600 string operands, list<dag> pattern> 1601 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1602 let Inst{31-25} = 0b1101011; 1603 let Inst{24-21} = opc; 1604 let Inst{20-16} = 0b11111; 1605 let Inst{15-10} = 0b000000; 1606 let Inst{4-0} = 0b00000; 1607} 1608 1609class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1610 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1611 bits<5> Rn; 1612 let Inst{9-5} = Rn; 1613} 1614 1615let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1616class SpecialReturn<bits<4> opc, string asm> 1617 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1618 let Inst{9-5} = 0b11111; 1619} 1620 1621let mayLoad = 1 in 1622class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1623 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1624 Sched<[]> { 1625 bits<5> Rn; 1626 bits<5> Rt; 1627 let Inst{31-30} = sz; 1628 let Inst{29-10} = 0b11100010111111110000; 1629 let Inst{9-5} = Rn; 1630 let Inst{4-0} = Rt; 1631} 1632 1633class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1634 list<dag> pattern> 1635 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1636 let isAuthenticated = 1; 1637 let Inst{31-25} = 0b1101011; 1638 let Inst{20-11} = 0b1111100001; 1639 let Inst{10} = M; 1640 let Inst{4-0} = 0b11111; 1641} 1642 1643class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1644 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1645 bits<5> Rn; 1646 bits<5> Rm; 1647 let Inst{24-22} = 0b100; 1648 let Inst{21} = op; 1649 let Inst{9-5} = Rn; 1650 let Inst{4-0} = Rm; 1651} 1652 1653class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1654 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1655 bits<5> Rn; 1656 let Inst{24} = 0; 1657 let Inst{23-21} = opc; 1658 let Inst{9-5} = Rn; 1659} 1660 1661let Uses = [LR,SP] in 1662class AuthReturn<bits<3> op, bits<1> M, string asm> 1663 : AuthBase<M, (outs), (ins), asm, "", []> { 1664 let Inst{24} = 0; 1665 let Inst{23-21} = op; 1666 let Inst{9-0} = 0b1111111111; 1667} 1668 1669let mayLoad = 1 in 1670class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1671 string operands, string cstr, Operand opr> 1672 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1673 bits<10> offset; 1674 bits<5> Rn; 1675 bits<5> Rt; 1676 let isAuthenticated = 1; 1677 let Inst{31-24} = 0b11111000; 1678 let Inst{23} = M; 1679 let Inst{22} = offset{9}; 1680 let Inst{21} = 1; 1681 let Inst{20-12} = offset{8-0}; 1682 let Inst{11} = W; 1683 let Inst{10} = 1; 1684 let Inst{9-5} = Rn; 1685 let Inst{4-0} = Rt; 1686 1687 let DecoderMethod = "DecodeAuthLoadInstruction"; 1688} 1689 1690multiclass AuthLoad<bit M, string asm, Operand opr> { 1691 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1692 (ins GPR64sp:$Rn, opr:$offset), 1693 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1694 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1695 (ins GPR64sp:$Rn, opr:$offset), 1696 asm, "\t$Rt, [$Rn, $offset]!", 1697 "$Rn = $wback,@earlyclobber $wback", opr>; 1698 1699 def : InstAlias<asm # "\t$Rt, [$Rn]", 1700 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1701 1702 def : InstAlias<asm # "\t$Rt, [$wback]!", 1703 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1704} 1705 1706//--- 1707// Conditional branch instruction. 1708//--- 1709 1710// Condition code. 1711// 4-bit immediate. Pretty-printed as <cc> 1712def ccode : Operand<i32> { 1713 let PrintMethod = "printCondCode"; 1714 let ParserMatchClass = CondCode; 1715} 1716def inv_ccode : Operand<i32> { 1717 // AL and NV are invalid in the aliases which use inv_ccode 1718 let PrintMethod = "printInverseCondCode"; 1719 let ParserMatchClass = CondCode; 1720 let MCOperandPredicate = [{ 1721 return MCOp.isImm() && 1722 MCOp.getImm() != AArch64CC::AL && 1723 MCOp.getImm() != AArch64CC::NV; 1724 }]; 1725} 1726 1727// Conditional branch target. 19-bit immediate. The low two bits of the target 1728// offset are implied zero and so are not part of the immediate. 1729def am_brcond : Operand<OtherVT> { 1730 let EncoderMethod = "getCondBranchTargetOpValue"; 1731 let DecoderMethod = "DecodePCRelLabel19"; 1732 let PrintMethod = "printAlignedLabel"; 1733 let ParserMatchClass = PCRelLabel19Operand; 1734 let OperandType = "OPERAND_PCREL"; 1735} 1736 1737class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1738 "b", ".$cond\t$target", "", 1739 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1740 Sched<[WriteBr]> { 1741 let isBranch = 1; 1742 let isTerminator = 1; 1743 let Uses = [NZCV]; 1744 1745 bits<4> cond; 1746 bits<19> target; 1747 let Inst{31-24} = 0b01010100; 1748 let Inst{23-5} = target; 1749 let Inst{4} = 0; 1750 let Inst{3-0} = cond; 1751} 1752 1753//--- 1754// Compare-and-branch instructions. 1755//--- 1756class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1757 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1758 asm, "\t$Rt, $target", "", 1759 [(node regtype:$Rt, bb:$target)]>, 1760 Sched<[WriteBr]> { 1761 let isBranch = 1; 1762 let isTerminator = 1; 1763 1764 bits<5> Rt; 1765 bits<19> target; 1766 let Inst{30-25} = 0b011010; 1767 let Inst{24} = op; 1768 let Inst{23-5} = target; 1769 let Inst{4-0} = Rt; 1770} 1771 1772multiclass CmpBranch<bit op, string asm, SDNode node> { 1773 def W : BaseCmpBranch<GPR32, op, asm, node> { 1774 let Inst{31} = 0; 1775 } 1776 def X : BaseCmpBranch<GPR64, op, asm, node> { 1777 let Inst{31} = 1; 1778 } 1779} 1780 1781//--- 1782// Test-bit-and-branch instructions. 1783//--- 1784// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1785// the target offset are implied zero and so are not part of the immediate. 1786def am_tbrcond : Operand<OtherVT> { 1787 let EncoderMethod = "getTestBranchTargetOpValue"; 1788 let PrintMethod = "printAlignedLabel"; 1789 let ParserMatchClass = BranchTarget14Operand; 1790 let OperandType = "OPERAND_PCREL"; 1791} 1792 1793// AsmOperand classes to emit (or not) special diagnostics 1794def TBZImm0_31Operand : AsmOperandClass { 1795 let Name = "TBZImm0_31"; 1796 let PredicateMethod = "isImmInRange<0,31>"; 1797 let RenderMethod = "addImmOperands"; 1798} 1799def TBZImm32_63Operand : AsmOperandClass { 1800 let Name = "Imm32_63"; 1801 let PredicateMethod = "isImmInRange<32,63>"; 1802 let DiagnosticType = "InvalidImm0_63"; 1803 let RenderMethod = "addImmOperands"; 1804} 1805 1806class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1807 return (((uint32_t)Imm) < 32); 1808}]> { 1809 let ParserMatchClass = matcher; 1810} 1811 1812def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1813def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1814 1815def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1816 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1817}]> { 1818 let ParserMatchClass = TBZImm32_63Operand; 1819} 1820 1821class BaseTestBranch<RegisterClass regtype, Operand immtype, 1822 bit op, string asm, SDNode node> 1823 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1824 asm, "\t$Rt, $bit_off, $target", "", 1825 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1826 Sched<[WriteBr]> { 1827 let isBranch = 1; 1828 let isTerminator = 1; 1829 1830 bits<5> Rt; 1831 bits<6> bit_off; 1832 bits<14> target; 1833 1834 let Inst{30-25} = 0b011011; 1835 let Inst{24} = op; 1836 let Inst{23-19} = bit_off{4-0}; 1837 let Inst{18-5} = target; 1838 let Inst{4-0} = Rt; 1839 1840 let DecoderMethod = "DecodeTestAndBranch"; 1841} 1842 1843multiclass TestBranch<bit op, string asm, SDNode node> { 1844 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1845 let Inst{31} = 0; 1846 } 1847 1848 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1849 let Inst{31} = 1; 1850 } 1851 1852 // Alias X-reg with 0-31 imm to W-Reg. 1853 def : InstAlias<asm # "\t$Rd, $imm, $target", 1854 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1855 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1856 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1857 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1858 tbz_imm0_31_diag:$imm, bb:$target)>; 1859} 1860 1861//--- 1862// Unconditional branch (immediate) instructions. 1863//--- 1864def am_b_target : Operand<OtherVT> { 1865 let EncoderMethod = "getBranchTargetOpValue"; 1866 let PrintMethod = "printAlignedLabel"; 1867 let ParserMatchClass = BranchTarget26Operand; 1868 let OperandType = "OPERAND_PCREL"; 1869} 1870def am_bl_target : Operand<i64> { 1871 let EncoderMethod = "getBranchTargetOpValue"; 1872 let PrintMethod = "printAlignedLabel"; 1873 let ParserMatchClass = BranchTarget26Operand; 1874 let OperandType = "OPERAND_PCREL"; 1875} 1876 1877class BImm<bit op, dag iops, string asm, list<dag> pattern> 1878 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1879 bits<26> addr; 1880 let Inst{31} = op; 1881 let Inst{30-26} = 0b00101; 1882 let Inst{25-0} = addr; 1883 1884 let DecoderMethod = "DecodeUnconditionalBranch"; 1885} 1886 1887class BranchImm<bit op, string asm, list<dag> pattern> 1888 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1889class CallImm<bit op, string asm, list<dag> pattern> 1890 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1891 1892//--- 1893// Basic one-operand data processing instructions. 1894//--- 1895 1896let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1897class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1898 SDPatternOperator node> 1899 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1900 [(set regtype:$Rd, (node regtype:$Rn))]>, 1901 Sched<[WriteI, ReadI]> { 1902 bits<5> Rd; 1903 bits<5> Rn; 1904 1905 let Inst{30-13} = 0b101101011000000000; 1906 let Inst{12-10} = opc; 1907 let Inst{9-5} = Rn; 1908 let Inst{4-0} = Rd; 1909} 1910 1911let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1912multiclass OneOperandData<bits<3> opc, string asm, 1913 SDPatternOperator node = null_frag> { 1914 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1915 let Inst{31} = 0; 1916 } 1917 1918 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1919 let Inst{31} = 1; 1920 } 1921} 1922 1923class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1924 : BaseOneOperandData<opc, GPR32, asm, node> { 1925 let Inst{31} = 0; 1926} 1927 1928class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1929 : BaseOneOperandData<opc, GPR64, asm, node> { 1930 let Inst{31} = 1; 1931} 1932 1933class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1934 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "", 1935 []>, 1936 Sched<[WriteI, ReadI]> { 1937 bits<5> Rd; 1938 bits<5> Rn; 1939 let Inst{31-15} = 0b11011010110000010; 1940 let Inst{14-12} = opcode_prefix; 1941 let Inst{11-10} = opcode; 1942 let Inst{9-5} = Rn; 1943 let Inst{4-0} = Rd; 1944} 1945 1946class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1947 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> { 1948 bits<5> Rd; 1949 let Inst{31-15} = 0b11011010110000010; 1950 let Inst{14-12} = opcode_prefix; 1951 let Inst{11-10} = opcode; 1952 let Inst{9-5} = 0b11111; 1953 let Inst{4-0} = Rd; 1954} 1955 1956class SignAuthTwoOperand<bits<4> opc, string asm, 1957 SDPatternOperator OpNode> 1958 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1959 asm, "\t$Rd, $Rn, $Rm", "", 1960 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1961 Sched<[WriteI, ReadI, ReadI]> { 1962 bits<5> Rd; 1963 bits<5> Rn; 1964 bits<5> Rm; 1965 let Inst{31-21} = 0b10011010110; 1966 let Inst{20-16} = Rm; 1967 let Inst{15-14} = 0b00; 1968 let Inst{13-10} = opc; 1969 let Inst{9-5} = Rn; 1970 let Inst{4-0} = Rd; 1971} 1972 1973class ClearAuth<bits<1> data, string asm> 1974 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 1975 bits<5> Rd; 1976 let Inst{31-11} = 0b110110101100000101000; 1977 let Inst{10} = data; 1978 let Inst{9-5} = 0b11111; 1979 let Inst{4-0} = Rd; 1980} 1981 1982// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 1983class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 1984 : I<(outs), iops, asm, ops, "", []>, 1985 Sched<[WriteI, ReadI, ReadI]> { 1986 let Uses = [NZCV]; 1987 let Defs = [NZCV]; 1988 bits<5> Rn; 1989 let Inst{31} = sf; 1990 let Inst{30-15} = 0b0111010000000000; 1991 let Inst{14} = sz; 1992 let Inst{13-10} = 0b0010; 1993 let Inst{9-5} = Rn; 1994 let Inst{4-0} = 0b01101; 1995} 1996 1997class FlagRotate<dag iops, string asm, string ops> 1998 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 1999 bits<6> imm; 2000 bits<4> mask; 2001 let Inst{20-15} = imm; 2002 let Inst{13-10} = 0b0001; 2003 let Inst{4} = 0b0; 2004 let Inst{3-0} = mask; 2005} 2006 2007//--- 2008// Basic two-operand data processing instructions. 2009//--- 2010class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2011 list<dag> pattern> 2012 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2013 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2014 Sched<[WriteI, ReadI, ReadI]> { 2015 let Uses = [NZCV]; 2016 bits<5> Rd; 2017 bits<5> Rn; 2018 bits<5> Rm; 2019 let Inst{30} = isSub; 2020 let Inst{28-21} = 0b11010000; 2021 let Inst{20-16} = Rm; 2022 let Inst{15-10} = 0; 2023 let Inst{9-5} = Rn; 2024 let Inst{4-0} = Rd; 2025} 2026 2027class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2028 SDNode OpNode> 2029 : BaseBaseAddSubCarry<isSub, regtype, asm, 2030 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2031 2032class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2033 SDNode OpNode> 2034 : BaseBaseAddSubCarry<isSub, regtype, asm, 2035 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2036 (implicit NZCV)]> { 2037 let Defs = [NZCV]; 2038} 2039 2040multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2041 SDNode OpNode, SDNode OpNode_setflags> { 2042 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2043 let Inst{31} = 0; 2044 let Inst{29} = 0; 2045 } 2046 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2047 let Inst{31} = 1; 2048 let Inst{29} = 0; 2049 } 2050 2051 // Sets flags. 2052 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2053 OpNode_setflags> { 2054 let Inst{31} = 0; 2055 let Inst{29} = 1; 2056 } 2057 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2058 OpNode_setflags> { 2059 let Inst{31} = 1; 2060 let Inst{29} = 1; 2061 } 2062} 2063 2064class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2065 SDPatternOperator OpNode, 2066 RegisterClass in1regtype = regtype, 2067 RegisterClass in2regtype = regtype> 2068 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2069 asm, "\t$Rd, $Rn, $Rm", "", 2070 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2071 bits<5> Rd; 2072 bits<5> Rn; 2073 bits<5> Rm; 2074 let Inst{30-21} = 0b0011010110; 2075 let Inst{20-16} = Rm; 2076 let Inst{15-14} = 0b00; 2077 let Inst{13-10} = opc; 2078 let Inst{9-5} = Rn; 2079 let Inst{4-0} = Rd; 2080} 2081 2082class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2083 SDPatternOperator OpNode> 2084 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2085 let Inst{10} = isSigned; 2086} 2087 2088multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2089 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2090 Sched<[WriteID32, ReadID, ReadID]> { 2091 let Inst{31} = 0; 2092 } 2093 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2094 Sched<[WriteID64, ReadID, ReadID]> { 2095 let Inst{31} = 1; 2096 } 2097} 2098 2099class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2100 SDPatternOperator OpNode = null_frag> 2101 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2102 Sched<[WriteIS, ReadI]> { 2103 let Inst{11-10} = shift_type; 2104} 2105 2106multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2107 def Wr : BaseShift<shift_type, GPR32, asm> { 2108 let Inst{31} = 0; 2109 } 2110 2111 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2112 let Inst{31} = 1; 2113 } 2114 2115 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2116 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2117 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2118 2119 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2120 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2121 2122 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2123 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2124 2125 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2126 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2127 2128 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2129 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2130 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2131 2132 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2133 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2134 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2135} 2136 2137class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2138 : InstAlias<asm#"\t$dst, $src1, $src2", 2139 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2140 2141class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2142 RegisterClass addtype, string asm, 2143 list<dag> pattern> 2144 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2145 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2146 bits<5> Rd; 2147 bits<5> Rn; 2148 bits<5> Rm; 2149 bits<5> Ra; 2150 let Inst{30-24} = 0b0011011; 2151 let Inst{23-21} = opc; 2152 let Inst{20-16} = Rm; 2153 let Inst{15} = isSub; 2154 let Inst{14-10} = Ra; 2155 let Inst{9-5} = Rn; 2156 let Inst{4-0} = Rd; 2157} 2158 2159multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 2160 // MADD/MSUB generation is decided by MachineCombiner.cpp 2161 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 2162 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 2163 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2164 let Inst{31} = 0; 2165 } 2166 2167 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 2168 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 2169 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2170 let Inst{31} = 1; 2171 } 2172} 2173 2174class WideMulAccum<bit isSub, bits<3> opc, string asm, 2175 SDNode AccNode, SDNode ExtNode> 2176 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2177 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2178 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2179 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2180 let Inst{31} = 1; 2181} 2182 2183class MulHi<bits<3> opc, string asm, SDNode OpNode> 2184 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2185 asm, "\t$Rd, $Rn, $Rm", "", 2186 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2187 Sched<[WriteIM64, ReadIM, ReadIM]> { 2188 bits<5> Rd; 2189 bits<5> Rn; 2190 bits<5> Rm; 2191 let Inst{31-24} = 0b10011011; 2192 let Inst{23-21} = opc; 2193 let Inst{20-16} = Rm; 2194 let Inst{15} = 0; 2195 let Inst{9-5} = Rn; 2196 let Inst{4-0} = Rd; 2197 2198 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2199 // (i.e. all bits 1) but is ignored by the processor. 2200 let PostEncoderMethod = "fixMulHigh"; 2201} 2202 2203class MulAccumWAlias<string asm, Instruction inst> 2204 : InstAlias<asm#"\t$dst, $src1, $src2", 2205 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2206class MulAccumXAlias<string asm, Instruction inst> 2207 : InstAlias<asm#"\t$dst, $src1, $src2", 2208 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2209class WideMulAccumAlias<string asm, Instruction inst> 2210 : InstAlias<asm#"\t$dst, $src1, $src2", 2211 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2212 2213class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2214 SDPatternOperator OpNode, string asm> 2215 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2216 asm, "\t$Rd, $Rn, $Rm", "", 2217 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2218 Sched<[WriteISReg, ReadI, ReadISReg]> { 2219 bits<5> Rd; 2220 bits<5> Rn; 2221 bits<5> Rm; 2222 2223 let Inst{31} = sf; 2224 let Inst{30-21} = 0b0011010110; 2225 let Inst{20-16} = Rm; 2226 let Inst{15-13} = 0b010; 2227 let Inst{12} = C; 2228 let Inst{11-10} = sz; 2229 let Inst{9-5} = Rn; 2230 let Inst{4-0} = Rd; 2231 let Predicates = [HasCRC]; 2232} 2233 2234//--- 2235// Address generation. 2236//--- 2237 2238class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2239 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2240 pattern>, 2241 Sched<[WriteI]> { 2242 bits<5> Xd; 2243 bits<21> label; 2244 let Inst{31} = page; 2245 let Inst{30-29} = label{1-0}; 2246 let Inst{28-24} = 0b10000; 2247 let Inst{23-5} = label{20-2}; 2248 let Inst{4-0} = Xd; 2249 2250 let DecoderMethod = "DecodeAdrInstruction"; 2251} 2252 2253//--- 2254// Move immediate. 2255//--- 2256 2257def movimm32_imm : Operand<i32> { 2258 let ParserMatchClass = AsmImmRange<0, 65535>; 2259 let EncoderMethod = "getMoveWideImmOpValue"; 2260 let PrintMethod = "printImm"; 2261} 2262def movimm32_shift : Operand<i32> { 2263 let PrintMethod = "printShifter"; 2264 let ParserMatchClass = MovImm32ShifterOperand; 2265} 2266def movimm64_shift : Operand<i32> { 2267 let PrintMethod = "printShifter"; 2268 let ParserMatchClass = MovImm64ShifterOperand; 2269} 2270 2271let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2272class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2273 string asm> 2274 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2275 asm, "\t$Rd, $imm$shift", "", []>, 2276 Sched<[WriteImm]> { 2277 bits<5> Rd; 2278 bits<16> imm; 2279 bits<6> shift; 2280 let Inst{30-29} = opc; 2281 let Inst{28-23} = 0b100101; 2282 let Inst{22-21} = shift{5-4}; 2283 let Inst{20-5} = imm; 2284 let Inst{4-0} = Rd; 2285 2286 let DecoderMethod = "DecodeMoveImmInstruction"; 2287} 2288 2289multiclass MoveImmediate<bits<2> opc, string asm> { 2290 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2291 let Inst{31} = 0; 2292 } 2293 2294 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2295 let Inst{31} = 1; 2296 } 2297} 2298 2299let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2300class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2301 string asm> 2302 : I<(outs regtype:$Rd), 2303 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2304 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2305 Sched<[WriteI, ReadI]> { 2306 bits<5> Rd; 2307 bits<16> imm; 2308 bits<6> shift; 2309 let Inst{30-29} = opc; 2310 let Inst{28-23} = 0b100101; 2311 let Inst{22-21} = shift{5-4}; 2312 let Inst{20-5} = imm; 2313 let Inst{4-0} = Rd; 2314 2315 let DecoderMethod = "DecodeMoveImmInstruction"; 2316} 2317 2318multiclass InsertImmediate<bits<2> opc, string asm> { 2319 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2320 let Inst{31} = 0; 2321 } 2322 2323 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2324 let Inst{31} = 1; 2325 } 2326} 2327 2328//--- 2329// Add/Subtract 2330//--- 2331 2332class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2333 string asm_inst, string asm_ops, 2334 dag inputs, dag pattern> 2335 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2336 Sched<[WriteI, ReadI]> { 2337 bits<5> Rd; 2338 bits<5> Rn; 2339 let Inst{30} = isSub; 2340 let Inst{29} = setFlags; 2341 let Inst{28-24} = 0b10001; 2342 let Inst{9-5} = Rn; 2343 let Inst{4-0} = Rd; 2344} 2345 2346class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2347 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2348 string asm_inst, SDPatternOperator OpNode> 2349 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2350 (ins srcRegtype:$Rn, immtype:$imm), 2351 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2352 bits<14> imm; 2353 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2354 let Inst{21-10} = imm{11-0}; 2355 let DecoderMethod = "DecodeAddSubImmShift"; 2356} 2357 2358class BaseAddSubRegPseudo<RegisterClass regtype, 2359 SDPatternOperator OpNode> 2360 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2361 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2362 Sched<[WriteI, ReadI, ReadI]>; 2363 2364class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2365 arith_shifted_reg shifted_regtype, string asm, 2366 SDPatternOperator OpNode> 2367 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2368 asm, "\t$Rd, $Rn, $Rm", "", 2369 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2370 Sched<[WriteISReg, ReadI, ReadISReg]> { 2371 // The operands are in order to match the 'addr' MI operands, so we 2372 // don't need an encoder method and by-name matching. Just use the default 2373 // in-order handling. Since we're using by-order, make sure the names 2374 // do not match. 2375 bits<5> dst; 2376 bits<5> src1; 2377 bits<5> src2; 2378 bits<8> shift; 2379 let Inst{30} = isSub; 2380 let Inst{29} = setFlags; 2381 let Inst{28-24} = 0b01011; 2382 let Inst{23-22} = shift{7-6}; 2383 let Inst{21} = 0; 2384 let Inst{20-16} = src2; 2385 let Inst{15-10} = shift{5-0}; 2386 let Inst{9-5} = src1; 2387 let Inst{4-0} = dst; 2388 2389 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2390} 2391 2392class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2393 RegisterClass src1Regtype, Operand src2Regtype, 2394 string asm, SDPatternOperator OpNode> 2395 : I<(outs dstRegtype:$R1), 2396 (ins src1Regtype:$R2, src2Regtype:$R3), 2397 asm, "\t$R1, $R2, $R3", "", 2398 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2399 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2400 bits<5> Rd; 2401 bits<5> Rn; 2402 bits<5> Rm; 2403 bits<6> ext; 2404 let Inst{30} = isSub; 2405 let Inst{29} = setFlags; 2406 let Inst{28-24} = 0b01011; 2407 let Inst{23-21} = 0b001; 2408 let Inst{20-16} = Rm; 2409 let Inst{15-13} = ext{5-3}; 2410 let Inst{12-10} = ext{2-0}; 2411 let Inst{9-5} = Rn; 2412 let Inst{4-0} = Rd; 2413 2414 let DecoderMethod = "DecodeAddSubERegInstruction"; 2415} 2416 2417let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2418class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2419 RegisterClass src1Regtype, RegisterClass src2Regtype, 2420 Operand ext_op, string asm> 2421 : I<(outs dstRegtype:$Rd), 2422 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2423 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2424 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2425 bits<5> Rd; 2426 bits<5> Rn; 2427 bits<5> Rm; 2428 bits<6> ext; 2429 let Inst{30} = isSub; 2430 let Inst{29} = setFlags; 2431 let Inst{28-24} = 0b01011; 2432 let Inst{23-21} = 0b001; 2433 let Inst{20-16} = Rm; 2434 let Inst{15} = ext{5}; 2435 let Inst{12-10} = ext{2-0}; 2436 let Inst{9-5} = Rn; 2437 let Inst{4-0} = Rd; 2438 2439 let DecoderMethod = "DecodeAddSubERegInstruction"; 2440} 2441 2442// Aliases for register+register add/subtract. 2443class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2444 RegisterClass src1Regtype, RegisterClass src2Regtype, 2445 int shiftExt> 2446 : InstAlias<asm#"\t$dst, $src1, $src2", 2447 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2448 shiftExt)>; 2449 2450multiclass AddSub<bit isSub, string mnemonic, string alias, 2451 SDPatternOperator OpNode = null_frag> { 2452 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2453 // Add/Subtract immediate 2454 // Increase the weight of the immediate variant to try to match it before 2455 // the extended register variant. 2456 // We used to match the register variant before the immediate when the 2457 // register argument could be implicitly zero-extended. 2458 let AddedComplexity = 6 in 2459 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2460 mnemonic, OpNode> { 2461 let Inst{31} = 0; 2462 } 2463 let AddedComplexity = 6 in 2464 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2465 mnemonic, OpNode> { 2466 let Inst{31} = 1; 2467 } 2468 2469 // Add/Subtract register - Only used for CodeGen 2470 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2471 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2472 2473 // Add/Subtract shifted register 2474 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2475 OpNode> { 2476 let Inst{31} = 0; 2477 } 2478 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2479 OpNode> { 2480 let Inst{31} = 1; 2481 } 2482 } 2483 2484 // Add/Subtract extended register 2485 let AddedComplexity = 1, hasSideEffects = 0 in { 2486 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2487 arith_extended_reg32_i32, mnemonic, OpNode> { 2488 let Inst{31} = 0; 2489 } 2490 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2491 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2492 let Inst{31} = 1; 2493 } 2494 } 2495 2496 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2497 arith_extendlsl64, mnemonic> { 2498 // UXTX and SXTX only. 2499 let Inst{14-13} = 0b11; 2500 let Inst{31} = 1; 2501 } 2502 2503 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2504 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2505 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2506 addsub_shifted_imm32_neg:$imm), 0>; 2507 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2508 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2509 addsub_shifted_imm64_neg:$imm), 0>; 2510 2511 // Register/register aliases with no shift when SP is not used. 2512 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2513 GPR32, GPR32, GPR32, 0>; 2514 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2515 GPR64, GPR64, GPR64, 0>; 2516 2517 // Register/register aliases with no shift when either the destination or 2518 // first source register is SP. 2519 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2520 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2521 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2522 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2523 def : AddSubRegAlias<mnemonic, 2524 !cast<Instruction>(NAME#"Xrx64"), 2525 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2526 def : AddSubRegAlias<mnemonic, 2527 !cast<Instruction>(NAME#"Xrx64"), 2528 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2529} 2530 2531multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2532 string alias, string cmpAlias> { 2533 let isCompare = 1, Defs = [NZCV] in { 2534 // Add/Subtract immediate 2535 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2536 mnemonic, OpNode> { 2537 let Inst{31} = 0; 2538 } 2539 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2540 mnemonic, OpNode> { 2541 let Inst{31} = 1; 2542 } 2543 2544 // Add/Subtract register 2545 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2546 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2547 2548 // Add/Subtract shifted register 2549 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2550 OpNode> { 2551 let Inst{31} = 0; 2552 } 2553 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2554 OpNode> { 2555 let Inst{31} = 1; 2556 } 2557 2558 // Add/Subtract extended register 2559 let AddedComplexity = 1 in { 2560 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2561 arith_extended_reg32_i32, mnemonic, OpNode> { 2562 let Inst{31} = 0; 2563 } 2564 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2565 arith_extended_reg32_i64, mnemonic, OpNode> { 2566 let Inst{31} = 1; 2567 } 2568 } 2569 2570 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2571 arith_extendlsl64, mnemonic> { 2572 // UXTX and SXTX only. 2573 let Inst{14-13} = 0b11; 2574 let Inst{31} = 1; 2575 } 2576 } // Defs = [NZCV] 2577 2578 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2579 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2580 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2581 addsub_shifted_imm32_neg:$imm), 0>; 2582 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2583 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2584 addsub_shifted_imm64_neg:$imm), 0>; 2585 2586 // Compare aliases 2587 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2588 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2589 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2590 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2591 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2592 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2593 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2594 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2595 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2596 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2597 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2598 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2599 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2600 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2601 2602 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2603 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2604 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2605 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2606 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2607 2608 // Compare shorthands 2609 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2610 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2611 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2612 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2613 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2614 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2615 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2616 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2617 2618 // Register/register aliases with no shift when SP is not used. 2619 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2620 GPR32, GPR32, GPR32, 0>; 2621 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2622 GPR64, GPR64, GPR64, 0>; 2623 2624 // Register/register aliases with no shift when the first source register 2625 // is SP. 2626 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2627 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2628 def : AddSubRegAlias<mnemonic, 2629 !cast<Instruction>(NAME#"Xrx64"), 2630 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2631} 2632 2633class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2634 : BaseAddSubImm< 2635 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2636 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2637 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2638 bits<6> imm6; 2639 bits<4> imm4; 2640 let Inst{31} = 1; 2641 let Inst{23-22} = 0b10; 2642 let Inst{21-16} = imm6; 2643 let Inst{15-14} = 0b00; 2644 let Inst{13-10} = imm4; 2645 let Unpredictable{15-14} = 0b11; 2646} 2647 2648class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2649 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2650 let Inst{31} = 1; 2651 let Inst{29} = setsFlags; 2652} 2653 2654//--- 2655// Extract 2656//--- 2657def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2658 SDTCisPtrTy<3>]>; 2659def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2660 2661class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2662 list<dag> patterns> 2663 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2664 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2665 Sched<[WriteExtr, ReadExtrHi]> { 2666 bits<5> Rd; 2667 bits<5> Rn; 2668 bits<5> Rm; 2669 bits<6> imm; 2670 2671 let Inst{30-23} = 0b00100111; 2672 let Inst{21} = 0; 2673 let Inst{20-16} = Rm; 2674 let Inst{15-10} = imm; 2675 let Inst{9-5} = Rn; 2676 let Inst{4-0} = Rd; 2677} 2678 2679multiclass ExtractImm<string asm> { 2680 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2681 [(set GPR32:$Rd, 2682 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2683 let Inst{31} = 0; 2684 let Inst{22} = 0; 2685 // imm<5> must be zero. 2686 let imm{5} = 0; 2687 } 2688 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2689 [(set GPR64:$Rd, 2690 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2691 2692 let Inst{31} = 1; 2693 let Inst{22} = 1; 2694 } 2695} 2696 2697//--- 2698// Bitfield 2699//--- 2700 2701let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2702class BaseBitfieldImm<bits<2> opc, 2703 RegisterClass regtype, Operand imm_type, string asm> 2704 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2705 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2706 Sched<[WriteIS, ReadI]> { 2707 bits<5> Rd; 2708 bits<5> Rn; 2709 bits<6> immr; 2710 bits<6> imms; 2711 2712 let Inst{30-29} = opc; 2713 let Inst{28-23} = 0b100110; 2714 let Inst{21-16} = immr; 2715 let Inst{15-10} = imms; 2716 let Inst{9-5} = Rn; 2717 let Inst{4-0} = Rd; 2718} 2719 2720multiclass BitfieldImm<bits<2> opc, string asm> { 2721 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2722 let Inst{31} = 0; 2723 let Inst{22} = 0; 2724 // imms<5> and immr<5> must be zero, else ReservedValue(). 2725 let Inst{21} = 0; 2726 let Inst{15} = 0; 2727 } 2728 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2729 let Inst{31} = 1; 2730 let Inst{22} = 1; 2731 } 2732} 2733 2734let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2735class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2736 RegisterClass regtype, Operand imm_type, string asm> 2737 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2738 imm_type:$imms), 2739 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2740 Sched<[WriteIS, ReadI]> { 2741 bits<5> Rd; 2742 bits<5> Rn; 2743 bits<6> immr; 2744 bits<6> imms; 2745 2746 let Inst{30-29} = opc; 2747 let Inst{28-23} = 0b100110; 2748 let Inst{21-16} = immr; 2749 let Inst{15-10} = imms; 2750 let Inst{9-5} = Rn; 2751 let Inst{4-0} = Rd; 2752} 2753 2754multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2755 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2756 let Inst{31} = 0; 2757 let Inst{22} = 0; 2758 // imms<5> and immr<5> must be zero, else ReservedValue(). 2759 let Inst{21} = 0; 2760 let Inst{15} = 0; 2761 } 2762 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2763 let Inst{31} = 1; 2764 let Inst{22} = 1; 2765 } 2766} 2767 2768//--- 2769// Logical 2770//--- 2771 2772// Logical (immediate) 2773class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2774 RegisterClass sregtype, Operand imm_type, string asm, 2775 list<dag> pattern> 2776 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2777 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2778 Sched<[WriteI, ReadI]> { 2779 bits<5> Rd; 2780 bits<5> Rn; 2781 bits<13> imm; 2782 let Inst{30-29} = opc; 2783 let Inst{28-23} = 0b100100; 2784 let Inst{22} = imm{12}; 2785 let Inst{21-16} = imm{11-6}; 2786 let Inst{15-10} = imm{5-0}; 2787 let Inst{9-5} = Rn; 2788 let Inst{4-0} = Rd; 2789 2790 let DecoderMethod = "DecodeLogicalImmInstruction"; 2791} 2792 2793// Logical (shifted register) 2794class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2795 logical_shifted_reg shifted_regtype, string asm, 2796 list<dag> pattern> 2797 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2798 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2799 Sched<[WriteISReg, ReadI, ReadISReg]> { 2800 // The operands are in order to match the 'addr' MI operands, so we 2801 // don't need an encoder method and by-name matching. Just use the default 2802 // in-order handling. Since we're using by-order, make sure the names 2803 // do not match. 2804 bits<5> dst; 2805 bits<5> src1; 2806 bits<5> src2; 2807 bits<8> shift; 2808 let Inst{30-29} = opc; 2809 let Inst{28-24} = 0b01010; 2810 let Inst{23-22} = shift{7-6}; 2811 let Inst{21} = N; 2812 let Inst{20-16} = src2; 2813 let Inst{15-10} = shift{5-0}; 2814 let Inst{9-5} = src1; 2815 let Inst{4-0} = dst; 2816 2817 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2818} 2819 2820// Aliases for register+register logical instructions. 2821class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2822 : InstAlias<asm#"\t$dst, $src1, $src2", 2823 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2824 2825multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2826 string Alias> { 2827 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2828 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2829 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2830 logical_imm32:$imm))]> { 2831 let Inst{31} = 0; 2832 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2833 } 2834 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2835 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2836 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2837 logical_imm64:$imm))]> { 2838 let Inst{31} = 1; 2839 } 2840 2841 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2842 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2843 logical_imm32_not:$imm), 0>; 2844 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2845 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2846 logical_imm64_not:$imm), 0>; 2847} 2848 2849multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2850 string Alias> { 2851 let isCompare = 1, Defs = [NZCV] in { 2852 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2853 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2854 let Inst{31} = 0; 2855 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2856 } 2857 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2858 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2859 let Inst{31} = 1; 2860 } 2861 } // end Defs = [NZCV] 2862 2863 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2864 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2865 logical_imm32_not:$imm), 0>; 2866 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2867 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2868 logical_imm64_not:$imm), 0>; 2869} 2870 2871class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2872 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2873 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2874 Sched<[WriteI, ReadI, ReadI]>; 2875 2876// Split from LogicalImm as not all instructions have both. 2877multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2878 SDPatternOperator OpNode> { 2879 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2880 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2881 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2882 } 2883 2884 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2885 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2886 logical_shifted_reg32:$Rm))]> { 2887 let Inst{31} = 0; 2888 } 2889 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2890 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2891 logical_shifted_reg64:$Rm))]> { 2892 let Inst{31} = 1; 2893 } 2894 2895 def : LogicalRegAlias<mnemonic, 2896 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2897 def : LogicalRegAlias<mnemonic, 2898 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2899} 2900 2901// Split from LogicalReg to allow setting NZCV Defs 2902multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2903 SDPatternOperator OpNode = null_frag> { 2904 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2905 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2906 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2907 2908 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2909 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2910 let Inst{31} = 0; 2911 } 2912 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2913 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2914 let Inst{31} = 1; 2915 } 2916 } // Defs = [NZCV] 2917 2918 def : LogicalRegAlias<mnemonic, 2919 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2920 def : LogicalRegAlias<mnemonic, 2921 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2922} 2923 2924//--- 2925// Conditionally set flags 2926//--- 2927 2928let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2929class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2930 string mnemonic, SDNode OpNode> 2931 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2932 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2933 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2934 (i32 imm:$cond), NZCV))]>, 2935 Sched<[WriteI, ReadI]> { 2936 let Uses = [NZCV]; 2937 let Defs = [NZCV]; 2938 2939 bits<5> Rn; 2940 bits<5> imm; 2941 bits<4> nzcv; 2942 bits<4> cond; 2943 2944 let Inst{30} = op; 2945 let Inst{29-21} = 0b111010010; 2946 let Inst{20-16} = imm; 2947 let Inst{15-12} = cond; 2948 let Inst{11-10} = 0b10; 2949 let Inst{9-5} = Rn; 2950 let Inst{4} = 0b0; 2951 let Inst{3-0} = nzcv; 2952} 2953 2954let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2955class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2956 SDNode OpNode> 2957 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2958 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2959 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2960 (i32 imm:$cond), NZCV))]>, 2961 Sched<[WriteI, ReadI, ReadI]> { 2962 let Uses = [NZCV]; 2963 let Defs = [NZCV]; 2964 2965 bits<5> Rn; 2966 bits<5> Rm; 2967 bits<4> nzcv; 2968 bits<4> cond; 2969 2970 let Inst{30} = op; 2971 let Inst{29-21} = 0b111010010; 2972 let Inst{20-16} = Rm; 2973 let Inst{15-12} = cond; 2974 let Inst{11-10} = 0b00; 2975 let Inst{9-5} = Rn; 2976 let Inst{4} = 0b0; 2977 let Inst{3-0} = nzcv; 2978} 2979 2980multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2981 // immediate operand variants 2982 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2983 let Inst{31} = 0; 2984 } 2985 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2986 let Inst{31} = 1; 2987 } 2988 // register operand variants 2989 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2990 let Inst{31} = 0; 2991 } 2992 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2993 let Inst{31} = 1; 2994 } 2995} 2996 2997//--- 2998// Conditional select 2999//--- 3000 3001class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3002 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3003 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3004 [(set regtype:$Rd, 3005 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3006 Sched<[WriteI, ReadI, ReadI]> { 3007 let Uses = [NZCV]; 3008 3009 bits<5> Rd; 3010 bits<5> Rn; 3011 bits<5> Rm; 3012 bits<4> cond; 3013 3014 let Inst{30} = op; 3015 let Inst{29-21} = 0b011010100; 3016 let Inst{20-16} = Rm; 3017 let Inst{15-12} = cond; 3018 let Inst{11-10} = op2; 3019 let Inst{9-5} = Rn; 3020 let Inst{4-0} = Rd; 3021} 3022 3023multiclass CondSelect<bit op, bits<2> op2, string asm> { 3024 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3025 let Inst{31} = 0; 3026 } 3027 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3028 let Inst{31} = 1; 3029 } 3030} 3031 3032class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3033 PatFrag frag> 3034 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3035 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3036 [(set regtype:$Rd, 3037 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3038 (i32 imm:$cond), NZCV))]>, 3039 Sched<[WriteI, ReadI, ReadI]> { 3040 let Uses = [NZCV]; 3041 3042 bits<5> Rd; 3043 bits<5> Rn; 3044 bits<5> Rm; 3045 bits<4> cond; 3046 3047 let Inst{30} = op; 3048 let Inst{29-21} = 0b011010100; 3049 let Inst{20-16} = Rm; 3050 let Inst{15-12} = cond; 3051 let Inst{11-10} = op2; 3052 let Inst{9-5} = Rn; 3053 let Inst{4-0} = Rd; 3054} 3055 3056def inv_cond_XFORM : SDNodeXForm<imm, [{ 3057 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3058 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3059 MVT::i32); 3060}]>; 3061 3062multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3063 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3064 let Inst{31} = 0; 3065 } 3066 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3067 let Inst{31} = 1; 3068 } 3069 3070 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3071 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3072 (inv_cond_XFORM imm:$cond))>; 3073 3074 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3075 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3076 (inv_cond_XFORM imm:$cond))>; 3077} 3078 3079//--- 3080// Special Mask Value 3081//--- 3082def maski8_or_more : Operand<i32>, 3083 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3084} 3085def maski16_or_more : Operand<i32>, 3086 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3087} 3088 3089 3090//--- 3091// Load/store 3092//--- 3093 3094// (unsigned immediate) 3095// Indexed for 8-bit registers. offset is in range [0,4095]. 3096def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 3097def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 3098def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 3099def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 3100def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 3101 3102def gi_am_indexed8 : 3103 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3104 GIComplexPatternEquiv<am_indexed8>; 3105def gi_am_indexed16 : 3106 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3107 GIComplexPatternEquiv<am_indexed16>; 3108def gi_am_indexed32 : 3109 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3110 GIComplexPatternEquiv<am_indexed32>; 3111def gi_am_indexed64 : 3112 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3113 GIComplexPatternEquiv<am_indexed64>; 3114def gi_am_indexed128 : 3115 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3116 GIComplexPatternEquiv<am_indexed128>; 3117 3118class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3119 let Name = "UImm12Offset" # Scale; 3120 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3121 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3122 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3123} 3124 3125def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3126def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3127def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3128def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3129def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3130 3131class uimm12_scaled<int Scale> : Operand<i64> { 3132 let ParserMatchClass 3133 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3134 let EncoderMethod 3135 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3136 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3137} 3138 3139def uimm12s1 : uimm12_scaled<1>; 3140def uimm12s2 : uimm12_scaled<2>; 3141def uimm12s4 : uimm12_scaled<4>; 3142def uimm12s8 : uimm12_scaled<8>; 3143def uimm12s16 : uimm12_scaled<16>; 3144 3145class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3146 string asm, list<dag> pattern> 3147 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3148 bits<5> Rt; 3149 3150 bits<5> Rn; 3151 bits<12> offset; 3152 3153 let Inst{31-30} = sz; 3154 let Inst{29-27} = 0b111; 3155 let Inst{26} = V; 3156 let Inst{25-24} = 0b01; 3157 let Inst{23-22} = opc; 3158 let Inst{21-10} = offset; 3159 let Inst{9-5} = Rn; 3160 let Inst{4-0} = Rt; 3161 3162 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3163} 3164 3165multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3166 Operand indextype, string asm, list<dag> pattern> { 3167 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3168 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3169 (ins GPR64sp:$Rn, indextype:$offset), 3170 asm, pattern>, 3171 Sched<[WriteLD]>; 3172 3173 def : InstAlias<asm # "\t$Rt, [$Rn]", 3174 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3175} 3176 3177multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3178 Operand indextype, string asm, list<dag> pattern> { 3179 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3180 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3181 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3182 asm, pattern>, 3183 Sched<[WriteST]>; 3184 3185 def : InstAlias<asm # "\t$Rt, [$Rn]", 3186 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3187} 3188 3189// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3190// substitute zero-registers automatically. 3191// 3192// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3193// into StoreUI. 3194multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3195 Operand indextype, string asm, list<dag> pattern> { 3196 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3197 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3198 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3199 asm, pattern>, 3200 Sched<[WriteST]>; 3201 3202 def : InstAlias<asm # "\t$Rt, [$Rn]", 3203 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3204} 3205 3206def PrefetchOperand : AsmOperandClass { 3207 let Name = "Prefetch"; 3208 let ParserMethod = "tryParsePrefetch"; 3209} 3210def prfop : Operand<i32> { 3211 let PrintMethod = "printPrefetchOp"; 3212 let ParserMatchClass = PrefetchOperand; 3213} 3214 3215let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3216class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3217 : BaseLoadStoreUI<sz, V, opc, 3218 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3219 asm, pat>, 3220 Sched<[WriteLD]>; 3221 3222//--- 3223// Load literal 3224//--- 3225 3226// Load literal address: 19-bit immediate. The low two bits of the target 3227// offset are implied zero and so are not part of the immediate. 3228def am_ldrlit : Operand<iPTR> { 3229 let EncoderMethod = "getLoadLiteralOpValue"; 3230 let DecoderMethod = "DecodePCRelLabel19"; 3231 let PrintMethod = "printAlignedLabel"; 3232 let ParserMatchClass = PCRelLabel19Operand; 3233 let OperandType = "OPERAND_PCREL"; 3234} 3235 3236let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3237class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3238 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3239 asm, "\t$Rt, $label", "", pat>, 3240 Sched<[WriteLD]> { 3241 bits<5> Rt; 3242 bits<19> label; 3243 let Inst{31-30} = opc; 3244 let Inst{29-27} = 0b011; 3245 let Inst{26} = V; 3246 let Inst{25-24} = 0b00; 3247 let Inst{23-5} = label; 3248 let Inst{4-0} = Rt; 3249} 3250 3251let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3252class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3253 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3254 asm, "\t$Rt, $label", "", pat>, 3255 Sched<[WriteLD]> { 3256 bits<5> Rt; 3257 bits<19> label; 3258 let Inst{31-30} = opc; 3259 let Inst{29-27} = 0b011; 3260 let Inst{26} = V; 3261 let Inst{25-24} = 0b00; 3262 let Inst{23-5} = label; 3263 let Inst{4-0} = Rt; 3264} 3265 3266//--- 3267// Load/store register offset 3268//--- 3269 3270def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3271def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3272def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3273def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3274def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3275 3276def gi_ro_Xindexed8 : 3277 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3278 GIComplexPatternEquiv<ro_Xindexed8>; 3279def gi_ro_Xindexed16 : 3280 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3281 GIComplexPatternEquiv<ro_Xindexed16>; 3282def gi_ro_Xindexed32 : 3283 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3284 GIComplexPatternEquiv<ro_Xindexed32>; 3285def gi_ro_Xindexed64 : 3286 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3287 GIComplexPatternEquiv<ro_Xindexed64>; 3288def gi_ro_Xindexed128 : 3289 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3290 GIComplexPatternEquiv<ro_Xindexed128>; 3291 3292def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3293def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3294def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3295def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3296def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3297 3298def gi_ro_Windexed8 : 3299 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3300 GIComplexPatternEquiv<ro_Windexed8>; 3301def gi_ro_Windexed16 : 3302 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3303 GIComplexPatternEquiv<ro_Windexed16>; 3304def gi_ro_Windexed32 : 3305 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3306 GIComplexPatternEquiv<ro_Windexed32>; 3307def gi_ro_Windexed64 : 3308 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3309 GIComplexPatternEquiv<ro_Windexed64>; 3310def gi_ro_Windexed128 : 3311 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3312 GIComplexPatternEquiv<ro_Windexed128>; 3313 3314class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3315 let Name = "Mem" # Reg # "Extend" # Width; 3316 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3317 let RenderMethod = "addMemExtendOperands"; 3318 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3319} 3320 3321def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3322 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3323 // the trivial shift. 3324 let RenderMethod = "addMemExtend8Operands"; 3325} 3326def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3327def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3328def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3329def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3330 3331def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3332 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3333 // the trivial shift. 3334 let RenderMethod = "addMemExtend8Operands"; 3335} 3336def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3337def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3338def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3339def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3340 3341class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3342 : Operand<i32> { 3343 let ParserMatchClass = ParserClass; 3344 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3345 let DecoderMethod = "DecodeMemExtend"; 3346 let EncoderMethod = "getMemExtendOpValue"; 3347 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3348} 3349 3350def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3351def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3352def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3353def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3354def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3355 3356def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3357def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3358def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3359def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3360def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3361 3362class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3363 Operand wextend, Operand xextend> { 3364 // CodeGen-level pattern covering the entire addressing mode. 3365 ComplexPattern Wpat = windex; 3366 ComplexPattern Xpat = xindex; 3367 3368 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3369 Operand Wext = wextend; 3370 Operand Xext = xextend; 3371} 3372 3373def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3374def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3375def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3376def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3377def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3378 ro_Xextend128>; 3379 3380class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3381 string asm, dag ins, dag outs, list<dag> pat> 3382 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3383 bits<5> Rt; 3384 bits<5> Rn; 3385 bits<5> Rm; 3386 bits<2> extend; 3387 let Inst{31-30} = sz; 3388 let Inst{29-27} = 0b111; 3389 let Inst{26} = V; 3390 let Inst{25-24} = 0b00; 3391 let Inst{23-22} = opc; 3392 let Inst{21} = 1; 3393 let Inst{20-16} = Rm; 3394 let Inst{15} = extend{1}; // sign extend Rm? 3395 let Inst{14} = 1; 3396 let Inst{12} = extend{0}; // do shift? 3397 let Inst{11-10} = 0b10; 3398 let Inst{9-5} = Rn; 3399 let Inst{4-0} = Rt; 3400} 3401 3402class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST> 3403 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3404 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3405 3406multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3407 string asm, ValueType Ty, SDPatternOperator loadop> { 3408 let AddedComplexity = 10 in 3409 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3410 (outs regtype:$Rt), 3411 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3412 [(set (Ty regtype:$Rt), 3413 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3414 ro_Wextend8:$extend)))]>, 3415 Sched<[WriteLDIdx, ReadAdrBase]> { 3416 let Inst{13} = 0b0; 3417 } 3418 3419 let AddedComplexity = 10 in 3420 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3421 (outs regtype:$Rt), 3422 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3423 [(set (Ty regtype:$Rt), 3424 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3425 ro_Xextend8:$extend)))]>, 3426 Sched<[WriteLDIdx, ReadAdrBase]> { 3427 let Inst{13} = 0b1; 3428 } 3429 3430 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3431} 3432 3433multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3434 string asm, ValueType Ty, SDPatternOperator storeop> { 3435 let AddedComplexity = 10 in 3436 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3437 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3438 [(storeop (Ty regtype:$Rt), 3439 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3440 ro_Wextend8:$extend))]>, 3441 Sched<[WriteSTIdx, ReadAdrBase]> { 3442 let Inst{13} = 0b0; 3443 } 3444 3445 let AddedComplexity = 10 in 3446 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3447 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3448 [(storeop (Ty regtype:$Rt), 3449 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3450 ro_Xextend8:$extend))]>, 3451 Sched<[WriteSTIdx, ReadAdrBase]> { 3452 let Inst{13} = 0b1; 3453 } 3454 3455 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3456} 3457 3458class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3459 string asm, dag ins, dag outs, list<dag> pat> 3460 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3461 bits<5> Rt; 3462 bits<5> Rn; 3463 bits<5> Rm; 3464 bits<2> extend; 3465 let Inst{31-30} = sz; 3466 let Inst{29-27} = 0b111; 3467 let Inst{26} = V; 3468 let Inst{25-24} = 0b00; 3469 let Inst{23-22} = opc; 3470 let Inst{21} = 1; 3471 let Inst{20-16} = Rm; 3472 let Inst{15} = extend{1}; // sign extend Rm? 3473 let Inst{14} = 1; 3474 let Inst{12} = extend{0}; // do shift? 3475 let Inst{11-10} = 0b10; 3476 let Inst{9-5} = Rn; 3477 let Inst{4-0} = Rt; 3478} 3479 3480multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3481 string asm, ValueType Ty, SDPatternOperator loadop> { 3482 let AddedComplexity = 10 in 3483 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3484 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3485 [(set (Ty regtype:$Rt), 3486 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3487 ro_Wextend16:$extend)))]>, 3488 Sched<[WriteLDIdx, ReadAdrBase]> { 3489 let Inst{13} = 0b0; 3490 } 3491 3492 let AddedComplexity = 10 in 3493 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3494 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3495 [(set (Ty regtype:$Rt), 3496 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3497 ro_Xextend16:$extend)))]>, 3498 Sched<[WriteLDIdx, ReadAdrBase]> { 3499 let Inst{13} = 0b1; 3500 } 3501 3502 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3503} 3504 3505multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3506 string asm, ValueType Ty, SDPatternOperator storeop> { 3507 let AddedComplexity = 10 in 3508 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3509 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3510 [(storeop (Ty regtype:$Rt), 3511 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3512 ro_Wextend16:$extend))]>, 3513 Sched<[WriteSTIdx, ReadAdrBase]> { 3514 let Inst{13} = 0b0; 3515 } 3516 3517 let AddedComplexity = 10 in 3518 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3519 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3520 [(storeop (Ty regtype:$Rt), 3521 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3522 ro_Xextend16:$extend))]>, 3523 Sched<[WriteSTIdx, ReadAdrBase]> { 3524 let Inst{13} = 0b1; 3525 } 3526 3527 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3528} 3529 3530class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3531 string asm, dag ins, dag outs, list<dag> pat> 3532 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3533 bits<5> Rt; 3534 bits<5> Rn; 3535 bits<5> Rm; 3536 bits<2> extend; 3537 let Inst{31-30} = sz; 3538 let Inst{29-27} = 0b111; 3539 let Inst{26} = V; 3540 let Inst{25-24} = 0b00; 3541 let Inst{23-22} = opc; 3542 let Inst{21} = 1; 3543 let Inst{20-16} = Rm; 3544 let Inst{15} = extend{1}; // sign extend Rm? 3545 let Inst{14} = 1; 3546 let Inst{12} = extend{0}; // do shift? 3547 let Inst{11-10} = 0b10; 3548 let Inst{9-5} = Rn; 3549 let Inst{4-0} = Rt; 3550} 3551 3552multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3553 string asm, ValueType Ty, SDPatternOperator loadop> { 3554 let AddedComplexity = 10 in 3555 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3556 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3557 [(set (Ty regtype:$Rt), 3558 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3559 ro_Wextend32:$extend)))]>, 3560 Sched<[WriteLDIdx, ReadAdrBase]> { 3561 let Inst{13} = 0b0; 3562 } 3563 3564 let AddedComplexity = 10 in 3565 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3566 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3567 [(set (Ty regtype:$Rt), 3568 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3569 ro_Xextend32:$extend)))]>, 3570 Sched<[WriteLDIdx, ReadAdrBase]> { 3571 let Inst{13} = 0b1; 3572 } 3573 3574 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3575} 3576 3577multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3578 string asm, ValueType Ty, SDPatternOperator storeop> { 3579 let AddedComplexity = 10 in 3580 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3581 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3582 [(storeop (Ty regtype:$Rt), 3583 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3584 ro_Wextend32:$extend))]>, 3585 Sched<[WriteSTIdx, ReadAdrBase]> { 3586 let Inst{13} = 0b0; 3587 } 3588 3589 let AddedComplexity = 10 in 3590 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3591 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3592 [(storeop (Ty regtype:$Rt), 3593 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3594 ro_Xextend32:$extend))]>, 3595 Sched<[WriteSTIdx, ReadAdrBase]> { 3596 let Inst{13} = 0b1; 3597 } 3598 3599 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3600} 3601 3602class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3603 string asm, dag ins, dag outs, list<dag> pat> 3604 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3605 bits<5> Rt; 3606 bits<5> Rn; 3607 bits<5> Rm; 3608 bits<2> extend; 3609 let Inst{31-30} = sz; 3610 let Inst{29-27} = 0b111; 3611 let Inst{26} = V; 3612 let Inst{25-24} = 0b00; 3613 let Inst{23-22} = opc; 3614 let Inst{21} = 1; 3615 let Inst{20-16} = Rm; 3616 let Inst{15} = extend{1}; // sign extend Rm? 3617 let Inst{14} = 1; 3618 let Inst{12} = extend{0}; // do shift? 3619 let Inst{11-10} = 0b10; 3620 let Inst{9-5} = Rn; 3621 let Inst{4-0} = Rt; 3622} 3623 3624multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3625 string asm, ValueType Ty, SDPatternOperator loadop> { 3626 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3627 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3628 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3629 [(set (Ty regtype:$Rt), 3630 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3631 ro_Wextend64:$extend)))]>, 3632 Sched<[WriteLDIdx, ReadAdrBase]> { 3633 let Inst{13} = 0b0; 3634 } 3635 3636 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3637 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3638 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3639 [(set (Ty regtype:$Rt), 3640 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3641 ro_Xextend64:$extend)))]>, 3642 Sched<[WriteLDIdx, ReadAdrBase]> { 3643 let Inst{13} = 0b1; 3644 } 3645 3646 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3647} 3648 3649multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3650 string asm, ValueType Ty, SDPatternOperator storeop> { 3651 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3652 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3653 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3654 [(storeop (Ty regtype:$Rt), 3655 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3656 ro_Wextend64:$extend))]>, 3657 Sched<[WriteSTIdx, ReadAdrBase]> { 3658 let Inst{13} = 0b0; 3659 } 3660 3661 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3662 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3663 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3664 [(storeop (Ty regtype:$Rt), 3665 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3666 ro_Xextend64:$extend))]>, 3667 Sched<[WriteSTIdx, ReadAdrBase]> { 3668 let Inst{13} = 0b1; 3669 } 3670 3671 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3672} 3673 3674class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3675 string asm, dag ins, dag outs, list<dag> pat> 3676 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3677 bits<5> Rt; 3678 bits<5> Rn; 3679 bits<5> Rm; 3680 bits<2> extend; 3681 let Inst{31-30} = sz; 3682 let Inst{29-27} = 0b111; 3683 let Inst{26} = V; 3684 let Inst{25-24} = 0b00; 3685 let Inst{23-22} = opc; 3686 let Inst{21} = 1; 3687 let Inst{20-16} = Rm; 3688 let Inst{15} = extend{1}; // sign extend Rm? 3689 let Inst{14} = 1; 3690 let Inst{12} = extend{0}; // do shift? 3691 let Inst{11-10} = 0b10; 3692 let Inst{9-5} = Rn; 3693 let Inst{4-0} = Rt; 3694} 3695 3696multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3697 string asm, ValueType Ty, SDPatternOperator loadop> { 3698 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3699 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3700 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3701 [(set (Ty regtype:$Rt), 3702 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3703 ro_Wextend128:$extend)))]>, 3704 Sched<[WriteLDIdx, ReadAdrBase]> { 3705 let Inst{13} = 0b0; 3706 } 3707 3708 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3709 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3710 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3711 [(set (Ty regtype:$Rt), 3712 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3713 ro_Xextend128:$extend)))]>, 3714 Sched<[WriteLDIdx, ReadAdrBase]> { 3715 let Inst{13} = 0b1; 3716 } 3717 3718 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3719} 3720 3721multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3722 string asm, ValueType Ty, SDPatternOperator storeop> { 3723 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3724 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3725 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3726 []>, 3727 Sched<[WriteSTIdx, ReadAdrBase]> { 3728 let Inst{13} = 0b0; 3729 } 3730 3731 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3732 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3733 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3734 []>, 3735 Sched<[WriteSTIdx, ReadAdrBase]> { 3736 let Inst{13} = 0b1; 3737 } 3738 3739 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3740} 3741 3742let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3743class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3744 string asm, list<dag> pat> 3745 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3746 Sched<[WriteLD]> { 3747 bits<5> Rt; 3748 bits<5> Rn; 3749 bits<5> Rm; 3750 bits<2> extend; 3751 let Inst{31-30} = sz; 3752 let Inst{29-27} = 0b111; 3753 let Inst{26} = V; 3754 let Inst{25-24} = 0b00; 3755 let Inst{23-22} = opc; 3756 let Inst{21} = 1; 3757 let Inst{20-16} = Rm; 3758 let Inst{15} = extend{1}; // sign extend Rm? 3759 let Inst{14} = 1; 3760 let Inst{12} = extend{0}; // do shift? 3761 let Inst{11-10} = 0b10; 3762 let Inst{9-5} = Rn; 3763 let Inst{4-0} = Rt; 3764} 3765 3766multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3767 def roW : BasePrefetchRO<sz, V, opc, (outs), 3768 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3769 asm, [(AArch64Prefetch imm:$Rt, 3770 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3771 ro_Wextend64:$extend))]> { 3772 let Inst{13} = 0b0; 3773 } 3774 3775 def roX : BasePrefetchRO<sz, V, opc, (outs), 3776 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3777 asm, [(AArch64Prefetch imm:$Rt, 3778 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3779 ro_Xextend64:$extend))]> { 3780 let Inst{13} = 0b1; 3781 } 3782 3783 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3784 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3785 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3786} 3787 3788//--- 3789// Load/store unscaled immediate 3790//--- 3791 3792def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3793def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3794def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3795def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3796def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3797 3798def gi_am_unscaled8 : 3799 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3800 GIComplexPatternEquiv<am_unscaled8>; 3801def gi_am_unscaled16 : 3802 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3803 GIComplexPatternEquiv<am_unscaled16>; 3804def gi_am_unscaled32 : 3805 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3806 GIComplexPatternEquiv<am_unscaled32>; 3807def gi_am_unscaled64 : 3808 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3809 GIComplexPatternEquiv<am_unscaled64>; 3810def gi_am_unscaled128 : 3811 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3812 GIComplexPatternEquiv<am_unscaled128>; 3813 3814 3815class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3816 string asm, list<dag> pattern> 3817 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3818 bits<5> Rt; 3819 bits<5> Rn; 3820 bits<9> offset; 3821 let Inst{31-30} = sz; 3822 let Inst{29-27} = 0b111; 3823 let Inst{26} = V; 3824 let Inst{25-24} = 0b00; 3825 let Inst{23-22} = opc; 3826 let Inst{21} = 0; 3827 let Inst{20-12} = offset; 3828 let Inst{11-10} = 0b00; 3829 let Inst{9-5} = Rn; 3830 let Inst{4-0} = Rt; 3831 3832 let DecoderMethod = "DecodeSignedLdStInstruction"; 3833} 3834 3835// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3836multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3837 RegisterOperand regtype > { 3838 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3839 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3840 Sched<[WriteST]> { 3841 let Inst{29} = 0; 3842 let Inst{24} = 1; 3843 } 3844 def : InstAlias<asm # "\t$Rt, [$Rn]", 3845 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3846} 3847 3848multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3849 RegisterOperand regtype > { 3850 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3851 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3852 asm, []>, 3853 Sched<[WriteST]> { 3854 let Inst{29} = 0; 3855 let Inst{24} = 1; 3856 } 3857 def : InstAlias<asm # "\t$Rt, [$Rn]", 3858 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3859} 3860 3861multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3862 string asm, list<dag> pattern> { 3863 let AddedComplexity = 1 in // try this before LoadUI 3864 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3865 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3866 Sched<[WriteLD]>; 3867 3868 def : InstAlias<asm # "\t$Rt, [$Rn]", 3869 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3870} 3871 3872multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3873 string asm, list<dag> pattern> { 3874 let AddedComplexity = 1 in // try this before StoreUI 3875 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3876 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3877 asm, pattern>, 3878 Sched<[WriteST]>; 3879 3880 def : InstAlias<asm # "\t$Rt, [$Rn]", 3881 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3882} 3883 3884multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3885 list<dag> pat> { 3886 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3887 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3888 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3889 asm, pat>, 3890 Sched<[WriteLD]>; 3891 3892 def : InstAlias<asm # "\t$Rt, [$Rn]", 3893 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3894} 3895 3896//--- 3897// Load/store unscaled immediate, unprivileged 3898//--- 3899 3900class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3901 dag oops, dag iops, string asm> 3902 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3903 bits<5> Rt; 3904 bits<5> Rn; 3905 bits<9> offset; 3906 let Inst{31-30} = sz; 3907 let Inst{29-27} = 0b111; 3908 let Inst{26} = V; 3909 let Inst{25-24} = 0b00; 3910 let Inst{23-22} = opc; 3911 let Inst{21} = 0; 3912 let Inst{20-12} = offset; 3913 let Inst{11-10} = 0b10; 3914 let Inst{9-5} = Rn; 3915 let Inst{4-0} = Rt; 3916 3917 let DecoderMethod = "DecodeSignedLdStInstruction"; 3918} 3919 3920multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3921 RegisterClass regtype, string asm> { 3922 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3923 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3924 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3925 Sched<[WriteLD]>; 3926 3927 def : InstAlias<asm # "\t$Rt, [$Rn]", 3928 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3929} 3930 3931multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3932 RegisterClass regtype, string asm> { 3933 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3934 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3935 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3936 asm>, 3937 Sched<[WriteST]>; 3938 3939 def : InstAlias<asm # "\t$Rt, [$Rn]", 3940 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3941} 3942 3943//--- 3944// Load/store pre-indexed 3945//--- 3946 3947class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3948 string asm, string cstr, list<dag> pat> 3949 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3950 bits<5> Rt; 3951 bits<5> Rn; 3952 bits<9> offset; 3953 let Inst{31-30} = sz; 3954 let Inst{29-27} = 0b111; 3955 let Inst{26} = V; 3956 let Inst{25-24} = 0; 3957 let Inst{23-22} = opc; 3958 let Inst{21} = 0; 3959 let Inst{20-12} = offset; 3960 let Inst{11-10} = 0b11; 3961 let Inst{9-5} = Rn; 3962 let Inst{4-0} = Rt; 3963 3964 let DecoderMethod = "DecodeSignedLdStInstruction"; 3965} 3966 3967let hasSideEffects = 0 in { 3968let mayStore = 0, mayLoad = 1 in 3969class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3970 string asm> 3971 : BaseLoadStorePreIdx<sz, V, opc, 3972 (outs GPR64sp:$wback, regtype:$Rt), 3973 (ins GPR64sp:$Rn, simm9:$offset), asm, 3974 "$Rn = $wback,@earlyclobber $wback", []>, 3975 Sched<[WriteAdr, WriteLD]>; 3976 3977let mayStore = 1, mayLoad = 0 in 3978class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3979 string asm, SDPatternOperator storeop, ValueType Ty> 3980 : BaseLoadStorePreIdx<sz, V, opc, 3981 (outs GPR64sp:$wback), 3982 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3983 asm, "$Rn = $wback,@earlyclobber $wback", 3984 [(set GPR64sp:$wback, 3985 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3986 Sched<[WriteAdr, WriteST]>; 3987} // hasSideEffects = 0 3988 3989//--- 3990// Load/store post-indexed 3991//--- 3992 3993class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3994 string asm, string cstr, list<dag> pat> 3995 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3996 bits<5> Rt; 3997 bits<5> Rn; 3998 bits<9> offset; 3999 let Inst{31-30} = sz; 4000 let Inst{29-27} = 0b111; 4001 let Inst{26} = V; 4002 let Inst{25-24} = 0b00; 4003 let Inst{23-22} = opc; 4004 let Inst{21} = 0b0; 4005 let Inst{20-12} = offset; 4006 let Inst{11-10} = 0b01; 4007 let Inst{9-5} = Rn; 4008 let Inst{4-0} = Rt; 4009 4010 let DecoderMethod = "DecodeSignedLdStInstruction"; 4011} 4012 4013let hasSideEffects = 0 in { 4014let mayStore = 0, mayLoad = 1 in 4015class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4016 string asm> 4017 : BaseLoadStorePostIdx<sz, V, opc, 4018 (outs GPR64sp:$wback, regtype:$Rt), 4019 (ins GPR64sp:$Rn, simm9:$offset), 4020 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4021 Sched<[WriteAdr, WriteLD]>; 4022 4023let mayStore = 1, mayLoad = 0 in 4024class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4025 string asm, SDPatternOperator storeop, ValueType Ty> 4026 : BaseLoadStorePostIdx<sz, V, opc, 4027 (outs GPR64sp:$wback), 4028 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4029 asm, "$Rn = $wback,@earlyclobber $wback", 4030 [(set GPR64sp:$wback, 4031 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4032 Sched<[WriteAdr, WriteST]>; 4033} // hasSideEffects = 0 4034 4035 4036//--- 4037// Load/store pair 4038//--- 4039 4040// (indexed, offset) 4041 4042class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4043 string asm> 4044 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4045 bits<5> Rt; 4046 bits<5> Rt2; 4047 bits<5> Rn; 4048 bits<7> offset; 4049 let Inst{31-30} = opc; 4050 let Inst{29-27} = 0b101; 4051 let Inst{26} = V; 4052 let Inst{25-23} = 0b010; 4053 let Inst{22} = L; 4054 let Inst{21-15} = offset; 4055 let Inst{14-10} = Rt2; 4056 let Inst{9-5} = Rn; 4057 let Inst{4-0} = Rt; 4058 4059 let DecoderMethod = "DecodePairLdStInstruction"; 4060} 4061 4062multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4063 Operand indextype, string asm> { 4064 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4065 def i : BaseLoadStorePairOffset<opc, V, 1, 4066 (outs regtype:$Rt, regtype:$Rt2), 4067 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4068 Sched<[WriteLD, WriteLDHi]>; 4069 4070 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4071 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4072 GPR64sp:$Rn, 0)>; 4073} 4074 4075 4076multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4077 Operand indextype, string asm> { 4078 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4079 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4080 (ins regtype:$Rt, regtype:$Rt2, 4081 GPR64sp:$Rn, indextype:$offset), 4082 asm>, 4083 Sched<[WriteSTP]>; 4084 4085 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4086 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4087 GPR64sp:$Rn, 0)>; 4088} 4089 4090// (pre-indexed) 4091class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4092 string asm> 4093 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4094 bits<5> Rt; 4095 bits<5> Rt2; 4096 bits<5> Rn; 4097 bits<7> offset; 4098 let Inst{31-30} = opc; 4099 let Inst{29-27} = 0b101; 4100 let Inst{26} = V; 4101 let Inst{25-23} = 0b011; 4102 let Inst{22} = L; 4103 let Inst{21-15} = offset; 4104 let Inst{14-10} = Rt2; 4105 let Inst{9-5} = Rn; 4106 let Inst{4-0} = Rt; 4107 4108 let DecoderMethod = "DecodePairLdStInstruction"; 4109} 4110 4111let hasSideEffects = 0 in { 4112let mayStore = 0, mayLoad = 1 in 4113class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4114 Operand indextype, string asm> 4115 : BaseLoadStorePairPreIdx<opc, V, 1, 4116 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4117 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4118 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4119 4120let mayStore = 1, mayLoad = 0 in 4121class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4122 Operand indextype, string asm> 4123 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4124 (ins regtype:$Rt, regtype:$Rt2, 4125 GPR64sp:$Rn, indextype:$offset), 4126 asm>, 4127 Sched<[WriteAdr, WriteSTP]>; 4128} // hasSideEffects = 0 4129 4130// (post-indexed) 4131 4132class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4133 string asm> 4134 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4135 bits<5> Rt; 4136 bits<5> Rt2; 4137 bits<5> Rn; 4138 bits<7> offset; 4139 let Inst{31-30} = opc; 4140 let Inst{29-27} = 0b101; 4141 let Inst{26} = V; 4142 let Inst{25-23} = 0b001; 4143 let Inst{22} = L; 4144 let Inst{21-15} = offset; 4145 let Inst{14-10} = Rt2; 4146 let Inst{9-5} = Rn; 4147 let Inst{4-0} = Rt; 4148 4149 let DecoderMethod = "DecodePairLdStInstruction"; 4150} 4151 4152let hasSideEffects = 0 in { 4153let mayStore = 0, mayLoad = 1 in 4154class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4155 Operand idxtype, string asm> 4156 : BaseLoadStorePairPostIdx<opc, V, 1, 4157 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4158 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4159 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4160 4161let mayStore = 1, mayLoad = 0 in 4162class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4163 Operand idxtype, string asm> 4164 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4165 (ins regtype:$Rt, regtype:$Rt2, 4166 GPR64sp:$Rn, idxtype:$offset), 4167 asm>, 4168 Sched<[WriteAdr, WriteSTP]>; 4169} // hasSideEffects = 0 4170 4171// (no-allocate) 4172 4173class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4174 string asm> 4175 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4176 bits<5> Rt; 4177 bits<5> Rt2; 4178 bits<5> Rn; 4179 bits<7> offset; 4180 let Inst{31-30} = opc; 4181 let Inst{29-27} = 0b101; 4182 let Inst{26} = V; 4183 let Inst{25-23} = 0b000; 4184 let Inst{22} = L; 4185 let Inst{21-15} = offset; 4186 let Inst{14-10} = Rt2; 4187 let Inst{9-5} = Rn; 4188 let Inst{4-0} = Rt; 4189 4190 let DecoderMethod = "DecodePairLdStInstruction"; 4191} 4192 4193multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4194 Operand indextype, string asm> { 4195 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4196 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4197 (outs regtype:$Rt, regtype:$Rt2), 4198 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4199 Sched<[WriteLD, WriteLDHi]>; 4200 4201 4202 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4203 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4204 GPR64sp:$Rn, 0)>; 4205} 4206 4207multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4208 Operand indextype, string asm> { 4209 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4210 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4211 (ins regtype:$Rt, regtype:$Rt2, 4212 GPR64sp:$Rn, indextype:$offset), 4213 asm>, 4214 Sched<[WriteSTP]>; 4215 4216 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4217 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4218 GPR64sp:$Rn, 0)>; 4219} 4220 4221//--- 4222// Load/store exclusive 4223//--- 4224 4225// True exclusive operations write to and/or read from the system's exclusive 4226// monitors, which as far as a compiler is concerned can be modelled as a 4227// random shared memory address. Hence LoadExclusive mayStore. 4228// 4229// Since these instructions have the undefined register bits set to 1 in 4230// their canonical form, we need a post encoder method to set those bits 4231// to 1 when encoding these instructions. We do this using the 4232// fixLoadStoreExclusive function. This function has template parameters: 4233// 4234// fixLoadStoreExclusive<int hasRs, int hasRt2> 4235// 4236// hasRs indicates that the instruction uses the Rs field, so we won't set 4237// it to 1 (and the same for Rt2). We don't need template parameters for 4238// the other register fields since Rt and Rn are always used. 4239// 4240let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4241class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4242 dag oops, dag iops, string asm, string operands> 4243 : I<oops, iops, asm, operands, "", []> { 4244 let Inst{31-30} = sz; 4245 let Inst{29-24} = 0b001000; 4246 let Inst{23} = o2; 4247 let Inst{22} = L; 4248 let Inst{21} = o1; 4249 let Inst{15} = o0; 4250 4251 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4252} 4253 4254// Neither Rs nor Rt2 operands. 4255class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4256 dag oops, dag iops, string asm, string operands> 4257 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4258 bits<5> Rt; 4259 bits<5> Rn; 4260 let Inst{20-16} = 0b11111; 4261 let Unpredictable{20-16} = 0b11111; 4262 let Inst{14-10} = 0b11111; 4263 let Unpredictable{14-10} = 0b11111; 4264 let Inst{9-5} = Rn; 4265 let Inst{4-0} = Rt; 4266 4267 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4268} 4269 4270// Simple load acquires don't set the exclusive monitor 4271let mayLoad = 1, mayStore = 0 in 4272class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4273 RegisterClass regtype, string asm> 4274 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4275 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4276 Sched<[WriteLD]>; 4277 4278class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4279 RegisterClass regtype, string asm> 4280 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4281 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4282 Sched<[WriteLD]>; 4283 4284class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4285 RegisterClass regtype, string asm> 4286 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4287 (outs regtype:$Rt, regtype:$Rt2), 4288 (ins GPR64sp0:$Rn), asm, 4289 "\t$Rt, $Rt2, [$Rn]">, 4290 Sched<[WriteLD, WriteLDHi]> { 4291 bits<5> Rt; 4292 bits<5> Rt2; 4293 bits<5> Rn; 4294 let Inst{14-10} = Rt2; 4295 let Inst{9-5} = Rn; 4296 let Inst{4-0} = Rt; 4297 4298 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4299} 4300 4301// Simple store release operations do not check the exclusive monitor. 4302let mayLoad = 0, mayStore = 1 in 4303class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4304 RegisterClass regtype, string asm> 4305 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4306 (ins regtype:$Rt, GPR64sp0:$Rn), 4307 asm, "\t$Rt, [$Rn]">, 4308 Sched<[WriteST]>; 4309 4310let mayLoad = 1, mayStore = 1 in 4311class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4312 RegisterClass regtype, string asm> 4313 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4314 (ins regtype:$Rt, GPR64sp0:$Rn), 4315 asm, "\t$Ws, $Rt, [$Rn]">, 4316 Sched<[WriteSTX]> { 4317 bits<5> Ws; 4318 bits<5> Rt; 4319 bits<5> Rn; 4320 let Inst{20-16} = Ws; 4321 let Inst{9-5} = Rn; 4322 let Inst{4-0} = Rt; 4323 4324 let Constraints = "@earlyclobber $Ws"; 4325 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4326} 4327 4328class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4329 RegisterClass regtype, string asm> 4330 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4331 (outs GPR32:$Ws), 4332 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4333 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4334 Sched<[WriteSTX]> { 4335 bits<5> Ws; 4336 bits<5> Rt; 4337 bits<5> Rt2; 4338 bits<5> Rn; 4339 let Inst{20-16} = Ws; 4340 let Inst{14-10} = Rt2; 4341 let Inst{9-5} = Rn; 4342 let Inst{4-0} = Rt; 4343 4344 let Constraints = "@earlyclobber $Ws"; 4345} 4346 4347// Armv8.5-A Memory Tagging Extension 4348class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4349 string asm_opnds, string cstr, dag oops, dag iops> 4350 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4351 Sched<[]> { 4352 bits<5> Rn; 4353 4354 let Inst{31-24} = 0b11011001; 4355 let Inst{23-22} = opc1; 4356 let Inst{21} = 1; 4357 // Inst{20-12} defined by subclass 4358 let Inst{11-10} = opc2; 4359 let Inst{9-5} = Rn; 4360 // Inst{4-0} defined by subclass 4361} 4362 4363class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4364 dag oops, dag iops> 4365 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4366 "", oops, iops> { 4367 bits<5> Rt; 4368 4369 let Inst{20-12} = 0b000000000; 4370 let Inst{4-0} = Rt; 4371 4372 let mayLoad = Load; 4373} 4374 4375class MemTagLoad<string asm_insn, string asm_opnds> 4376 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4377 (outs GPR64:$wback), 4378 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4379 bits<5> Rt; 4380 bits<9> offset; 4381 4382 let Inst{20-12} = offset; 4383 let Inst{4-0} = Rt; 4384 4385 let mayLoad = 1; 4386} 4387 4388class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4389 string asm_opnds, string cstr, dag oops, dag iops> 4390 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4391 bits<5> Rt; 4392 bits<9> offset; 4393 4394 let Inst{20-12} = offset; 4395 let Inst{4-0} = Rt; 4396 4397 let mayStore = 1; 4398} 4399 4400multiclass MemTagStore<bits<2> opc1, string insn> { 4401 def Offset : 4402 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4403 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4404 def PreIndex : 4405 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4406 "$Rn = $wback", 4407 (outs GPR64sp:$wback), 4408 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4409 def PostIndex : 4410 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4411 "$Rn = $wback", 4412 (outs GPR64sp:$wback), 4413 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4414 4415 def : InstAlias<insn # "\t$Rt, [$Rn]", 4416 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4417} 4418 4419//--- 4420// Exception generation 4421//--- 4422 4423let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4424class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4425 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4426 Sched<[WriteSys]> { 4427 bits<16> imm; 4428 let Inst{31-24} = 0b11010100; 4429 let Inst{23-21} = op1; 4430 let Inst{20-5} = imm; 4431 let Inst{4-2} = 0b000; 4432 let Inst{1-0} = ll; 4433} 4434 4435//--- 4436// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4437//-- 4438let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4439class UDFType<bits<16> opc, string asm> 4440 : I<(outs), (ins uimm16:$imm), 4441 asm, "\t$imm", "", []>, 4442 Sched<[]> { 4443 bits<16> imm; 4444 let Inst{31-16} = opc; 4445 let Inst{15-0} = imm; 4446} 4447} 4448let Predicates = [HasFPARMv8] in { 4449 4450//--- 4451// Floating point to integer conversion 4452//--- 4453 4454class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4455 RegisterClass srcType, RegisterClass dstType, 4456 string asm, list<dag> pattern> 4457 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4458 asm, "\t$Rd, $Rn", "", pattern>, 4459 Sched<[WriteFCvt]> { 4460 bits<5> Rd; 4461 bits<5> Rn; 4462 let Inst{30-29} = 0b00; 4463 let Inst{28-24} = 0b11110; 4464 let Inst{23-22} = type; 4465 let Inst{21} = 1; 4466 let Inst{20-19} = rmode; 4467 let Inst{18-16} = opcode; 4468 let Inst{15-10} = 0; 4469 let Inst{9-5} = Rn; 4470 let Inst{4-0} = Rd; 4471} 4472 4473let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4474class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4475 RegisterClass srcType, RegisterClass dstType, 4476 Operand immType, string asm, list<dag> pattern> 4477 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4478 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4479 Sched<[WriteFCvt]> { 4480 bits<5> Rd; 4481 bits<5> Rn; 4482 bits<6> scale; 4483 let Inst{30-29} = 0b00; 4484 let Inst{28-24} = 0b11110; 4485 let Inst{23-22} = type; 4486 let Inst{21} = 0; 4487 let Inst{20-19} = rmode; 4488 let Inst{18-16} = opcode; 4489 let Inst{15-10} = scale; 4490 let Inst{9-5} = Rn; 4491 let Inst{4-0} = Rd; 4492} 4493 4494multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4495 SDPatternOperator OpN> { 4496 // Unscaled half-precision to 32-bit 4497 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4498 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4499 let Inst{31} = 0; // 32-bit GPR flag 4500 let Predicates = [HasFullFP16]; 4501 } 4502 4503 // Unscaled half-precision to 64-bit 4504 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4505 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4506 let Inst{31} = 1; // 64-bit GPR flag 4507 let Predicates = [HasFullFP16]; 4508 } 4509 4510 // Unscaled single-precision to 32-bit 4511 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4512 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4513 let Inst{31} = 0; // 32-bit GPR flag 4514 } 4515 4516 // Unscaled single-precision to 64-bit 4517 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4518 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4519 let Inst{31} = 1; // 64-bit GPR flag 4520 } 4521 4522 // Unscaled double-precision to 32-bit 4523 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4524 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4525 let Inst{31} = 0; // 32-bit GPR flag 4526 } 4527 4528 // Unscaled double-precision to 64-bit 4529 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4530 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4531 let Inst{31} = 1; // 64-bit GPR flag 4532 } 4533} 4534 4535multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4536 SDPatternOperator OpN> { 4537 // Scaled half-precision to 32-bit 4538 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4539 fixedpoint_f16_i32, asm, 4540 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4541 fixedpoint_f16_i32:$scale)))]> { 4542 let Inst{31} = 0; // 32-bit GPR flag 4543 let scale{5} = 1; 4544 let Predicates = [HasFullFP16]; 4545 } 4546 4547 // Scaled half-precision to 64-bit 4548 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4549 fixedpoint_f16_i64, asm, 4550 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4551 fixedpoint_f16_i64:$scale)))]> { 4552 let Inst{31} = 1; // 64-bit GPR flag 4553 let Predicates = [HasFullFP16]; 4554 } 4555 4556 // Scaled single-precision to 32-bit 4557 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4558 fixedpoint_f32_i32, asm, 4559 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4560 fixedpoint_f32_i32:$scale)))]> { 4561 let Inst{31} = 0; // 32-bit GPR flag 4562 let scale{5} = 1; 4563 } 4564 4565 // Scaled single-precision to 64-bit 4566 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4567 fixedpoint_f32_i64, asm, 4568 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4569 fixedpoint_f32_i64:$scale)))]> { 4570 let Inst{31} = 1; // 64-bit GPR flag 4571 } 4572 4573 // Scaled double-precision to 32-bit 4574 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4575 fixedpoint_f64_i32, asm, 4576 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4577 fixedpoint_f64_i32:$scale)))]> { 4578 let Inst{31} = 0; // 32-bit GPR flag 4579 let scale{5} = 1; 4580 } 4581 4582 // Scaled double-precision to 64-bit 4583 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4584 fixedpoint_f64_i64, asm, 4585 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4586 fixedpoint_f64_i64:$scale)))]> { 4587 let Inst{31} = 1; // 64-bit GPR flag 4588 } 4589} 4590 4591//--- 4592// Integer to floating point conversion 4593//--- 4594 4595let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4596class BaseIntegerToFP<bit isUnsigned, 4597 RegisterClass srcType, RegisterClass dstType, 4598 Operand immType, string asm, list<dag> pattern> 4599 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4600 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4601 Sched<[WriteFCvt]> { 4602 bits<5> Rd; 4603 bits<5> Rn; 4604 bits<6> scale; 4605 let Inst{30-24} = 0b0011110; 4606 let Inst{21-17} = 0b00001; 4607 let Inst{16} = isUnsigned; 4608 let Inst{15-10} = scale; 4609 let Inst{9-5} = Rn; 4610 let Inst{4-0} = Rd; 4611} 4612 4613class BaseIntegerToFPUnscaled<bit isUnsigned, 4614 RegisterClass srcType, RegisterClass dstType, 4615 ValueType dvt, string asm, SDNode node> 4616 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4617 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4618 Sched<[WriteFCvt]> { 4619 bits<5> Rd; 4620 bits<5> Rn; 4621 bits<6> scale; 4622 let Inst{30-24} = 0b0011110; 4623 let Inst{21-17} = 0b10001; 4624 let Inst{16} = isUnsigned; 4625 let Inst{15-10} = 0b000000; 4626 let Inst{9-5} = Rn; 4627 let Inst{4-0} = Rd; 4628} 4629 4630multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 4631 // Unscaled 4632 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4633 let Inst{31} = 0; // 32-bit GPR flag 4634 let Inst{23-22} = 0b11; // 16-bit FPR flag 4635 let Predicates = [HasFullFP16]; 4636 } 4637 4638 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4639 let Inst{31} = 0; // 32-bit GPR flag 4640 let Inst{23-22} = 0b00; // 32-bit FPR flag 4641 } 4642 4643 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4644 let Inst{31} = 0; // 32-bit GPR flag 4645 let Inst{23-22} = 0b01; // 64-bit FPR flag 4646 } 4647 4648 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4649 let Inst{31} = 1; // 64-bit GPR flag 4650 let Inst{23-22} = 0b11; // 16-bit FPR flag 4651 let Predicates = [HasFullFP16]; 4652 } 4653 4654 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4655 let Inst{31} = 1; // 64-bit GPR flag 4656 let Inst{23-22} = 0b00; // 32-bit FPR flag 4657 } 4658 4659 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4660 let Inst{31} = 1; // 64-bit GPR flag 4661 let Inst{23-22} = 0b01; // 64-bit FPR flag 4662 } 4663 4664 // Scaled 4665 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4666 [(set (f16 FPR16:$Rd), 4667 (fdiv (node GPR32:$Rn), 4668 fixedpoint_f16_i32:$scale))]> { 4669 let Inst{31} = 0; // 32-bit GPR flag 4670 let Inst{23-22} = 0b11; // 16-bit FPR flag 4671 let scale{5} = 1; 4672 let Predicates = [HasFullFP16]; 4673 } 4674 4675 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4676 [(set FPR32:$Rd, 4677 (fdiv (node GPR32:$Rn), 4678 fixedpoint_f32_i32:$scale))]> { 4679 let Inst{31} = 0; // 32-bit GPR flag 4680 let Inst{23-22} = 0b00; // 32-bit FPR flag 4681 let scale{5} = 1; 4682 } 4683 4684 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4685 [(set FPR64:$Rd, 4686 (fdiv (node GPR32:$Rn), 4687 fixedpoint_f64_i32:$scale))]> { 4688 let Inst{31} = 0; // 32-bit GPR flag 4689 let Inst{23-22} = 0b01; // 64-bit FPR flag 4690 let scale{5} = 1; 4691 } 4692 4693 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4694 [(set (f16 FPR16:$Rd), 4695 (fdiv (node GPR64:$Rn), 4696 fixedpoint_f16_i64:$scale))]> { 4697 let Inst{31} = 1; // 64-bit GPR flag 4698 let Inst{23-22} = 0b11; // 16-bit FPR flag 4699 let Predicates = [HasFullFP16]; 4700 } 4701 4702 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4703 [(set FPR32:$Rd, 4704 (fdiv (node GPR64:$Rn), 4705 fixedpoint_f32_i64:$scale))]> { 4706 let Inst{31} = 1; // 64-bit GPR flag 4707 let Inst{23-22} = 0b00; // 32-bit FPR flag 4708 } 4709 4710 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4711 [(set FPR64:$Rd, 4712 (fdiv (node GPR64:$Rn), 4713 fixedpoint_f64_i64:$scale))]> { 4714 let Inst{31} = 1; // 64-bit GPR flag 4715 let Inst{23-22} = 0b01; // 64-bit FPR flag 4716 } 4717} 4718 4719//--- 4720// Unscaled integer <-> floating point conversion (i.e. FMOV) 4721//--- 4722 4723let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4724class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4725 RegisterClass srcType, RegisterClass dstType, 4726 string asm> 4727 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4728 // We use COPY_TO_REGCLASS for these bitconvert operations. 4729 // copyPhysReg() expands the resultant COPY instructions after 4730 // regalloc is done. This gives greater freedom for the allocator 4731 // and related passes (coalescing, copy propagation, et. al.) to 4732 // be more effective. 4733 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4734 Sched<[WriteFCopy]> { 4735 bits<5> Rd; 4736 bits<5> Rn; 4737 let Inst{30-24} = 0b0011110; 4738 let Inst{21} = 1; 4739 let Inst{20-19} = rmode; 4740 let Inst{18-16} = opcode; 4741 let Inst{15-10} = 0b000000; 4742 let Inst{9-5} = Rn; 4743 let Inst{4-0} = Rd; 4744} 4745 4746let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4747class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4748 RegisterClass srcType, RegisterOperand dstType, string asm, 4749 string kind> 4750 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4751 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4752 Sched<[WriteFCopy]> { 4753 bits<5> Rd; 4754 bits<5> Rn; 4755 let Inst{30-23} = 0b00111101; 4756 let Inst{21} = 1; 4757 let Inst{20-19} = rmode; 4758 let Inst{18-16} = opcode; 4759 let Inst{15-10} = 0b000000; 4760 let Inst{9-5} = Rn; 4761 let Inst{4-0} = Rd; 4762 4763 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4764} 4765 4766let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4767class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4768 RegisterOperand srcType, RegisterClass dstType, string asm, 4769 string kind> 4770 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4771 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4772 Sched<[WriteFCopy]> { 4773 bits<5> Rd; 4774 bits<5> Rn; 4775 let Inst{30-23} = 0b00111101; 4776 let Inst{21} = 1; 4777 let Inst{20-19} = rmode; 4778 let Inst{18-16} = opcode; 4779 let Inst{15-10} = 0b000000; 4780 let Inst{9-5} = Rn; 4781 let Inst{4-0} = Rd; 4782 4783 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4784} 4785 4786 4787multiclass UnscaledConversion<string asm> { 4788 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4789 let Inst{31} = 0; // 32-bit GPR flag 4790 let Inst{23-22} = 0b11; // 16-bit FPR flag 4791 let Predicates = [HasFullFP16]; 4792 } 4793 4794 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4795 let Inst{31} = 1; // 64-bit GPR flag 4796 let Inst{23-22} = 0b11; // 16-bit FPR flag 4797 let Predicates = [HasFullFP16]; 4798 } 4799 4800 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4801 let Inst{31} = 0; // 32-bit GPR flag 4802 let Inst{23-22} = 0b00; // 32-bit FPR flag 4803 } 4804 4805 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4806 let Inst{31} = 1; // 64-bit GPR flag 4807 let Inst{23-22} = 0b01; // 64-bit FPR flag 4808 } 4809 4810 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4811 let Inst{31} = 0; // 32-bit GPR flag 4812 let Inst{23-22} = 0b11; // 16-bit FPR flag 4813 let Predicates = [HasFullFP16]; 4814 } 4815 4816 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4817 let Inst{31} = 1; // 64-bit GPR flag 4818 let Inst{23-22} = 0b11; // 16-bit FPR flag 4819 let Predicates = [HasFullFP16]; 4820 } 4821 4822 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4823 let Inst{31} = 0; // 32-bit GPR flag 4824 let Inst{23-22} = 0b00; // 32-bit FPR flag 4825 } 4826 4827 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4828 let Inst{31} = 1; // 64-bit GPR flag 4829 let Inst{23-22} = 0b01; // 64-bit FPR flag 4830 } 4831 4832 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4833 asm, ".d"> { 4834 let Inst{31} = 1; 4835 let Inst{22} = 0; 4836 } 4837 4838 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4839 asm, ".d"> { 4840 let Inst{31} = 1; 4841 let Inst{22} = 0; 4842 } 4843} 4844 4845//--- 4846// Floating point conversion 4847//--- 4848 4849class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4850 RegisterClass srcType, string asm, list<dag> pattern> 4851 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4852 Sched<[WriteFCvt]> { 4853 bits<5> Rd; 4854 bits<5> Rn; 4855 let Inst{31-24} = 0b00011110; 4856 let Inst{23-22} = type; 4857 let Inst{21-17} = 0b10001; 4858 let Inst{16-15} = opcode; 4859 let Inst{14-10} = 0b10000; 4860 let Inst{9-5} = Rn; 4861 let Inst{4-0} = Rd; 4862} 4863 4864multiclass FPConversion<string asm> { 4865 // Double-precision to Half-precision 4866 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4867 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4868 4869 // Double-precision to Single-precision 4870 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4871 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4872 4873 // Half-precision to Double-precision 4874 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4875 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4876 4877 // Half-precision to Single-precision 4878 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4879 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4880 4881 // Single-precision to Double-precision 4882 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4883 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4884 4885 // Single-precision to Half-precision 4886 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4887 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 4888} 4889 4890//--- 4891// Single operand floating point data processing 4892//--- 4893 4894let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4895class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4896 ValueType vt, string asm, SDPatternOperator node> 4897 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4898 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4899 Sched<[WriteF]> { 4900 bits<5> Rd; 4901 bits<5> Rn; 4902 let Inst{31-24} = 0b00011110; 4903 let Inst{21} = 0b1; 4904 let Inst{20-15} = opcode; 4905 let Inst{14-10} = 0b10000; 4906 let Inst{9-5} = Rn; 4907 let Inst{4-0} = Rd; 4908} 4909 4910multiclass SingleOperandFPData<bits<4> opcode, string asm, 4911 SDPatternOperator node = null_frag> { 4912 4913 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4914 let Inst{23-22} = 0b11; // 16-bit size flag 4915 let Predicates = [HasFullFP16]; 4916 } 4917 4918 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4919 let Inst{23-22} = 0b00; // 32-bit size flag 4920 } 4921 4922 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4923 let Inst{23-22} = 0b01; // 64-bit size flag 4924 } 4925} 4926 4927multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4928 SDPatternOperator node = null_frag>{ 4929 4930 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4931 let Inst{23-22} = 0b00; // 32-bit registers 4932 } 4933 4934 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4935 let Inst{23-22} = 0b01; // 64-bit registers 4936 } 4937} 4938 4939// FRInt[32|64][Z|N] instructions 4940multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4941 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4942 4943//--- 4944// Two operand floating point data processing 4945//--- 4946 4947let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4948class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4949 string asm, list<dag> pat> 4950 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4951 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4952 Sched<[WriteF]> { 4953 bits<5> Rd; 4954 bits<5> Rn; 4955 bits<5> Rm; 4956 let Inst{31-24} = 0b00011110; 4957 let Inst{21} = 1; 4958 let Inst{20-16} = Rm; 4959 let Inst{15-12} = opcode; 4960 let Inst{11-10} = 0b10; 4961 let Inst{9-5} = Rn; 4962 let Inst{4-0} = Rd; 4963} 4964 4965multiclass TwoOperandFPData<bits<4> opcode, string asm, 4966 SDPatternOperator node = null_frag> { 4967 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4968 [(set (f16 FPR16:$Rd), 4969 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4970 let Inst{23-22} = 0b11; // 16-bit size flag 4971 let Predicates = [HasFullFP16]; 4972 } 4973 4974 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4975 [(set (f32 FPR32:$Rd), 4976 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4977 let Inst{23-22} = 0b00; // 32-bit size flag 4978 } 4979 4980 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4981 [(set (f64 FPR64:$Rd), 4982 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4983 let Inst{23-22} = 0b01; // 64-bit size flag 4984 } 4985} 4986 4987multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4988 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4989 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 4990 let Inst{23-22} = 0b11; // 16-bit size flag 4991 let Predicates = [HasFullFP16]; 4992 } 4993 4994 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4995 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4996 let Inst{23-22} = 0b00; // 32-bit size flag 4997 } 4998 4999 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5000 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5001 let Inst{23-22} = 0b01; // 64-bit size flag 5002 } 5003} 5004 5005 5006//--- 5007// Three operand floating point data processing 5008//--- 5009 5010class BaseThreeOperandFPData<bit isNegated, bit isSub, 5011 RegisterClass regtype, string asm, list<dag> pat> 5012 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5013 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5014 Sched<[WriteFMul]> { 5015 bits<5> Rd; 5016 bits<5> Rn; 5017 bits<5> Rm; 5018 bits<5> Ra; 5019 let Inst{31-24} = 0b00011111; 5020 let Inst{21} = isNegated; 5021 let Inst{20-16} = Rm; 5022 let Inst{15} = isSub; 5023 let Inst{14-10} = Ra; 5024 let Inst{9-5} = Rn; 5025 let Inst{4-0} = Rd; 5026} 5027 5028multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5029 SDPatternOperator node> { 5030 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5031 [(set (f16 FPR16:$Rd), 5032 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5033 let Inst{23-22} = 0b11; // 16-bit size flag 5034 let Predicates = [HasFullFP16]; 5035 } 5036 5037 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5038 [(set FPR32:$Rd, 5039 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5040 let Inst{23-22} = 0b00; // 32-bit size flag 5041 } 5042 5043 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5044 [(set FPR64:$Rd, 5045 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5046 let Inst{23-22} = 0b01; // 64-bit size flag 5047 } 5048} 5049 5050//--- 5051// Floating point data comparisons 5052//--- 5053 5054let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5055class BaseOneOperandFPComparison<bit signalAllNans, 5056 RegisterClass regtype, string asm, 5057 list<dag> pat> 5058 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5059 Sched<[WriteFCmp]> { 5060 bits<5> Rn; 5061 let Inst{31-24} = 0b00011110; 5062 let Inst{21} = 1; 5063 5064 let Inst{15-10} = 0b001000; 5065 let Inst{9-5} = Rn; 5066 let Inst{4} = signalAllNans; 5067 let Inst{3-0} = 0b1000; 5068 5069 // Rm should be 0b00000 canonically, but we need to accept any value. 5070 let PostEncoderMethod = "fixOneOperandFPComparison"; 5071} 5072 5073let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5074class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5075 string asm, list<dag> pat> 5076 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5077 Sched<[WriteFCmp]> { 5078 bits<5> Rm; 5079 bits<5> Rn; 5080 let Inst{31-24} = 0b00011110; 5081 let Inst{21} = 1; 5082 let Inst{20-16} = Rm; 5083 let Inst{15-10} = 0b001000; 5084 let Inst{9-5} = Rn; 5085 let Inst{4} = signalAllNans; 5086 let Inst{3-0} = 0b0000; 5087} 5088 5089multiclass FPComparison<bit signalAllNans, string asm, 5090 SDPatternOperator OpNode = null_frag> { 5091 let Defs = [NZCV] in { 5092 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5093 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5094 let Inst{23-22} = 0b11; 5095 let Predicates = [HasFullFP16]; 5096 } 5097 5098 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5099 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5100 let Inst{23-22} = 0b11; 5101 let Predicates = [HasFullFP16]; 5102 } 5103 5104 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5105 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5106 let Inst{23-22} = 0b00; 5107 } 5108 5109 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5110 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5111 let Inst{23-22} = 0b00; 5112 } 5113 5114 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5115 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5116 let Inst{23-22} = 0b01; 5117 } 5118 5119 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5120 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5121 let Inst{23-22} = 0b01; 5122 } 5123 } // Defs = [NZCV] 5124} 5125 5126//--- 5127// Floating point conditional comparisons 5128//--- 5129 5130let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5131class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5132 string mnemonic, list<dag> pat> 5133 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5134 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5135 Sched<[WriteFCmp]> { 5136 let Uses = [NZCV]; 5137 let Defs = [NZCV]; 5138 5139 bits<5> Rn; 5140 bits<5> Rm; 5141 bits<4> nzcv; 5142 bits<4> cond; 5143 5144 let Inst{31-24} = 0b00011110; 5145 let Inst{21} = 1; 5146 let Inst{20-16} = Rm; 5147 let Inst{15-12} = cond; 5148 let Inst{11-10} = 0b01; 5149 let Inst{9-5} = Rn; 5150 let Inst{4} = signalAllNans; 5151 let Inst{3-0} = nzcv; 5152} 5153 5154multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5155 SDPatternOperator OpNode = null_frag> { 5156 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5157 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5158 (i32 imm:$cond), NZCV))]> { 5159 let Inst{23-22} = 0b11; 5160 let Predicates = [HasFullFP16]; 5161 } 5162 5163 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5164 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5165 (i32 imm:$cond), NZCV))]> { 5166 let Inst{23-22} = 0b00; 5167 } 5168 5169 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5170 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5171 (i32 imm:$cond), NZCV))]> { 5172 let Inst{23-22} = 0b01; 5173 } 5174} 5175 5176//--- 5177// Floating point conditional select 5178//--- 5179 5180class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5181 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5182 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5183 [(set regtype:$Rd, 5184 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5185 (i32 imm:$cond), NZCV))]>, 5186 Sched<[WriteF]> { 5187 bits<5> Rd; 5188 bits<5> Rn; 5189 bits<5> Rm; 5190 bits<4> cond; 5191 5192 let Inst{31-24} = 0b00011110; 5193 let Inst{21} = 1; 5194 let Inst{20-16} = Rm; 5195 let Inst{15-12} = cond; 5196 let Inst{11-10} = 0b11; 5197 let Inst{9-5} = Rn; 5198 let Inst{4-0} = Rd; 5199} 5200 5201multiclass FPCondSelect<string asm> { 5202 let Uses = [NZCV] in { 5203 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5204 let Inst{23-22} = 0b11; 5205 let Predicates = [HasFullFP16]; 5206 } 5207 5208 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5209 let Inst{23-22} = 0b00; 5210 } 5211 5212 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5213 let Inst{23-22} = 0b01; 5214 } 5215 } // Uses = [NZCV] 5216} 5217 5218//--- 5219// Floating move immediate 5220//--- 5221 5222class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5223 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5224 [(set regtype:$Rd, fpimmtype:$imm)]>, 5225 Sched<[WriteFImm]> { 5226 bits<5> Rd; 5227 bits<8> imm; 5228 let Inst{31-24} = 0b00011110; 5229 let Inst{21} = 1; 5230 let Inst{20-13} = imm; 5231 let Inst{12-5} = 0b10000000; 5232 let Inst{4-0} = Rd; 5233} 5234 5235multiclass FPMoveImmediate<string asm> { 5236 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5237 let Inst{23-22} = 0b11; 5238 let Predicates = [HasFullFP16]; 5239 } 5240 5241 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5242 let Inst{23-22} = 0b00; 5243 } 5244 5245 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5246 let Inst{23-22} = 0b01; 5247 } 5248} 5249} // end of 'let Predicates = [HasFPARMv8]' 5250 5251//---------------------------------------------------------------------------- 5252// AdvSIMD 5253//---------------------------------------------------------------------------- 5254 5255let Predicates = [HasNEON] in { 5256 5257//---------------------------------------------------------------------------- 5258// AdvSIMD three register vector instructions 5259//---------------------------------------------------------------------------- 5260 5261let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5262class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5263 RegisterOperand regtype, string asm, string kind, 5264 list<dag> pattern> 5265 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5266 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5267 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5268 Sched<[WriteV]> { 5269 bits<5> Rd; 5270 bits<5> Rn; 5271 bits<5> Rm; 5272 let Inst{31} = 0; 5273 let Inst{30} = Q; 5274 let Inst{29} = U; 5275 let Inst{28-24} = 0b01110; 5276 let Inst{23-21} = size; 5277 let Inst{20-16} = Rm; 5278 let Inst{15-11} = opcode; 5279 let Inst{10} = 1; 5280 let Inst{9-5} = Rn; 5281 let Inst{4-0} = Rd; 5282} 5283 5284let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5285class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5286 RegisterOperand regtype, string asm, string kind, 5287 list<dag> pattern> 5288 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5289 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5290 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5291 Sched<[WriteV]> { 5292 bits<5> Rd; 5293 bits<5> Rn; 5294 bits<5> Rm; 5295 let Inst{31} = 0; 5296 let Inst{30} = Q; 5297 let Inst{29} = U; 5298 let Inst{28-24} = 0b01110; 5299 let Inst{23-21} = size; 5300 let Inst{20-16} = Rm; 5301 let Inst{15-11} = opcode; 5302 let Inst{10} = 1; 5303 let Inst{9-5} = Rn; 5304 let Inst{4-0} = Rd; 5305} 5306 5307let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5308class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5309 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5310 Sched<[WriteV]>; 5311 5312multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5313 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5314 [(set (v8i8 V64:$dst), 5315 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5316 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5317 [(set (v16i8 V128:$dst), 5318 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5319 (v16i8 V128:$Rm)))]>; 5320 5321 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5322 (v4i16 V64:$RHS))), 5323 (!cast<Instruction>(NAME#"v8i8") 5324 V64:$LHS, V64:$MHS, V64:$RHS)>; 5325 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5326 (v2i32 V64:$RHS))), 5327 (!cast<Instruction>(NAME#"v8i8") 5328 V64:$LHS, V64:$MHS, V64:$RHS)>; 5329 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5330 (v1i64 V64:$RHS))), 5331 (!cast<Instruction>(NAME#"v8i8") 5332 V64:$LHS, V64:$MHS, V64:$RHS)>; 5333 5334 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5335 (v8i16 V128:$RHS))), 5336 (!cast<Instruction>(NAME#"v16i8") 5337 V128:$LHS, V128:$MHS, V128:$RHS)>; 5338 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5339 (v4i32 V128:$RHS))), 5340 (!cast<Instruction>(NAME#"v16i8") 5341 V128:$LHS, V128:$MHS, V128:$RHS)>; 5342 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5343 (v2i64 V128:$RHS))), 5344 (!cast<Instruction>(NAME#"v16i8") 5345 V128:$LHS, V128:$MHS, V128:$RHS)>; 5346} 5347 5348// All operand sizes distinguished in the encoding. 5349multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5350 SDPatternOperator OpNode> { 5351 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5352 asm, ".8b", 5353 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5354 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5355 asm, ".16b", 5356 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5357 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5358 asm, ".4h", 5359 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5360 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5361 asm, ".8h", 5362 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5363 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5364 asm, ".2s", 5365 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5366 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5367 asm, ".4s", 5368 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5369 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5370 asm, ".2d", 5371 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5372} 5373 5374multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5375 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5376 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5377 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5378 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5379 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5380 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5381 5382 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5383 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5384 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5385 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5386 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5387 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5388 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5389 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5390} 5391 5392// As above, but D sized elements unsupported. 5393multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5394 SDPatternOperator OpNode> { 5395 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5396 asm, ".8b", 5397 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5398 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5399 asm, ".16b", 5400 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5401 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5402 asm, ".4h", 5403 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5404 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5405 asm, ".8h", 5406 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5407 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5408 asm, ".2s", 5409 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5410 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5411 asm, ".4s", 5412 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5413} 5414 5415multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5416 SDPatternOperator OpNode> { 5417 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5418 asm, ".8b", 5419 [(set (v8i8 V64:$dst), 5420 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5421 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5422 asm, ".16b", 5423 [(set (v16i8 V128:$dst), 5424 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5425 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5426 asm, ".4h", 5427 [(set (v4i16 V64:$dst), 5428 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5429 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5430 asm, ".8h", 5431 [(set (v8i16 V128:$dst), 5432 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5433 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5434 asm, ".2s", 5435 [(set (v2i32 V64:$dst), 5436 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5437 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5438 asm, ".4s", 5439 [(set (v4i32 V128:$dst), 5440 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5441} 5442 5443// As above, but only B sized elements supported. 5444multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5445 SDPatternOperator OpNode> { 5446 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5447 asm, ".8b", 5448 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5449 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5450 asm, ".16b", 5451 [(set (v16i8 V128:$Rd), 5452 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5453} 5454 5455// As above, but only floating point elements supported. 5456multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5457 string asm, SDPatternOperator OpNode> { 5458 let Predicates = [HasNEON, HasFullFP16] in { 5459 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5460 asm, ".4h", 5461 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5462 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5463 asm, ".8h", 5464 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5465 } // Predicates = [HasNEON, HasFullFP16] 5466 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5467 asm, ".2s", 5468 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5469 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5470 asm, ".4s", 5471 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5472 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5473 asm, ".2d", 5474 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5475} 5476 5477multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5478 string asm, 5479 SDPatternOperator OpNode> { 5480 let Predicates = [HasNEON, HasFullFP16] in { 5481 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5482 asm, ".4h", 5483 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5484 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5485 asm, ".8h", 5486 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5487 } // Predicates = [HasNEON, HasFullFP16] 5488 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5489 asm, ".2s", 5490 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5491 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5492 asm, ".4s", 5493 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5494 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5495 asm, ".2d", 5496 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5497} 5498 5499multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5500 string asm, SDPatternOperator OpNode> { 5501 let Predicates = [HasNEON, HasFullFP16] in { 5502 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5503 asm, ".4h", 5504 [(set (v4f16 V64:$dst), 5505 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5506 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5507 asm, ".8h", 5508 [(set (v8f16 V128:$dst), 5509 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5510 } // Predicates = [HasNEON, HasFullFP16] 5511 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5512 asm, ".2s", 5513 [(set (v2f32 V64:$dst), 5514 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5515 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5516 asm, ".4s", 5517 [(set (v4f32 V128:$dst), 5518 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5519 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5520 asm, ".2d", 5521 [(set (v2f64 V128:$dst), 5522 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5523} 5524 5525// As above, but D and B sized elements unsupported. 5526multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5527 SDPatternOperator OpNode> { 5528 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5529 asm, ".4h", 5530 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5531 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5532 asm, ".8h", 5533 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5534 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5535 asm, ".2s", 5536 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5537 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5538 asm, ".4s", 5539 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5540} 5541 5542// Logical three vector ops share opcode bits, and only use B sized elements. 5543multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5544 SDPatternOperator OpNode = null_frag> { 5545 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5546 asm, ".8b", 5547 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5548 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5549 asm, ".16b", 5550 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5551 5552 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5553 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5554 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5555 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5556 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5557 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5558 5559 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5560 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5561 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5562 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5563 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5564 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5565} 5566 5567multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5568 string asm, SDPatternOperator OpNode = null_frag> { 5569 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5570 asm, ".8b", 5571 [(set (v8i8 V64:$dst), 5572 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5573 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5574 asm, ".16b", 5575 [(set (v16i8 V128:$dst), 5576 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5577 (v16i8 V128:$Rm)))]>; 5578 5579 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5580 (v4i16 V64:$RHS))), 5581 (!cast<Instruction>(NAME#"v8i8") 5582 V64:$LHS, V64:$MHS, V64:$RHS)>; 5583 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5584 (v2i32 V64:$RHS))), 5585 (!cast<Instruction>(NAME#"v8i8") 5586 V64:$LHS, V64:$MHS, V64:$RHS)>; 5587 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5588 (v1i64 V64:$RHS))), 5589 (!cast<Instruction>(NAME#"v8i8") 5590 V64:$LHS, V64:$MHS, V64:$RHS)>; 5591 5592 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5593 (v8i16 V128:$RHS))), 5594 (!cast<Instruction>(NAME#"v16i8") 5595 V128:$LHS, V128:$MHS, V128:$RHS)>; 5596 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5597 (v4i32 V128:$RHS))), 5598 (!cast<Instruction>(NAME#"v16i8") 5599 V128:$LHS, V128:$MHS, V128:$RHS)>; 5600 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5601 (v2i64 V128:$RHS))), 5602 (!cast<Instruction>(NAME#"v16i8") 5603 V128:$LHS, V128:$MHS, V128:$RHS)>; 5604} 5605 5606// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5607// bytes from S-sized elements. 5608class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5609 string kind2, RegisterOperand RegType, 5610 ValueType AccumType, ValueType InputType, 5611 SDPatternOperator OpNode> : 5612 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5613 [(set (AccumType RegType:$dst), 5614 (OpNode (AccumType RegType:$Rd), 5615 (InputType RegType:$Rn), 5616 (InputType RegType:$Rm)))]> { 5617 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5618} 5619 5620multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5621 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5622 v2i32, v8i8, OpNode>; 5623 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5624 v4i32, v16i8, OpNode>; 5625} 5626 5627// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5628// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5629// 8H to 4S, when Q=1). 5630class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5631 string kind2, RegisterOperand RegType, 5632 ValueType AccumType, ValueType InputType, 5633 SDPatternOperator OpNode> : 5634 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5635 [(set (AccumType RegType:$dst), 5636 (OpNode (AccumType RegType:$Rd), 5637 (InputType RegType:$Rn), 5638 (InputType RegType:$Rm)))]> { 5639 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5640 let Inst{13} = b13; 5641} 5642 5643multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5644 SDPatternOperator OpNode> { 5645 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5646 v2f32, v4f16, OpNode>; 5647 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5648 v4f32, v8f16, OpNode>; 5649} 5650 5651 5652//---------------------------------------------------------------------------- 5653// AdvSIMD two register vector instructions. 5654//---------------------------------------------------------------------------- 5655 5656let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5657class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5658 bits<2> size2, RegisterOperand regtype, string asm, 5659 string dstkind, string srckind, list<dag> pattern> 5660 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5661 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5662 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5663 Sched<[WriteV]> { 5664 bits<5> Rd; 5665 bits<5> Rn; 5666 let Inst{31} = 0; 5667 let Inst{30} = Q; 5668 let Inst{29} = U; 5669 let Inst{28-24} = 0b01110; 5670 let Inst{23-22} = size; 5671 let Inst{21} = 0b1; 5672 let Inst{20-19} = size2; 5673 let Inst{18-17} = 0b00; 5674 let Inst{16-12} = opcode; 5675 let Inst{11-10} = 0b10; 5676 let Inst{9-5} = Rn; 5677 let Inst{4-0} = Rd; 5678} 5679 5680let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5681class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5682 bits<2> size2, RegisterOperand regtype, 5683 string asm, string dstkind, string srckind, 5684 list<dag> pattern> 5685 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5686 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5687 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5688 Sched<[WriteV]> { 5689 bits<5> Rd; 5690 bits<5> Rn; 5691 let Inst{31} = 0; 5692 let Inst{30} = Q; 5693 let Inst{29} = U; 5694 let Inst{28-24} = 0b01110; 5695 let Inst{23-22} = size; 5696 let Inst{21} = 0b1; 5697 let Inst{20-19} = size2; 5698 let Inst{18-17} = 0b00; 5699 let Inst{16-12} = opcode; 5700 let Inst{11-10} = 0b10; 5701 let Inst{9-5} = Rn; 5702 let Inst{4-0} = Rd; 5703} 5704 5705// Supports B, H, and S element sizes. 5706multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5707 SDPatternOperator OpNode> { 5708 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5709 asm, ".8b", ".8b", 5710 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5711 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5712 asm, ".16b", ".16b", 5713 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5714 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5715 asm, ".4h", ".4h", 5716 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5717 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5718 asm, ".8h", ".8h", 5719 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5720 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5721 asm, ".2s", ".2s", 5722 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5723 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5724 asm, ".4s", ".4s", 5725 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5726} 5727 5728class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5729 RegisterOperand regtype, string asm, string dstkind, 5730 string srckind, string amount> 5731 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5732 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5733 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5734 Sched<[WriteV]> { 5735 bits<5> Rd; 5736 bits<5> Rn; 5737 let Inst{31} = 0; 5738 let Inst{30} = Q; 5739 let Inst{29-24} = 0b101110; 5740 let Inst{23-22} = size; 5741 let Inst{21-10} = 0b100001001110; 5742 let Inst{9-5} = Rn; 5743 let Inst{4-0} = Rd; 5744} 5745 5746multiclass SIMDVectorLShiftLongBySizeBHS { 5747 let hasSideEffects = 0 in { 5748 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5749 "shll", ".8h", ".8b", "8">; 5750 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5751 "shll2", ".8h", ".16b", "8">; 5752 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5753 "shll", ".4s", ".4h", "16">; 5754 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5755 "shll2", ".4s", ".8h", "16">; 5756 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5757 "shll", ".2d", ".2s", "32">; 5758 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5759 "shll2", ".2d", ".4s", "32">; 5760 } 5761} 5762 5763// Supports all element sizes. 5764multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5765 SDPatternOperator OpNode> { 5766 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5767 asm, ".4h", ".8b", 5768 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5769 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5770 asm, ".8h", ".16b", 5771 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5772 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5773 asm, ".2s", ".4h", 5774 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5775 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5776 asm, ".4s", ".8h", 5777 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5778 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5779 asm, ".1d", ".2s", 5780 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5781 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5782 asm, ".2d", ".4s", 5783 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5784} 5785 5786multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5787 SDPatternOperator OpNode> { 5788 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5789 asm, ".4h", ".8b", 5790 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5791 (v8i8 V64:$Rn)))]>; 5792 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5793 asm, ".8h", ".16b", 5794 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5795 (v16i8 V128:$Rn)))]>; 5796 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5797 asm, ".2s", ".4h", 5798 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5799 (v4i16 V64:$Rn)))]>; 5800 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5801 asm, ".4s", ".8h", 5802 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5803 (v8i16 V128:$Rn)))]>; 5804 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5805 asm, ".1d", ".2s", 5806 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5807 (v2i32 V64:$Rn)))]>; 5808 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5809 asm, ".2d", ".4s", 5810 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5811 (v4i32 V128:$Rn)))]>; 5812} 5813 5814// Supports all element sizes, except 1xD. 5815multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5816 SDPatternOperator OpNode> { 5817 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5818 asm, ".8b", ".8b", 5819 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5820 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5821 asm, ".16b", ".16b", 5822 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5823 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5824 asm, ".4h", ".4h", 5825 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5826 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5827 asm, ".8h", ".8h", 5828 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5829 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5830 asm, ".2s", ".2s", 5831 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5832 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5833 asm, ".4s", ".4s", 5834 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5835 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5836 asm, ".2d", ".2d", 5837 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5838} 5839 5840multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5841 SDPatternOperator OpNode = null_frag> { 5842 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5843 asm, ".8b", ".8b", 5844 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5845 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5846 asm, ".16b", ".16b", 5847 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5848 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5849 asm, ".4h", ".4h", 5850 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5851 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5852 asm, ".8h", ".8h", 5853 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5854 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5855 asm, ".2s", ".2s", 5856 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5857 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5858 asm, ".4s", ".4s", 5859 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5860 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5861 asm, ".2d", ".2d", 5862 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5863} 5864 5865 5866// Supports only B element sizes. 5867multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5868 SDPatternOperator OpNode> { 5869 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5870 asm, ".8b", ".8b", 5871 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5872 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5873 asm, ".16b", ".16b", 5874 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5875 5876} 5877 5878// Supports only B and H element sizes. 5879multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5880 SDPatternOperator OpNode> { 5881 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5882 asm, ".8b", ".8b", 5883 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5884 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5885 asm, ".16b", ".16b", 5886 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5887 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5888 asm, ".4h", ".4h", 5889 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5890 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5891 asm, ".8h", ".8h", 5892 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5893} 5894 5895// Supports H, S and D element sizes, uses high bit of the size field 5896// as an extra opcode bit. 5897multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5898 SDPatternOperator OpNode> { 5899 let Predicates = [HasNEON, HasFullFP16] in { 5900 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5901 asm, ".4h", ".4h", 5902 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5903 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5904 asm, ".8h", ".8h", 5905 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5906 } // Predicates = [HasNEON, HasFullFP16] 5907 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5908 asm, ".2s", ".2s", 5909 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5910 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5911 asm, ".4s", ".4s", 5912 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5913 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5914 asm, ".2d", ".2d", 5915 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5916} 5917 5918// Supports only S and D element sizes 5919multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5920 SDPatternOperator OpNode = null_frag> { 5921 5922 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5923 asm, ".2s", ".2s", 5924 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5925 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5926 asm, ".4s", ".4s", 5927 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5928 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5929 asm, ".2d", ".2d", 5930 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5931} 5932 5933multiclass FRIntNNTVector<bit U, bit op, string asm, 5934 SDPatternOperator OpNode = null_frag> : 5935 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5936 5937// Supports only S element size. 5938multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5939 SDPatternOperator OpNode> { 5940 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5941 asm, ".2s", ".2s", 5942 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5943 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5944 asm, ".4s", ".4s", 5945 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5946} 5947 5948 5949multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5950 SDPatternOperator OpNode> { 5951 let Predicates = [HasNEON, HasFullFP16] in { 5952 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5953 asm, ".4h", ".4h", 5954 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5955 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5956 asm, ".8h", ".8h", 5957 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5958 } // Predicates = [HasNEON, HasFullFP16] 5959 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5960 asm, ".2s", ".2s", 5961 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5962 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5963 asm, ".4s", ".4s", 5964 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5965 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5966 asm, ".2d", ".2d", 5967 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5968} 5969 5970multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 5971 SDPatternOperator OpNode> { 5972 let Predicates = [HasNEON, HasFullFP16] in { 5973 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5974 asm, ".4h", ".4h", 5975 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5976 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5977 asm, ".8h", ".8h", 5978 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5979 } // Predicates = [HasNEON, HasFullFP16] 5980 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5981 asm, ".2s", ".2s", 5982 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5983 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5984 asm, ".4s", ".4s", 5985 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5986 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5987 asm, ".2d", ".2d", 5988 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5989} 5990 5991 5992class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5993 RegisterOperand inreg, RegisterOperand outreg, 5994 string asm, string outkind, string inkind, 5995 list<dag> pattern> 5996 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 5997 "{\t$Rd" # outkind # ", $Rn" # inkind # 5998 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 5999 Sched<[WriteV]> { 6000 bits<5> Rd; 6001 bits<5> Rn; 6002 let Inst{31} = 0; 6003 let Inst{30} = Q; 6004 let Inst{29} = U; 6005 let Inst{28-24} = 0b01110; 6006 let Inst{23-22} = size; 6007 let Inst{21-17} = 0b10000; 6008 let Inst{16-12} = opcode; 6009 let Inst{11-10} = 0b10; 6010 let Inst{9-5} = Rn; 6011 let Inst{4-0} = Rd; 6012} 6013 6014class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6015 RegisterOperand inreg, RegisterOperand outreg, 6016 string asm, string outkind, string inkind, 6017 list<dag> pattern> 6018 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6019 "{\t$Rd" # outkind # ", $Rn" # inkind # 6020 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6021 Sched<[WriteV]> { 6022 bits<5> Rd; 6023 bits<5> Rn; 6024 let Inst{31} = 0; 6025 let Inst{30} = Q; 6026 let Inst{29} = U; 6027 let Inst{28-24} = 0b01110; 6028 let Inst{23-22} = size; 6029 let Inst{21-17} = 0b10000; 6030 let Inst{16-12} = opcode; 6031 let Inst{11-10} = 0b10; 6032 let Inst{9-5} = Rn; 6033 let Inst{4-0} = Rd; 6034} 6035 6036multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6037 SDPatternOperator OpNode> { 6038 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6039 asm, ".8b", ".8h", 6040 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6041 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6042 asm#"2", ".16b", ".8h", []>; 6043 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6044 asm, ".4h", ".4s", 6045 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6046 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6047 asm#"2", ".8h", ".4s", []>; 6048 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6049 asm, ".2s", ".2d", 6050 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6051 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6052 asm#"2", ".4s", ".2d", []>; 6053 6054 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6055 (!cast<Instruction>(NAME # "v16i8") 6056 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6057 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6058 (!cast<Instruction>(NAME # "v8i16") 6059 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6060 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6061 (!cast<Instruction>(NAME # "v4i32") 6062 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6063} 6064 6065class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6066 bits<5> opcode, RegisterOperand regtype, string asm, 6067 string kind, string zero, ValueType dty, 6068 ValueType sty, SDNode OpNode> 6069 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6070 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6071 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6072 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6073 Sched<[WriteV]> { 6074 bits<5> Rd; 6075 bits<5> Rn; 6076 let Inst{31} = 0; 6077 let Inst{30} = Q; 6078 let Inst{29} = U; 6079 let Inst{28-24} = 0b01110; 6080 let Inst{23-22} = size; 6081 let Inst{21} = 0b1; 6082 let Inst{20-19} = size2; 6083 let Inst{18-17} = 0b00; 6084 let Inst{16-12} = opcode; 6085 let Inst{11-10} = 0b10; 6086 let Inst{9-5} = Rn; 6087 let Inst{4-0} = Rd; 6088} 6089 6090// Comparisons support all element sizes, except 1xD. 6091multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6092 SDNode OpNode> { 6093 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6094 asm, ".8b", "0", 6095 v8i8, v8i8, OpNode>; 6096 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6097 asm, ".16b", "0", 6098 v16i8, v16i8, OpNode>; 6099 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6100 asm, ".4h", "0", 6101 v4i16, v4i16, OpNode>; 6102 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6103 asm, ".8h", "0", 6104 v8i16, v8i16, OpNode>; 6105 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6106 asm, ".2s", "0", 6107 v2i32, v2i32, OpNode>; 6108 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6109 asm, ".4s", "0", 6110 v4i32, v4i32, OpNode>; 6111 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6112 asm, ".2d", "0", 6113 v2i64, v2i64, OpNode>; 6114} 6115 6116// FP Comparisons support only S and D element sizes (and H for v8.2a). 6117multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6118 string asm, SDNode OpNode> { 6119 6120 let Predicates = [HasNEON, HasFullFP16] in { 6121 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6122 asm, ".4h", "0.0", 6123 v4i16, v4f16, OpNode>; 6124 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6125 asm, ".8h", "0.0", 6126 v8i16, v8f16, OpNode>; 6127 } // Predicates = [HasNEON, HasFullFP16] 6128 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6129 asm, ".2s", "0.0", 6130 v2i32, v2f32, OpNode>; 6131 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6132 asm, ".4s", "0.0", 6133 v4i32, v4f32, OpNode>; 6134 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6135 asm, ".2d", "0.0", 6136 v2i64, v2f64, OpNode>; 6137 6138 let Predicates = [HasNEON, HasFullFP16] in { 6139 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6140 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6141 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6142 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6143 } 6144 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6145 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6146 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6147 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6148 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6149 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6150 let Predicates = [HasNEON, HasFullFP16] in { 6151 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6152 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6153 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6154 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6155 } 6156 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6157 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6158 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6159 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6160 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6161 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6162} 6163 6164let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6165class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6166 RegisterOperand outtype, RegisterOperand intype, 6167 string asm, string VdTy, string VnTy, 6168 list<dag> pattern> 6169 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6170 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6171 Sched<[WriteV]> { 6172 bits<5> Rd; 6173 bits<5> Rn; 6174 let Inst{31} = 0; 6175 let Inst{30} = Q; 6176 let Inst{29} = U; 6177 let Inst{28-24} = 0b01110; 6178 let Inst{23-22} = size; 6179 let Inst{21-17} = 0b10000; 6180 let Inst{16-12} = opcode; 6181 let Inst{11-10} = 0b10; 6182 let Inst{9-5} = Rn; 6183 let Inst{4-0} = Rd; 6184} 6185 6186class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6187 RegisterOperand outtype, RegisterOperand intype, 6188 string asm, string VdTy, string VnTy, 6189 list<dag> pattern> 6190 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6191 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6192 Sched<[WriteV]> { 6193 bits<5> Rd; 6194 bits<5> Rn; 6195 let Inst{31} = 0; 6196 let Inst{30} = Q; 6197 let Inst{29} = U; 6198 let Inst{28-24} = 0b01110; 6199 let Inst{23-22} = size; 6200 let Inst{21-17} = 0b10000; 6201 let Inst{16-12} = opcode; 6202 let Inst{11-10} = 0b10; 6203 let Inst{9-5} = Rn; 6204 let Inst{4-0} = Rd; 6205} 6206 6207multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6208 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6209 asm, ".4s", ".4h", []>; 6210 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6211 asm#"2", ".4s", ".8h", []>; 6212 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6213 asm, ".2d", ".2s", []>; 6214 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6215 asm#"2", ".2d", ".4s", []>; 6216} 6217 6218multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6219 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6220 asm, ".4h", ".4s", []>; 6221 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6222 asm#"2", ".8h", ".4s", []>; 6223 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6224 asm, ".2s", ".2d", []>; 6225 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6226 asm#"2", ".4s", ".2d", []>; 6227} 6228 6229multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6230 Intrinsic OpNode> { 6231 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6232 asm, ".2s", ".2d", 6233 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6234 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6235 asm#"2", ".4s", ".2d", []>; 6236 6237 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6238 (!cast<Instruction>(NAME # "v4f32") 6239 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6240} 6241 6242//---------------------------------------------------------------------------- 6243// AdvSIMD three register different-size vector instructions. 6244//---------------------------------------------------------------------------- 6245 6246let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6247class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6248 RegisterOperand outtype, RegisterOperand intype1, 6249 RegisterOperand intype2, string asm, 6250 string outkind, string inkind1, string inkind2, 6251 list<dag> pattern> 6252 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6253 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6254 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6255 Sched<[WriteV]> { 6256 bits<5> Rd; 6257 bits<5> Rn; 6258 bits<5> Rm; 6259 let Inst{31} = 0; 6260 let Inst{30} = size{0}; 6261 let Inst{29} = U; 6262 let Inst{28-24} = 0b01110; 6263 let Inst{23-22} = size{2-1}; 6264 let Inst{21} = 1; 6265 let Inst{20-16} = Rm; 6266 let Inst{15-12} = opcode; 6267 let Inst{11-10} = 0b00; 6268 let Inst{9-5} = Rn; 6269 let Inst{4-0} = Rd; 6270} 6271 6272let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6273class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6274 RegisterOperand outtype, RegisterOperand intype1, 6275 RegisterOperand intype2, string asm, 6276 string outkind, string inkind1, string inkind2, 6277 list<dag> pattern> 6278 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6279 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6280 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6281 Sched<[WriteV]> { 6282 bits<5> Rd; 6283 bits<5> Rn; 6284 bits<5> Rm; 6285 let Inst{31} = 0; 6286 let Inst{30} = size{0}; 6287 let Inst{29} = U; 6288 let Inst{28-24} = 0b01110; 6289 let Inst{23-22} = size{2-1}; 6290 let Inst{21} = 1; 6291 let Inst{20-16} = Rm; 6292 let Inst{15-12} = opcode; 6293 let Inst{11-10} = 0b00; 6294 let Inst{9-5} = Rn; 6295 let Inst{4-0} = Rd; 6296} 6297 6298// FIXME: TableGen doesn't know how to deal with expanded types that also 6299// change the element count (in this case, placing the results in 6300// the high elements of the result register rather than the low 6301// elements). Until that's fixed, we can't code-gen those. 6302multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6303 Intrinsic IntOp> { 6304 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6305 V64, V128, V128, 6306 asm, ".8b", ".8h", ".8h", 6307 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6308 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6309 V128, V128, V128, 6310 asm#"2", ".16b", ".8h", ".8h", 6311 []>; 6312 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6313 V64, V128, V128, 6314 asm, ".4h", ".4s", ".4s", 6315 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6316 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6317 V128, V128, V128, 6318 asm#"2", ".8h", ".4s", ".4s", 6319 []>; 6320 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6321 V64, V128, V128, 6322 asm, ".2s", ".2d", ".2d", 6323 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6324 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6325 V128, V128, V128, 6326 asm#"2", ".4s", ".2d", ".2d", 6327 []>; 6328 6329 6330 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6331 // a version attached to an instruction. 6332 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6333 (v8i16 V128:$Rm))), 6334 (!cast<Instruction>(NAME # "v8i16_v16i8") 6335 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6336 V128:$Rn, V128:$Rm)>; 6337 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6338 (v4i32 V128:$Rm))), 6339 (!cast<Instruction>(NAME # "v4i32_v8i16") 6340 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6341 V128:$Rn, V128:$Rm)>; 6342 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6343 (v2i64 V128:$Rm))), 6344 (!cast<Instruction>(NAME # "v2i64_v4i32") 6345 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6346 V128:$Rn, V128:$Rm)>; 6347} 6348 6349multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6350 Intrinsic IntOp> { 6351 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6352 V128, V64, V64, 6353 asm, ".8h", ".8b", ".8b", 6354 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6355 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6356 V128, V128, V128, 6357 asm#"2", ".8h", ".16b", ".16b", []>; 6358 let Predicates = [HasAES] in { 6359 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6360 V128, V64, V64, 6361 asm, ".1q", ".1d", ".1d", []>; 6362 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6363 V128, V128, V128, 6364 asm#"2", ".1q", ".2d", ".2d", []>; 6365 } 6366 6367 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6368 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6369 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6370} 6371 6372multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6373 SDPatternOperator OpNode> { 6374 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6375 V128, V64, V64, 6376 asm, ".4s", ".4h", ".4h", 6377 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6378 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6379 V128, V128, V128, 6380 asm#"2", ".4s", ".8h", ".8h", 6381 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6382 (extract_high_v8i16 V128:$Rm)))]>; 6383 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6384 V128, V64, V64, 6385 asm, ".2d", ".2s", ".2s", 6386 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6387 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6388 V128, V128, V128, 6389 asm#"2", ".2d", ".4s", ".4s", 6390 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6391 (extract_high_v4i32 V128:$Rm)))]>; 6392} 6393 6394multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6395 SDPatternOperator OpNode = null_frag> { 6396 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6397 V128, V64, V64, 6398 asm, ".8h", ".8b", ".8b", 6399 [(set (v8i16 V128:$Rd), 6400 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6401 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6402 V128, V128, V128, 6403 asm#"2", ".8h", ".16b", ".16b", 6404 [(set (v8i16 V128:$Rd), 6405 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6406 (extract_high_v16i8 V128:$Rm)))))]>; 6407 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6408 V128, V64, V64, 6409 asm, ".4s", ".4h", ".4h", 6410 [(set (v4i32 V128:$Rd), 6411 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6412 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6413 V128, V128, V128, 6414 asm#"2", ".4s", ".8h", ".8h", 6415 [(set (v4i32 V128:$Rd), 6416 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6417 (extract_high_v8i16 V128:$Rm)))))]>; 6418 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6419 V128, V64, V64, 6420 asm, ".2d", ".2s", ".2s", 6421 [(set (v2i64 V128:$Rd), 6422 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6423 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6424 V128, V128, V128, 6425 asm#"2", ".2d", ".4s", ".4s", 6426 [(set (v2i64 V128:$Rd), 6427 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6428 (extract_high_v4i32 V128:$Rm)))))]>; 6429} 6430 6431multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6432 string asm, 6433 SDPatternOperator OpNode> { 6434 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6435 V128, V64, V64, 6436 asm, ".8h", ".8b", ".8b", 6437 [(set (v8i16 V128:$dst), 6438 (add (v8i16 V128:$Rd), 6439 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6440 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6441 V128, V128, V128, 6442 asm#"2", ".8h", ".16b", ".16b", 6443 [(set (v8i16 V128:$dst), 6444 (add (v8i16 V128:$Rd), 6445 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6446 (extract_high_v16i8 V128:$Rm))))))]>; 6447 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6448 V128, V64, V64, 6449 asm, ".4s", ".4h", ".4h", 6450 [(set (v4i32 V128:$dst), 6451 (add (v4i32 V128:$Rd), 6452 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6453 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6454 V128, V128, V128, 6455 asm#"2", ".4s", ".8h", ".8h", 6456 [(set (v4i32 V128:$dst), 6457 (add (v4i32 V128:$Rd), 6458 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6459 (extract_high_v8i16 V128:$Rm))))))]>; 6460 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6461 V128, V64, V64, 6462 asm, ".2d", ".2s", ".2s", 6463 [(set (v2i64 V128:$dst), 6464 (add (v2i64 V128:$Rd), 6465 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6466 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6467 V128, V128, V128, 6468 asm#"2", ".2d", ".4s", ".4s", 6469 [(set (v2i64 V128:$dst), 6470 (add (v2i64 V128:$Rd), 6471 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6472 (extract_high_v4i32 V128:$Rm))))))]>; 6473} 6474 6475multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6476 SDPatternOperator OpNode = null_frag> { 6477 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6478 V128, V64, V64, 6479 asm, ".8h", ".8b", ".8b", 6480 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6481 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6482 V128, V128, V128, 6483 asm#"2", ".8h", ".16b", ".16b", 6484 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6485 (extract_high_v16i8 V128:$Rm)))]>; 6486 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6487 V128, V64, V64, 6488 asm, ".4s", ".4h", ".4h", 6489 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6490 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6491 V128, V128, V128, 6492 asm#"2", ".4s", ".8h", ".8h", 6493 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6494 (extract_high_v8i16 V128:$Rm)))]>; 6495 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6496 V128, V64, V64, 6497 asm, ".2d", ".2s", ".2s", 6498 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6499 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6500 V128, V128, V128, 6501 asm#"2", ".2d", ".4s", ".4s", 6502 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6503 (extract_high_v4i32 V128:$Rm)))]>; 6504} 6505 6506multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6507 string asm, 6508 SDPatternOperator OpNode> { 6509 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6510 V128, V64, V64, 6511 asm, ".8h", ".8b", ".8b", 6512 [(set (v8i16 V128:$dst), 6513 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6514 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6515 V128, V128, V128, 6516 asm#"2", ".8h", ".16b", ".16b", 6517 [(set (v8i16 V128:$dst), 6518 (OpNode (v8i16 V128:$Rd), 6519 (extract_high_v16i8 V128:$Rn), 6520 (extract_high_v16i8 V128:$Rm)))]>; 6521 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6522 V128, V64, V64, 6523 asm, ".4s", ".4h", ".4h", 6524 [(set (v4i32 V128:$dst), 6525 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6526 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6527 V128, V128, V128, 6528 asm#"2", ".4s", ".8h", ".8h", 6529 [(set (v4i32 V128:$dst), 6530 (OpNode (v4i32 V128:$Rd), 6531 (extract_high_v8i16 V128:$Rn), 6532 (extract_high_v8i16 V128:$Rm)))]>; 6533 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6534 V128, V64, V64, 6535 asm, ".2d", ".2s", ".2s", 6536 [(set (v2i64 V128:$dst), 6537 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6538 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6539 V128, V128, V128, 6540 asm#"2", ".2d", ".4s", ".4s", 6541 [(set (v2i64 V128:$dst), 6542 (OpNode (v2i64 V128:$Rd), 6543 (extract_high_v4i32 V128:$Rn), 6544 (extract_high_v4i32 V128:$Rm)))]>; 6545} 6546 6547multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6548 SDPatternOperator Accum> { 6549 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6550 V128, V64, V64, 6551 asm, ".4s", ".4h", ".4h", 6552 [(set (v4i32 V128:$dst), 6553 (Accum (v4i32 V128:$Rd), 6554 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6555 (v4i16 V64:$Rm)))))]>; 6556 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6557 V128, V128, V128, 6558 asm#"2", ".4s", ".8h", ".8h", 6559 [(set (v4i32 V128:$dst), 6560 (Accum (v4i32 V128:$Rd), 6561 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6562 (extract_high_v8i16 V128:$Rm)))))]>; 6563 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6564 V128, V64, V64, 6565 asm, ".2d", ".2s", ".2s", 6566 [(set (v2i64 V128:$dst), 6567 (Accum (v2i64 V128:$Rd), 6568 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6569 (v2i32 V64:$Rm)))))]>; 6570 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6571 V128, V128, V128, 6572 asm#"2", ".2d", ".4s", ".4s", 6573 [(set (v2i64 V128:$dst), 6574 (Accum (v2i64 V128:$Rd), 6575 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6576 (extract_high_v4i32 V128:$Rm)))))]>; 6577} 6578 6579multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6580 SDPatternOperator OpNode> { 6581 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6582 V128, V128, V64, 6583 asm, ".8h", ".8h", ".8b", 6584 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6585 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6586 V128, V128, V128, 6587 asm#"2", ".8h", ".8h", ".16b", 6588 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6589 (extract_high_v16i8 V128:$Rm)))]>; 6590 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6591 V128, V128, V64, 6592 asm, ".4s", ".4s", ".4h", 6593 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6594 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6595 V128, V128, V128, 6596 asm#"2", ".4s", ".4s", ".8h", 6597 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6598 (extract_high_v8i16 V128:$Rm)))]>; 6599 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6600 V128, V128, V64, 6601 asm, ".2d", ".2d", ".2s", 6602 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6603 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6604 V128, V128, V128, 6605 asm#"2", ".2d", ".2d", ".4s", 6606 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6607 (extract_high_v4i32 V128:$Rm)))]>; 6608} 6609 6610//---------------------------------------------------------------------------- 6611// AdvSIMD bitwise extract from vector 6612//---------------------------------------------------------------------------- 6613 6614class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6615 string asm, string kind> 6616 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6617 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6618 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6619 [(set (vty regtype:$Rd), 6620 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6621 Sched<[WriteV]> { 6622 bits<5> Rd; 6623 bits<5> Rn; 6624 bits<5> Rm; 6625 bits<4> imm; 6626 let Inst{31} = 0; 6627 let Inst{30} = size; 6628 let Inst{29-21} = 0b101110000; 6629 let Inst{20-16} = Rm; 6630 let Inst{15} = 0; 6631 let Inst{14-11} = imm; 6632 let Inst{10} = 0; 6633 let Inst{9-5} = Rn; 6634 let Inst{4-0} = Rd; 6635} 6636 6637 6638multiclass SIMDBitwiseExtract<string asm> { 6639 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6640 let imm{3} = 0; 6641 } 6642 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6643} 6644 6645//---------------------------------------------------------------------------- 6646// AdvSIMD zip vector 6647//---------------------------------------------------------------------------- 6648 6649class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6650 string asm, string kind, SDNode OpNode, ValueType valty> 6651 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6652 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6653 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6654 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6655 Sched<[WriteV]> { 6656 bits<5> Rd; 6657 bits<5> Rn; 6658 bits<5> Rm; 6659 let Inst{31} = 0; 6660 let Inst{30} = size{0}; 6661 let Inst{29-24} = 0b001110; 6662 let Inst{23-22} = size{2-1}; 6663 let Inst{21} = 0; 6664 let Inst{20-16} = Rm; 6665 let Inst{15} = 0; 6666 let Inst{14-12} = opc; 6667 let Inst{11-10} = 0b10; 6668 let Inst{9-5} = Rn; 6669 let Inst{4-0} = Rd; 6670} 6671 6672multiclass SIMDZipVector<bits<3>opc, string asm, 6673 SDNode OpNode> { 6674 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6675 asm, ".8b", OpNode, v8i8>; 6676 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6677 asm, ".16b", OpNode, v16i8>; 6678 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6679 asm, ".4h", OpNode, v4i16>; 6680 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6681 asm, ".8h", OpNode, v8i16>; 6682 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6683 asm, ".2s", OpNode, v2i32>; 6684 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6685 asm, ".4s", OpNode, v4i32>; 6686 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6687 asm, ".2d", OpNode, v2i64>; 6688 6689 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6690 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6691 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6692 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6693 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6694 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6695 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6696 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6697 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6698 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6699} 6700 6701//---------------------------------------------------------------------------- 6702// AdvSIMD three register scalar instructions 6703//---------------------------------------------------------------------------- 6704 6705let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6706class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6707 RegisterClass regtype, string asm, 6708 list<dag> pattern> 6709 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6710 "\t$Rd, $Rn, $Rm", "", pattern>, 6711 Sched<[WriteV]> { 6712 bits<5> Rd; 6713 bits<5> Rn; 6714 bits<5> Rm; 6715 let Inst{31-30} = 0b01; 6716 let Inst{29} = U; 6717 let Inst{28-24} = 0b11110; 6718 let Inst{23-21} = size; 6719 let Inst{20-16} = Rm; 6720 let Inst{15-11} = opcode; 6721 let Inst{10} = 1; 6722 let Inst{9-5} = Rn; 6723 let Inst{4-0} = Rd; 6724} 6725 6726let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6727class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6728 dag oops, dag iops, string asm, 6729 list<dag> pattern> 6730 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6731 Sched<[WriteV]> { 6732 bits<5> Rd; 6733 bits<5> Rn; 6734 bits<5> Rm; 6735 let Inst{31-30} = 0b01; 6736 let Inst{29} = U; 6737 let Inst{28-24} = 0b11110; 6738 let Inst{23-22} = size; 6739 let Inst{21} = R; 6740 let Inst{20-16} = Rm; 6741 let Inst{15-11} = opcode; 6742 let Inst{10} = 1; 6743 let Inst{9-5} = Rn; 6744 let Inst{4-0} = Rd; 6745} 6746 6747multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6748 SDPatternOperator OpNode> { 6749 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6750 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6751} 6752 6753multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6754 SDPatternOperator OpNode> { 6755 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6756 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6757 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6758 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6759 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6760 6761 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6762 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6763 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6764 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6765} 6766 6767multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6768 SDPatternOperator OpNode> { 6769 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6770 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6771 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6772} 6773 6774multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6775 SDPatternOperator OpNode = null_frag> { 6776 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6777 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6778 asm, []>; 6779 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6780 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6781 asm, []>; 6782} 6783 6784multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6785 SDPatternOperator OpNode = null_frag> { 6786 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6787 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6788 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6789 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6790 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6791 let Predicates = [HasNEON, HasFullFP16] in { 6792 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6793 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6794 } // Predicates = [HasNEON, HasFullFP16] 6795 } 6796 6797 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6798 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6799} 6800 6801multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6802 SDPatternOperator OpNode = null_frag> { 6803 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6804 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6805 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6806 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6807 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6808 let Predicates = [HasNEON, HasFullFP16] in { 6809 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6810 []>; 6811 } // Predicates = [HasNEON, HasFullFP16] 6812 } 6813 6814 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6815 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6816} 6817 6818class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6819 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6820 : I<oops, iops, asm, 6821 "\t$Rd, $Rn, $Rm", cstr, pat>, 6822 Sched<[WriteV]> { 6823 bits<5> Rd; 6824 bits<5> Rn; 6825 bits<5> Rm; 6826 let Inst{31-30} = 0b01; 6827 let Inst{29} = U; 6828 let Inst{28-24} = 0b11110; 6829 let Inst{23-22} = size; 6830 let Inst{21} = 1; 6831 let Inst{20-16} = Rm; 6832 let Inst{15-11} = opcode; 6833 let Inst{10} = 0; 6834 let Inst{9-5} = Rn; 6835 let Inst{4-0} = Rd; 6836} 6837 6838let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6839multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6840 SDPatternOperator OpNode = null_frag> { 6841 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6842 (outs FPR32:$Rd), 6843 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6844 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6845 (outs FPR64:$Rd), 6846 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6847 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6848} 6849 6850let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6851multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6852 SDPatternOperator OpNode = null_frag> { 6853 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6854 (outs FPR32:$dst), 6855 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6856 asm, "$Rd = $dst", []>; 6857 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6858 (outs FPR64:$dst), 6859 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6860 asm, "$Rd = $dst", 6861 [(set (i64 FPR64:$dst), 6862 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6863} 6864 6865//---------------------------------------------------------------------------- 6866// AdvSIMD two register scalar instructions 6867//---------------------------------------------------------------------------- 6868 6869let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6870class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6871 RegisterClass regtype, RegisterClass regtype2, 6872 string asm, list<dag> pat> 6873 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6874 "\t$Rd, $Rn", "", pat>, 6875 Sched<[WriteV]> { 6876 bits<5> Rd; 6877 bits<5> Rn; 6878 let Inst{31-30} = 0b01; 6879 let Inst{29} = U; 6880 let Inst{28-24} = 0b11110; 6881 let Inst{23-22} = size; 6882 let Inst{21} = 0b1; 6883 let Inst{20-19} = size2; 6884 let Inst{18-17} = 0b00; 6885 let Inst{16-12} = opcode; 6886 let Inst{11-10} = 0b10; 6887 let Inst{9-5} = Rn; 6888 let Inst{4-0} = Rd; 6889} 6890 6891let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6892class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6893 RegisterClass regtype, RegisterClass regtype2, 6894 string asm, list<dag> pat> 6895 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6896 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6897 Sched<[WriteV]> { 6898 bits<5> Rd; 6899 bits<5> Rn; 6900 let Inst{31-30} = 0b01; 6901 let Inst{29} = U; 6902 let Inst{28-24} = 0b11110; 6903 let Inst{23-22} = size; 6904 let Inst{21-17} = 0b10000; 6905 let Inst{16-12} = opcode; 6906 let Inst{11-10} = 0b10; 6907 let Inst{9-5} = Rn; 6908 let Inst{4-0} = Rd; 6909} 6910 6911 6912let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6913class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6914 RegisterClass regtype, string asm, string zero> 6915 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6916 "\t$Rd, $Rn, #" # zero, "", []>, 6917 Sched<[WriteV]> { 6918 bits<5> Rd; 6919 bits<5> Rn; 6920 let Inst{31-30} = 0b01; 6921 let Inst{29} = U; 6922 let Inst{28-24} = 0b11110; 6923 let Inst{23-22} = size; 6924 let Inst{21} = 0b1; 6925 let Inst{20-19} = size2; 6926 let Inst{18-17} = 0b00; 6927 let Inst{16-12} = opcode; 6928 let Inst{11-10} = 0b10; 6929 let Inst{9-5} = Rn; 6930 let Inst{4-0} = Rd; 6931} 6932 6933class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6934 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6935 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6936 Sched<[WriteV]> { 6937 bits<5> Rd; 6938 bits<5> Rn; 6939 let Inst{31-17} = 0b011111100110000; 6940 let Inst{16-12} = opcode; 6941 let Inst{11-10} = 0b10; 6942 let Inst{9-5} = Rn; 6943 let Inst{4-0} = Rd; 6944} 6945 6946multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6947 SDPatternOperator OpNode> { 6948 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6949 6950 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6951 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6952} 6953 6954multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6955 SDPatternOperator OpNode> { 6956 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 6957 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 6958 let Predicates = [HasNEON, HasFullFP16] in { 6959 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 6960 } 6961 6962 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6963 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 6964 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6965 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 6966 let Predicates = [HasNEON, HasFullFP16] in { 6967 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6968 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 6969 } 6970 6971 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 6972 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6973} 6974 6975multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 6976 SDPatternOperator OpNode = null_frag> { 6977 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6978 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 6979 6980 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 6981 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 6982} 6983 6984multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 6985 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 6986 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 6987 let Predicates = [HasNEON, HasFullFP16] in { 6988 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 6989 } 6990} 6991 6992multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 6993 SDPatternOperator OpNode> { 6994 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 6995 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 6996 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 6997 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 6998 let Predicates = [HasNEON, HasFullFP16] in { 6999 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7000 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7001 } 7002} 7003 7004multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7005 SDPatternOperator OpNode = null_frag> { 7006 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7007 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7008 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7009 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7010 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7011 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7012 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7013 } 7014 7015 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7016 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7017} 7018 7019multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7020 Intrinsic OpNode> { 7021 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7022 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7023 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7024 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7025 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7026 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7027 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7028 } 7029 7030 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7031 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7032} 7033 7034 7035 7036let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7037multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7038 SDPatternOperator OpNode = null_frag> { 7039 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7040 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7041 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7042 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7043} 7044 7045//---------------------------------------------------------------------------- 7046// AdvSIMD scalar pairwise instructions 7047//---------------------------------------------------------------------------- 7048 7049let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7050class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7051 RegisterOperand regtype, RegisterOperand vectype, 7052 string asm, string kind> 7053 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7054 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7055 Sched<[WriteV]> { 7056 bits<5> Rd; 7057 bits<5> Rn; 7058 let Inst{31-30} = 0b01; 7059 let Inst{29} = U; 7060 let Inst{28-24} = 0b11110; 7061 let Inst{23-22} = size; 7062 let Inst{21-17} = 0b11000; 7063 let Inst{16-12} = opcode; 7064 let Inst{11-10} = 0b10; 7065 let Inst{9-5} = Rn; 7066 let Inst{4-0} = Rd; 7067} 7068 7069multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7070 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7071 asm, ".2d">; 7072} 7073 7074multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7075 let Predicates = [HasNEON, HasFullFP16] in { 7076 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7077 asm, ".2h">; 7078 } 7079 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7080 asm, ".2s">; 7081 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7082 asm, ".2d">; 7083} 7084 7085//---------------------------------------------------------------------------- 7086// AdvSIMD across lanes instructions 7087//---------------------------------------------------------------------------- 7088 7089let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7090class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7091 RegisterClass regtype, RegisterOperand vectype, 7092 string asm, string kind, list<dag> pattern> 7093 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7094 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7095 Sched<[WriteV]> { 7096 bits<5> Rd; 7097 bits<5> Rn; 7098 let Inst{31} = 0; 7099 let Inst{30} = Q; 7100 let Inst{29} = U; 7101 let Inst{28-24} = 0b01110; 7102 let Inst{23-22} = size; 7103 let Inst{21-17} = 0b11000; 7104 let Inst{16-12} = opcode; 7105 let Inst{11-10} = 0b10; 7106 let Inst{9-5} = Rn; 7107 let Inst{4-0} = Rd; 7108} 7109 7110multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7111 string asm> { 7112 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7113 asm, ".8b", []>; 7114 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7115 asm, ".16b", []>; 7116 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7117 asm, ".4h", []>; 7118 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7119 asm, ".8h", []>; 7120 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7121 asm, ".4s", []>; 7122} 7123 7124multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7125 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7126 asm, ".8b", []>; 7127 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7128 asm, ".16b", []>; 7129 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7130 asm, ".4h", []>; 7131 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7132 asm, ".8h", []>; 7133 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7134 asm, ".4s", []>; 7135} 7136 7137multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7138 Intrinsic intOp> { 7139 let Predicates = [HasNEON, HasFullFP16] in { 7140 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7141 asm, ".4h", 7142 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7143 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7144 asm, ".8h", 7145 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7146 } // Predicates = [HasNEON, HasFullFP16] 7147 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7148 asm, ".4s", 7149 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7150} 7151 7152//---------------------------------------------------------------------------- 7153// AdvSIMD INS/DUP instructions 7154//---------------------------------------------------------------------------- 7155 7156// FIXME: There has got to be a better way to factor these. ugh. 7157 7158class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7159 string operands, string constraints, list<dag> pattern> 7160 : I<outs, ins, asm, operands, constraints, pattern>, 7161 Sched<[WriteV]> { 7162 bits<5> Rd; 7163 bits<5> Rn; 7164 let Inst{31} = 0; 7165 let Inst{30} = Q; 7166 let Inst{29} = op; 7167 let Inst{28-21} = 0b01110000; 7168 let Inst{15} = 0; 7169 let Inst{10} = 1; 7170 let Inst{9-5} = Rn; 7171 let Inst{4-0} = Rd; 7172} 7173 7174class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7175 RegisterOperand vecreg, RegisterClass regtype> 7176 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7177 "{\t$Rd" # size # ", $Rn" # 7178 "|" # size # "\t$Rd, $Rn}", "", 7179 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7180 let Inst{20-16} = imm5; 7181 let Inst{14-11} = 0b0001; 7182} 7183 7184class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7185 ValueType vectype, ValueType insreg, 7186 RegisterOperand vecreg, Operand idxtype, 7187 ValueType elttype, SDNode OpNode> 7188 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7189 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7190 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7191 [(set (vectype vecreg:$Rd), 7192 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7193 let Inst{14-11} = 0b0000; 7194} 7195 7196class SIMDDup64FromElement 7197 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7198 VectorIndexD, i64, AArch64duplane64> { 7199 bits<1> idx; 7200 let Inst{20} = idx; 7201 let Inst{19-16} = 0b1000; 7202} 7203 7204class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7205 RegisterOperand vecreg> 7206 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7207 VectorIndexS, i64, AArch64duplane32> { 7208 bits<2> idx; 7209 let Inst{20-19} = idx; 7210 let Inst{18-16} = 0b100; 7211} 7212 7213class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7214 RegisterOperand vecreg> 7215 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7216 VectorIndexH, i64, AArch64duplane16> { 7217 bits<3> idx; 7218 let Inst{20-18} = idx; 7219 let Inst{17-16} = 0b10; 7220} 7221 7222class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7223 RegisterOperand vecreg> 7224 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7225 VectorIndexB, i64, AArch64duplane8> { 7226 bits<4> idx; 7227 let Inst{20-17} = idx; 7228 let Inst{16} = 1; 7229} 7230 7231class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7232 Operand idxtype, string asm, list<dag> pattern> 7233 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7234 "{\t$Rd, $Rn" # size # "$idx" # 7235 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7236 let Inst{14-11} = imm4; 7237} 7238 7239class SIMDSMov<bit Q, string size, RegisterClass regtype, 7240 Operand idxtype> 7241 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7242class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7243 Operand idxtype> 7244 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7245 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7246 7247class SIMDMovAlias<string asm, string size, Instruction inst, 7248 RegisterClass regtype, Operand idxtype> 7249 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7250 "|" # size # "\t$dst, $src$idx}", 7251 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7252 7253multiclass SMov { 7254 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7255 bits<4> idx; 7256 let Inst{20-17} = idx; 7257 let Inst{16} = 1; 7258 } 7259 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7260 bits<4> idx; 7261 let Inst{20-17} = idx; 7262 let Inst{16} = 1; 7263 } 7264 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7265 bits<3> idx; 7266 let Inst{20-18} = idx; 7267 let Inst{17-16} = 0b10; 7268 } 7269 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7270 bits<3> idx; 7271 let Inst{20-18} = idx; 7272 let Inst{17-16} = 0b10; 7273 } 7274 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7275 bits<2> idx; 7276 let Inst{20-19} = idx; 7277 let Inst{18-16} = 0b100; 7278 } 7279} 7280 7281multiclass UMov { 7282 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7283 bits<4> idx; 7284 let Inst{20-17} = idx; 7285 let Inst{16} = 1; 7286 } 7287 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7288 bits<3> idx; 7289 let Inst{20-18} = idx; 7290 let Inst{17-16} = 0b10; 7291 } 7292 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7293 bits<2> idx; 7294 let Inst{20-19} = idx; 7295 let Inst{18-16} = 0b100; 7296 } 7297 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7298 bits<1> idx; 7299 let Inst{20} = idx; 7300 let Inst{19-16} = 0b1000; 7301 } 7302 def : SIMDMovAlias<"mov", ".s", 7303 !cast<Instruction>(NAME#"vi32"), 7304 GPR32, VectorIndexS>; 7305 def : SIMDMovAlias<"mov", ".d", 7306 !cast<Instruction>(NAME#"vi64"), 7307 GPR64, VectorIndexD>; 7308} 7309 7310class SIMDInsFromMain<string size, ValueType vectype, 7311 RegisterClass regtype, Operand idxtype> 7312 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7313 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7314 "{\t$Rd" # size # "$idx, $Rn" # 7315 "|" # size # "\t$Rd$idx, $Rn}", 7316 "$Rd = $dst", 7317 [(set V128:$dst, 7318 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7319 let Inst{14-11} = 0b0011; 7320} 7321 7322class SIMDInsFromElement<string size, ValueType vectype, 7323 ValueType elttype, Operand idxtype> 7324 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7325 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7326 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7327 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7328 "$Rd = $dst", 7329 [(set V128:$dst, 7330 (vector_insert 7331 (vectype V128:$Rd), 7332 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7333 idxtype:$idx))]>; 7334 7335class SIMDInsMainMovAlias<string size, Instruction inst, 7336 RegisterClass regtype, Operand idxtype> 7337 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7338 "|" # size #"\t$dst$idx, $src}", 7339 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7340class SIMDInsElementMovAlias<string size, Instruction inst, 7341 Operand idxtype> 7342 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7343 # "|" # size #"\t$dst$idx, $src$idx2}", 7344 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7345 7346 7347multiclass SIMDIns { 7348 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7349 bits<4> idx; 7350 let Inst{20-17} = idx; 7351 let Inst{16} = 1; 7352 } 7353 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7354 bits<3> idx; 7355 let Inst{20-18} = idx; 7356 let Inst{17-16} = 0b10; 7357 } 7358 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7359 bits<2> idx; 7360 let Inst{20-19} = idx; 7361 let Inst{18-16} = 0b100; 7362 } 7363 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7364 bits<1> idx; 7365 let Inst{20} = idx; 7366 let Inst{19-16} = 0b1000; 7367 } 7368 7369 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7370 bits<4> idx; 7371 bits<4> idx2; 7372 let Inst{20-17} = idx; 7373 let Inst{16} = 1; 7374 let Inst{14-11} = idx2; 7375 } 7376 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7377 bits<3> idx; 7378 bits<3> idx2; 7379 let Inst{20-18} = idx; 7380 let Inst{17-16} = 0b10; 7381 let Inst{14-12} = idx2; 7382 let Inst{11} = {?}; 7383 } 7384 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7385 bits<2> idx; 7386 bits<2> idx2; 7387 let Inst{20-19} = idx; 7388 let Inst{18-16} = 0b100; 7389 let Inst{14-13} = idx2; 7390 let Inst{12-11} = {?,?}; 7391 } 7392 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7393 bits<1> idx; 7394 bits<1> idx2; 7395 let Inst{20} = idx; 7396 let Inst{19-16} = 0b1000; 7397 let Inst{14} = idx2; 7398 let Inst{13-11} = {?,?,?}; 7399 } 7400 7401 // For all forms of the INS instruction, the "mov" mnemonic is the 7402 // preferred alias. Why they didn't just call the instruction "mov" in 7403 // the first place is a very good question indeed... 7404 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7405 GPR32, VectorIndexB>; 7406 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7407 GPR32, VectorIndexH>; 7408 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7409 GPR32, VectorIndexS>; 7410 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7411 GPR64, VectorIndexD>; 7412 7413 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7414 VectorIndexB>; 7415 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7416 VectorIndexH>; 7417 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7418 VectorIndexS>; 7419 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7420 VectorIndexD>; 7421} 7422 7423//---------------------------------------------------------------------------- 7424// AdvSIMD TBL/TBX 7425//---------------------------------------------------------------------------- 7426 7427let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7428class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7429 RegisterOperand listtype, string asm, string kind> 7430 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7431 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7432 Sched<[WriteV]> { 7433 bits<5> Vd; 7434 bits<5> Vn; 7435 bits<5> Vm; 7436 let Inst{31} = 0; 7437 let Inst{30} = Q; 7438 let Inst{29-21} = 0b001110000; 7439 let Inst{20-16} = Vm; 7440 let Inst{15} = 0; 7441 let Inst{14-13} = len; 7442 let Inst{12} = op; 7443 let Inst{11-10} = 0b00; 7444 let Inst{9-5} = Vn; 7445 let Inst{4-0} = Vd; 7446} 7447 7448let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7449class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7450 RegisterOperand listtype, string asm, string kind> 7451 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7452 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7453 Sched<[WriteV]> { 7454 bits<5> Vd; 7455 bits<5> Vn; 7456 bits<5> Vm; 7457 let Inst{31} = 0; 7458 let Inst{30} = Q; 7459 let Inst{29-21} = 0b001110000; 7460 let Inst{20-16} = Vm; 7461 let Inst{15} = 0; 7462 let Inst{14-13} = len; 7463 let Inst{12} = op; 7464 let Inst{11-10} = 0b00; 7465 let Inst{9-5} = Vn; 7466 let Inst{4-0} = Vd; 7467} 7468 7469class SIMDTableLookupAlias<string asm, Instruction inst, 7470 RegisterOperand vectype, RegisterOperand listtype> 7471 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7472 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7473 7474multiclass SIMDTableLookup<bit op, string asm> { 7475 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7476 asm, ".8b">; 7477 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7478 asm, ".8b">; 7479 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7480 asm, ".8b">; 7481 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7482 asm, ".8b">; 7483 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7484 asm, ".16b">; 7485 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7486 asm, ".16b">; 7487 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7488 asm, ".16b">; 7489 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7490 asm, ".16b">; 7491 7492 def : SIMDTableLookupAlias<asm # ".8b", 7493 !cast<Instruction>(NAME#"v8i8One"), 7494 V64, VecListOne128>; 7495 def : SIMDTableLookupAlias<asm # ".8b", 7496 !cast<Instruction>(NAME#"v8i8Two"), 7497 V64, VecListTwo128>; 7498 def : SIMDTableLookupAlias<asm # ".8b", 7499 !cast<Instruction>(NAME#"v8i8Three"), 7500 V64, VecListThree128>; 7501 def : SIMDTableLookupAlias<asm # ".8b", 7502 !cast<Instruction>(NAME#"v8i8Four"), 7503 V64, VecListFour128>; 7504 def : SIMDTableLookupAlias<asm # ".16b", 7505 !cast<Instruction>(NAME#"v16i8One"), 7506 V128, VecListOne128>; 7507 def : SIMDTableLookupAlias<asm # ".16b", 7508 !cast<Instruction>(NAME#"v16i8Two"), 7509 V128, VecListTwo128>; 7510 def : SIMDTableLookupAlias<asm # ".16b", 7511 !cast<Instruction>(NAME#"v16i8Three"), 7512 V128, VecListThree128>; 7513 def : SIMDTableLookupAlias<asm # ".16b", 7514 !cast<Instruction>(NAME#"v16i8Four"), 7515 V128, VecListFour128>; 7516} 7517 7518multiclass SIMDTableLookupTied<bit op, string asm> { 7519 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7520 asm, ".8b">; 7521 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7522 asm, ".8b">; 7523 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7524 asm, ".8b">; 7525 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7526 asm, ".8b">; 7527 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7528 asm, ".16b">; 7529 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7530 asm, ".16b">; 7531 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7532 asm, ".16b">; 7533 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7534 asm, ".16b">; 7535 7536 def : SIMDTableLookupAlias<asm # ".8b", 7537 !cast<Instruction>(NAME#"v8i8One"), 7538 V64, VecListOne128>; 7539 def : SIMDTableLookupAlias<asm # ".8b", 7540 !cast<Instruction>(NAME#"v8i8Two"), 7541 V64, VecListTwo128>; 7542 def : SIMDTableLookupAlias<asm # ".8b", 7543 !cast<Instruction>(NAME#"v8i8Three"), 7544 V64, VecListThree128>; 7545 def : SIMDTableLookupAlias<asm # ".8b", 7546 !cast<Instruction>(NAME#"v8i8Four"), 7547 V64, VecListFour128>; 7548 def : SIMDTableLookupAlias<asm # ".16b", 7549 !cast<Instruction>(NAME#"v16i8One"), 7550 V128, VecListOne128>; 7551 def : SIMDTableLookupAlias<asm # ".16b", 7552 !cast<Instruction>(NAME#"v16i8Two"), 7553 V128, VecListTwo128>; 7554 def : SIMDTableLookupAlias<asm # ".16b", 7555 !cast<Instruction>(NAME#"v16i8Three"), 7556 V128, VecListThree128>; 7557 def : SIMDTableLookupAlias<asm # ".16b", 7558 !cast<Instruction>(NAME#"v16i8Four"), 7559 V128, VecListFour128>; 7560} 7561 7562 7563//---------------------------------------------------------------------------- 7564// AdvSIMD scalar CPY 7565//---------------------------------------------------------------------------- 7566let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7567class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7568 string kind, Operand idxtype> 7569 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7570 "{\t$dst, $src" # kind # "$idx" # 7571 "|\t$dst, $src$idx}", "", []>, 7572 Sched<[WriteV]> { 7573 bits<5> dst; 7574 bits<5> src; 7575 let Inst{31-21} = 0b01011110000; 7576 let Inst{15-10} = 0b000001; 7577 let Inst{9-5} = src; 7578 let Inst{4-0} = dst; 7579} 7580 7581class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7582 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7583 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7584 # "|\t$dst, $src$index}", 7585 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7586 7587 7588multiclass SIMDScalarCPY<string asm> { 7589 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7590 bits<4> idx; 7591 let Inst{20-17} = idx; 7592 let Inst{16} = 1; 7593 } 7594 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7595 bits<3> idx; 7596 let Inst{20-18} = idx; 7597 let Inst{17-16} = 0b10; 7598 } 7599 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7600 bits<2> idx; 7601 let Inst{20-19} = idx; 7602 let Inst{18-16} = 0b100; 7603 } 7604 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7605 bits<1> idx; 7606 let Inst{20} = idx; 7607 let Inst{19-16} = 0b1000; 7608 } 7609 7610 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7611 VectorIndexD:$idx)))), 7612 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7613 7614 // 'DUP' mnemonic aliases. 7615 def : SIMDScalarCPYAlias<"dup", ".b", 7616 !cast<Instruction>(NAME#"i8"), 7617 FPR8, V128, VectorIndexB>; 7618 def : SIMDScalarCPYAlias<"dup", ".h", 7619 !cast<Instruction>(NAME#"i16"), 7620 FPR16, V128, VectorIndexH>; 7621 def : SIMDScalarCPYAlias<"dup", ".s", 7622 !cast<Instruction>(NAME#"i32"), 7623 FPR32, V128, VectorIndexS>; 7624 def : SIMDScalarCPYAlias<"dup", ".d", 7625 !cast<Instruction>(NAME#"i64"), 7626 FPR64, V128, VectorIndexD>; 7627} 7628 7629//---------------------------------------------------------------------------- 7630// AdvSIMD modified immediate instructions 7631//---------------------------------------------------------------------------- 7632 7633class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7634 string asm, string op_string, 7635 string cstr, list<dag> pattern> 7636 : I<oops, iops, asm, op_string, cstr, pattern>, 7637 Sched<[WriteV]> { 7638 bits<5> Rd; 7639 bits<8> imm8; 7640 let Inst{31} = 0; 7641 let Inst{30} = Q; 7642 let Inst{29} = op; 7643 let Inst{28-19} = 0b0111100000; 7644 let Inst{18-16} = imm8{7-5}; 7645 let Inst{11} = op2; 7646 let Inst{10} = 1; 7647 let Inst{9-5} = imm8{4-0}; 7648 let Inst{4-0} = Rd; 7649} 7650 7651class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7652 Operand immtype, dag opt_shift_iop, 7653 string opt_shift, string asm, string kind, 7654 list<dag> pattern> 7655 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7656 !con((ins immtype:$imm8), opt_shift_iop), asm, 7657 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7658 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7659 "", pattern> { 7660 let DecoderMethod = "DecodeModImmInstruction"; 7661} 7662 7663class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7664 Operand immtype, dag opt_shift_iop, 7665 string opt_shift, string asm, string kind, 7666 list<dag> pattern> 7667 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7668 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7669 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7670 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7671 "$Rd = $dst", pattern> { 7672 let DecoderMethod = "DecodeModImmTiedInstruction"; 7673} 7674 7675class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7676 RegisterOperand vectype, string asm, 7677 string kind, list<dag> pattern> 7678 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7679 (ins logical_vec_shift:$shift), 7680 "$shift", asm, kind, pattern> { 7681 bits<2> shift; 7682 let Inst{15} = b15_b12{1}; 7683 let Inst{14-13} = shift; 7684 let Inst{12} = b15_b12{0}; 7685} 7686 7687class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7688 RegisterOperand vectype, string asm, 7689 string kind, list<dag> pattern> 7690 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7691 (ins logical_vec_shift:$shift), 7692 "$shift", asm, kind, pattern> { 7693 bits<2> shift; 7694 let Inst{15} = b15_b12{1}; 7695 let Inst{14-13} = shift; 7696 let Inst{12} = b15_b12{0}; 7697} 7698 7699 7700class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7701 RegisterOperand vectype, string asm, 7702 string kind, list<dag> pattern> 7703 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7704 (ins logical_vec_hw_shift:$shift), 7705 "$shift", asm, kind, pattern> { 7706 bits<2> shift; 7707 let Inst{15} = b15_b12{1}; 7708 let Inst{14} = 0; 7709 let Inst{13} = shift{0}; 7710 let Inst{12} = b15_b12{0}; 7711} 7712 7713class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7714 RegisterOperand vectype, string asm, 7715 string kind, list<dag> pattern> 7716 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7717 (ins logical_vec_hw_shift:$shift), 7718 "$shift", asm, kind, pattern> { 7719 bits<2> shift; 7720 let Inst{15} = b15_b12{1}; 7721 let Inst{14} = 0; 7722 let Inst{13} = shift{0}; 7723 let Inst{12} = b15_b12{0}; 7724} 7725 7726multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7727 string asm> { 7728 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7729 asm, ".4h", []>; 7730 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7731 asm, ".8h", []>; 7732 7733 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7734 asm, ".2s", []>; 7735 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7736 asm, ".4s", []>; 7737} 7738 7739multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7740 bits<2> w_cmode, string asm, 7741 SDNode OpNode> { 7742 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7743 asm, ".4h", 7744 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7745 imm0_255:$imm8, 7746 (i32 imm:$shift)))]>; 7747 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7748 asm, ".8h", 7749 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7750 imm0_255:$imm8, 7751 (i32 imm:$shift)))]>; 7752 7753 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7754 asm, ".2s", 7755 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7756 imm0_255:$imm8, 7757 (i32 imm:$shift)))]>; 7758 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7759 asm, ".4s", 7760 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7761 imm0_255:$imm8, 7762 (i32 imm:$shift)))]>; 7763} 7764 7765class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7766 RegisterOperand vectype, string asm, 7767 string kind, list<dag> pattern> 7768 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7769 (ins move_vec_shift:$shift), 7770 "$shift", asm, kind, pattern> { 7771 bits<1> shift; 7772 let Inst{15-13} = cmode{3-1}; 7773 let Inst{12} = shift; 7774} 7775 7776class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7777 RegisterOperand vectype, 7778 Operand imm_type, string asm, 7779 string kind, list<dag> pattern> 7780 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7781 asm, kind, pattern> { 7782 let Inst{15-12} = cmode; 7783} 7784 7785class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7786 list<dag> pattern> 7787 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7788 "\t$Rd, $imm8", "", pattern> { 7789 let Inst{15-12} = cmode; 7790 let DecoderMethod = "DecodeModImmInstruction"; 7791} 7792 7793//---------------------------------------------------------------------------- 7794// AdvSIMD indexed element 7795//---------------------------------------------------------------------------- 7796 7797let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7798class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7799 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7800 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7801 string apple_kind, string dst_kind, string lhs_kind, 7802 string rhs_kind, list<dag> pattern> 7803 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7804 asm, 7805 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7806 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7807 Sched<[WriteV]> { 7808 bits<5> Rd; 7809 bits<5> Rn; 7810 bits<5> Rm; 7811 7812 let Inst{31} = 0; 7813 let Inst{30} = Q; 7814 let Inst{29} = U; 7815 let Inst{28} = Scalar; 7816 let Inst{27-24} = 0b1111; 7817 let Inst{23-22} = size; 7818 // Bit 21 must be set by the derived class. 7819 let Inst{20-16} = Rm; 7820 let Inst{15-12} = opc; 7821 // Bit 11 must be set by the derived class. 7822 let Inst{10} = 0; 7823 let Inst{9-5} = Rn; 7824 let Inst{4-0} = Rd; 7825} 7826 7827let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7828class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7829 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7830 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7831 string apple_kind, string dst_kind, string lhs_kind, 7832 string rhs_kind, list<dag> pattern> 7833 : I<(outs dst_reg:$dst), 7834 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7835 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7836 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7837 Sched<[WriteV]> { 7838 bits<5> Rd; 7839 bits<5> Rn; 7840 bits<5> Rm; 7841 7842 let Inst{31} = 0; 7843 let Inst{30} = Q; 7844 let Inst{29} = U; 7845 let Inst{28} = Scalar; 7846 let Inst{27-24} = 0b1111; 7847 let Inst{23-22} = size; 7848 // Bit 21 must be set by the derived class. 7849 let Inst{20-16} = Rm; 7850 let Inst{15-12} = opc; 7851 // Bit 11 must be set by the derived class. 7852 let Inst{10} = 0; 7853 let Inst{9-5} = Rn; 7854 let Inst{4-0} = Rd; 7855} 7856 7857 7858//---------------------------------------------------------------------------- 7859// Armv8.6 BFloat16 Extension 7860//---------------------------------------------------------------------------- 7861let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 7862 7863class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 7864 string kind2, RegisterOperand RegType, 7865 ValueType AccumType, ValueType InputType> 7866 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 7867 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 7868 (InputType RegType:$Rn), 7869 (InputType RegType:$Rm)))]> { 7870 let AsmString = !strconcat(asm, 7871 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 7872 ", $Rm" # kind2 # "}"); 7873} 7874 7875multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 7876 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 7877 v2f32, v4bf16>; 7878 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 7879 v4f32, v8bf16>; 7880} 7881 7882class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 7883 string dst_kind, string lhs_kind, 7884 string rhs_kind, 7885 RegisterOperand RegType, 7886 ValueType AccumType, 7887 ValueType InputType> 7888 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 7889 RegType, RegType, V128, VectorIndexS, 7890 asm, "", dst_kind, lhs_kind, rhs_kind, 7891 [(set (AccumType RegType:$dst), 7892 (AccumType (int_aarch64_neon_bfdot 7893 (AccumType RegType:$Rd), 7894 (InputType RegType:$Rn), 7895 (InputType (bitconvert (AccumType 7896 (AArch64duplane32 (v4f32 V128:$Rm), 7897 VectorIndexS:$idx)))))))]> { 7898 7899 bits<2> idx; 7900 let Inst{21} = idx{0}; // L 7901 let Inst{11} = idx{1}; // H 7902} 7903 7904multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 7905 7906 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 7907 ".2h", V64, v2f32, v4bf16>; 7908 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 7909 ".2h", V128, v4f32, v8bf16>; 7910} 7911 7912class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 7913 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 7914 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 7915 (v8bf16 V128:$Rn), 7916 (v8bf16 V128:$Rm)))]> { 7917 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 7918} 7919 7920class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 7921 : I<(outs V128:$dst), 7922 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 7923 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 7924 [(set (v4f32 V128:$dst), 7925 (v4f32 (OpNode (v4f32 V128:$Rd), 7926 (v8bf16 V128:$Rn), 7927 (v8bf16 7928 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 7929 VectorIndexH:$idx)))))]>, 7930 Sched<[WriteV]> { 7931 bits<5> Rd; 7932 bits<5> Rn; 7933 bits<4> Rm; 7934 bits<3> idx; 7935 7936 let Inst{31} = 0; 7937 let Inst{30} = Q; 7938 let Inst{29-22} = 0b00111111; 7939 let Inst{21-20} = idx{1-0}; 7940 let Inst{19-16} = Rm; 7941 let Inst{15-12} = 0b1111; 7942 let Inst{11} = idx{2}; // H 7943 let Inst{10} = 0; 7944 let Inst{9-5} = Rn; 7945 let Inst{4-0} = Rd; 7946} 7947 7948class SIMDThreeSameVectorBF16MatrixMul<string asm> 7949 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 7950 V128, asm, ".4s", 7951 [(set (v4f32 V128:$dst), 7952 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 7953 (v8bf16 V128:$Rn), 7954 (v8bf16 V128:$Rm)))]> { 7955 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 7956 ", $Rm", ".8h", "}"); 7957} 7958 7959class SIMD_BFCVTN 7960 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 7961 "bfcvtn", ".4h", ".4s", 7962 [(set (v8bf16 V128:$Rd), 7963 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 7964 7965class SIMD_BFCVTN2 7966 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 7967 "bfcvtn2", ".8h", ".4s", 7968 [(set (v8bf16 V128:$dst), 7969 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 7970 7971class BF16ToSinglePrecision<string asm> 7972 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 7973 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 7974 Sched<[WriteFCvt]> { 7975 bits<5> Rd; 7976 bits<5> Rn; 7977 let Inst{31-10} = 0b0001111001100011010000; 7978 let Inst{9-5} = Rn; 7979 let Inst{4-0} = Rd; 7980} 7981} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 7982 7983//---------------------------------------------------------------------------- 7984// Armv8.6 Matrix Multiply Extension 7985//---------------------------------------------------------------------------- 7986 7987class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 7988 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 7989 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 7990 (v16i8 V128:$Rn), 7991 (v16i8 V128:$Rm)))]> { 7992 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 7993} 7994 7995//---------------------------------------------------------------------------- 7996// ARMv8.2-A Dot Product Instructions (Indexed) 7997class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 7998 string dst_kind, string lhs_kind, string rhs_kind, 7999 RegisterOperand RegType, 8000 ValueType AccumType, ValueType InputType, 8001 SDPatternOperator OpNode> : 8002 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8003 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8004 [(set (AccumType RegType:$dst), 8005 (AccumType (OpNode (AccumType RegType:$Rd), 8006 (InputType RegType:$Rn), 8007 (InputType (bitconvert (AccumType 8008 (AArch64duplane32 (v4i32 V128:$Rm), 8009 VectorIndexS:$idx)))))))]> { 8010 bits<2> idx; 8011 let Inst{21} = idx{0}; // L 8012 let Inst{11} = idx{1}; // H 8013} 8014 8015multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8016 SDPatternOperator OpNode> { 8017 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8018 V64, v2i32, v8i8, OpNode>; 8019 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8020 V128, v4i32, v16i8, OpNode>; 8021} 8022 8023// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8024class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8025 string dst_kind, string lhs_kind, 8026 string rhs_kind, RegisterOperand RegType, 8027 ValueType AccumType, ValueType InputType, 8028 SDPatternOperator OpNode> : 8029 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8030 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8031 [(set (AccumType RegType:$dst), 8032 (AccumType (OpNode (AccumType RegType:$Rd), 8033 (InputType RegType:$Rn), 8034 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8035 VectorIndexH:$idx)))))]> { 8036 // idx = H:L:M 8037 bits<3> idx; 8038 let Inst{11} = idx{2}; // H 8039 let Inst{21} = idx{1}; // L 8040 let Inst{20} = idx{0}; // M 8041} 8042 8043multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8044 SDPatternOperator OpNode> { 8045 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8046 V64, v2f32, v4f16, OpNode>; 8047 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8048 V128, v4f32, v8f16, OpNode>; 8049} 8050 8051multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8052 SDPatternOperator OpNode> { 8053 let Predicates = [HasNEON, HasFullFP16] in { 8054 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8055 V64, V64, 8056 V128_lo, VectorIndexH, 8057 asm, ".4h", ".4h", ".4h", ".h", 8058 [(set (v4f16 V64:$Rd), 8059 (OpNode (v4f16 V64:$Rn), 8060 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8061 bits<3> idx; 8062 let Inst{11} = idx{2}; 8063 let Inst{21} = idx{1}; 8064 let Inst{20} = idx{0}; 8065 } 8066 8067 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8068 V128, V128, 8069 V128_lo, VectorIndexH, 8070 asm, ".8h", ".8h", ".8h", ".h", 8071 [(set (v8f16 V128:$Rd), 8072 (OpNode (v8f16 V128:$Rn), 8073 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8074 bits<3> idx; 8075 let Inst{11} = idx{2}; 8076 let Inst{21} = idx{1}; 8077 let Inst{20} = idx{0}; 8078 } 8079 } // Predicates = [HasNEON, HasFullFP16] 8080 8081 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8082 V64, V64, 8083 V128, VectorIndexS, 8084 asm, ".2s", ".2s", ".2s", ".s", 8085 [(set (v2f32 V64:$Rd), 8086 (OpNode (v2f32 V64:$Rn), 8087 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8088 bits<2> idx; 8089 let Inst{11} = idx{1}; 8090 let Inst{21} = idx{0}; 8091 } 8092 8093 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8094 V128, V128, 8095 V128, VectorIndexS, 8096 asm, ".4s", ".4s", ".4s", ".s", 8097 [(set (v4f32 V128:$Rd), 8098 (OpNode (v4f32 V128:$Rn), 8099 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8100 bits<2> idx; 8101 let Inst{11} = idx{1}; 8102 let Inst{21} = idx{0}; 8103 } 8104 8105 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8106 V128, V128, 8107 V128, VectorIndexD, 8108 asm, ".2d", ".2d", ".2d", ".d", 8109 [(set (v2f64 V128:$Rd), 8110 (OpNode (v2f64 V128:$Rn), 8111 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8112 bits<1> idx; 8113 let Inst{11} = idx{0}; 8114 let Inst{21} = 0; 8115 } 8116 8117 let Predicates = [HasNEON, HasFullFP16] in { 8118 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8119 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8120 asm, ".h", "", "", ".h", 8121 [(set (f16 FPR16Op:$Rd), 8122 (OpNode (f16 FPR16Op:$Rn), 8123 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8124 VectorIndexH:$idx))))]> { 8125 bits<3> idx; 8126 let Inst{11} = idx{2}; 8127 let Inst{21} = idx{1}; 8128 let Inst{20} = idx{0}; 8129 } 8130 } // Predicates = [HasNEON, HasFullFP16] 8131 8132 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8133 FPR32Op, FPR32Op, V128, VectorIndexS, 8134 asm, ".s", "", "", ".s", 8135 [(set (f32 FPR32Op:$Rd), 8136 (OpNode (f32 FPR32Op:$Rn), 8137 (f32 (vector_extract (v4f32 V128:$Rm), 8138 VectorIndexS:$idx))))]> { 8139 bits<2> idx; 8140 let Inst{11} = idx{1}; 8141 let Inst{21} = idx{0}; 8142 } 8143 8144 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8145 FPR64Op, FPR64Op, V128, VectorIndexD, 8146 asm, ".d", "", "", ".d", 8147 [(set (f64 FPR64Op:$Rd), 8148 (OpNode (f64 FPR64Op:$Rn), 8149 (f64 (vector_extract (v2f64 V128:$Rm), 8150 VectorIndexD:$idx))))]> { 8151 bits<1> idx; 8152 let Inst{11} = idx{0}; 8153 let Inst{21} = 0; 8154 } 8155} 8156 8157multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8158 let Predicates = [HasNEON, HasFullFP16] in { 8159 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8160 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8161 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8162 VectorIndexH:$idx))), 8163 (!cast<Instruction>(INST # "v8i16_indexed") 8164 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8165 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8166 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8167 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8168 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8169 8170 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8171 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8172 VectorIndexH:$idx))), 8173 (!cast<Instruction>(INST # "v4i16_indexed") 8174 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8175 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8176 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8177 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8178 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8179 8180 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8181 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8182 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8183 V128_lo:$Rm, VectorIndexH:$idx)>; 8184 } // Predicates = [HasNEON, HasFullFP16] 8185 8186 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8187 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8188 (AArch64duplane32 (v4f32 V128:$Rm), 8189 VectorIndexS:$idx))), 8190 (!cast<Instruction>(INST # v2i32_indexed) 8191 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8192 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8193 (AArch64dup (f32 FPR32Op:$Rm)))), 8194 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8195 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8196 8197 8198 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8199 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8200 (AArch64duplane32 (v4f32 V128:$Rm), 8201 VectorIndexS:$idx))), 8202 (!cast<Instruction>(INST # "v4i32_indexed") 8203 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8204 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8205 (AArch64dup (f32 FPR32Op:$Rm)))), 8206 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8207 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8208 8209 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8210 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8211 (AArch64duplane64 (v2f64 V128:$Rm), 8212 VectorIndexD:$idx))), 8213 (!cast<Instruction>(INST # "v2i64_indexed") 8214 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8215 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8216 (AArch64dup (f64 FPR64Op:$Rm)))), 8217 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8218 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8219 8220 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8221 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8222 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8223 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8224 V128:$Rm, VectorIndexS:$idx)>; 8225 8226 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8227 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8228 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8229 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8230 V128:$Rm, VectorIndexD:$idx)>; 8231} 8232 8233multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8234 let Predicates = [HasNEON, HasFullFP16] in { 8235 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8236 V128_lo, VectorIndexH, 8237 asm, ".4h", ".4h", ".4h", ".h", []> { 8238 bits<3> idx; 8239 let Inst{11} = idx{2}; 8240 let Inst{21} = idx{1}; 8241 let Inst{20} = idx{0}; 8242 } 8243 8244 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8245 V128, V128, 8246 V128_lo, VectorIndexH, 8247 asm, ".8h", ".8h", ".8h", ".h", []> { 8248 bits<3> idx; 8249 let Inst{11} = idx{2}; 8250 let Inst{21} = idx{1}; 8251 let Inst{20} = idx{0}; 8252 } 8253 } // Predicates = [HasNEON, HasFullFP16] 8254 8255 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8256 V128, VectorIndexS, 8257 asm, ".2s", ".2s", ".2s", ".s", []> { 8258 bits<2> idx; 8259 let Inst{11} = idx{1}; 8260 let Inst{21} = idx{0}; 8261 } 8262 8263 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8264 V128, V128, 8265 V128, VectorIndexS, 8266 asm, ".4s", ".4s", ".4s", ".s", []> { 8267 bits<2> idx; 8268 let Inst{11} = idx{1}; 8269 let Inst{21} = idx{0}; 8270 } 8271 8272 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8273 V128, V128, 8274 V128, VectorIndexD, 8275 asm, ".2d", ".2d", ".2d", ".d", []> { 8276 bits<1> idx; 8277 let Inst{11} = idx{0}; 8278 let Inst{21} = 0; 8279 } 8280 8281 let Predicates = [HasNEON, HasFullFP16] in { 8282 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8283 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8284 asm, ".h", "", "", ".h", []> { 8285 bits<3> idx; 8286 let Inst{11} = idx{2}; 8287 let Inst{21} = idx{1}; 8288 let Inst{20} = idx{0}; 8289 } 8290 } // Predicates = [HasNEON, HasFullFP16] 8291 8292 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8293 FPR32Op, FPR32Op, V128, VectorIndexS, 8294 asm, ".s", "", "", ".s", []> { 8295 bits<2> idx; 8296 let Inst{11} = idx{1}; 8297 let Inst{21} = idx{0}; 8298 } 8299 8300 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8301 FPR64Op, FPR64Op, V128, VectorIndexD, 8302 asm, ".d", "", "", ".d", []> { 8303 bits<1> idx; 8304 let Inst{11} = idx{0}; 8305 let Inst{21} = 0; 8306 } 8307} 8308 8309multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8310 SDPatternOperator OpNodeLaneQ> { 8311 8312 def : Pat<(v4i16 (OpNodeLane 8313 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8314 VectorIndexS32b:$idx)), 8315 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8316 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8317 (UImmS1XForm $idx))>; 8318 8319 def : Pat<(v4i16 (OpNodeLaneQ 8320 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8321 VectorIndexH32b:$idx)), 8322 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8323 (UImmS1XForm $idx))>; 8324 8325 def : Pat<(v8i16 (OpNodeLane 8326 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8327 VectorIndexS32b:$idx)), 8328 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8329 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8330 (UImmS1XForm $idx))>; 8331 8332 def : Pat<(v8i16 (OpNodeLaneQ 8333 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8334 VectorIndexH32b:$idx)), 8335 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8336 (UImmS1XForm $idx))>; 8337 8338 def : Pat<(v2i32 (OpNodeLane 8339 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8340 VectorIndexD32b:$idx)), 8341 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8342 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8343 (UImmS1XForm $idx))>; 8344 8345 def : Pat<(v2i32 (OpNodeLaneQ 8346 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8347 VectorIndexS32b:$idx)), 8348 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8349 (UImmS1XForm $idx))>; 8350 8351 def : Pat<(v4i32 (OpNodeLane 8352 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8353 VectorIndexD32b:$idx)), 8354 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8355 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8356 (UImmS1XForm $idx))>; 8357 8358 def : Pat<(v4i32 (OpNodeLaneQ 8359 (v4i32 V128:$Rn), 8360 (v4i32 V128:$Rm), 8361 VectorIndexS32b:$idx)), 8362 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8363 (UImmS1XForm $idx))>; 8364 8365} 8366 8367multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8368 SDPatternOperator OpNode> { 8369 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8370 V128_lo, VectorIndexH, 8371 asm, ".4h", ".4h", ".4h", ".h", 8372 [(set (v4i16 V64:$Rd), 8373 (OpNode (v4i16 V64:$Rn), 8374 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8375 bits<3> idx; 8376 let Inst{11} = idx{2}; 8377 let Inst{21} = idx{1}; 8378 let Inst{20} = idx{0}; 8379 } 8380 8381 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8382 V128, V128, 8383 V128_lo, VectorIndexH, 8384 asm, ".8h", ".8h", ".8h", ".h", 8385 [(set (v8i16 V128:$Rd), 8386 (OpNode (v8i16 V128:$Rn), 8387 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8388 bits<3> idx; 8389 let Inst{11} = idx{2}; 8390 let Inst{21} = idx{1}; 8391 let Inst{20} = idx{0}; 8392 } 8393 8394 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8395 V64, V64, 8396 V128, VectorIndexS, 8397 asm, ".2s", ".2s", ".2s", ".s", 8398 [(set (v2i32 V64:$Rd), 8399 (OpNode (v2i32 V64:$Rn), 8400 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8401 bits<2> idx; 8402 let Inst{11} = idx{1}; 8403 let Inst{21} = idx{0}; 8404 } 8405 8406 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8407 V128, V128, 8408 V128, VectorIndexS, 8409 asm, ".4s", ".4s", ".4s", ".s", 8410 [(set (v4i32 V128:$Rd), 8411 (OpNode (v4i32 V128:$Rn), 8412 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8413 bits<2> idx; 8414 let Inst{11} = idx{1}; 8415 let Inst{21} = idx{0}; 8416 } 8417 8418 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8419 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8420 asm, ".h", "", "", ".h", []> { 8421 bits<3> idx; 8422 let Inst{11} = idx{2}; 8423 let Inst{21} = idx{1}; 8424 let Inst{20} = idx{0}; 8425 } 8426 8427 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8428 FPR32Op, FPR32Op, V128, VectorIndexS, 8429 asm, ".s", "", "", ".s", 8430 [(set (i32 FPR32Op:$Rd), 8431 (OpNode FPR32Op:$Rn, 8432 (i32 (vector_extract (v4i32 V128:$Rm), 8433 VectorIndexS:$idx))))]> { 8434 bits<2> idx; 8435 let Inst{11} = idx{1}; 8436 let Inst{21} = idx{0}; 8437 } 8438} 8439 8440multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8441 SDPatternOperator OpNode> { 8442 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8443 V64, V64, 8444 V128_lo, VectorIndexH, 8445 asm, ".4h", ".4h", ".4h", ".h", 8446 [(set (v4i16 V64:$Rd), 8447 (OpNode (v4i16 V64:$Rn), 8448 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 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 v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8456 V128, V128, 8457 V128_lo, VectorIndexH, 8458 asm, ".8h", ".8h", ".8h", ".h", 8459 [(set (v8i16 V128:$Rd), 8460 (OpNode (v8i16 V128:$Rn), 8461 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8462 bits<3> idx; 8463 let Inst{11} = idx{2}; 8464 let Inst{21} = idx{1}; 8465 let Inst{20} = idx{0}; 8466 } 8467 8468 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8469 V64, V64, 8470 V128, VectorIndexS, 8471 asm, ".2s", ".2s", ".2s", ".s", 8472 [(set (v2i32 V64:$Rd), 8473 (OpNode (v2i32 V64:$Rn), 8474 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8475 bits<2> idx; 8476 let Inst{11} = idx{1}; 8477 let Inst{21} = idx{0}; 8478 } 8479 8480 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8481 V128, V128, 8482 V128, VectorIndexS, 8483 asm, ".4s", ".4s", ".4s", ".s", 8484 [(set (v4i32 V128:$Rd), 8485 (OpNode (v4i32 V128:$Rn), 8486 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8487 bits<2> idx; 8488 let Inst{11} = idx{1}; 8489 let Inst{21} = idx{0}; 8490 } 8491} 8492 8493multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8494 SDPatternOperator OpNode> { 8495 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8496 V128_lo, VectorIndexH, 8497 asm, ".4h", ".4h", ".4h", ".h", 8498 [(set (v4i16 V64:$dst), 8499 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8500 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8501 bits<3> idx; 8502 let Inst{11} = idx{2}; 8503 let Inst{21} = idx{1}; 8504 let Inst{20} = idx{0}; 8505 } 8506 8507 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8508 V128, V128, 8509 V128_lo, VectorIndexH, 8510 asm, ".8h", ".8h", ".8h", ".h", 8511 [(set (v8i16 V128:$dst), 8512 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8513 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8514 bits<3> idx; 8515 let Inst{11} = idx{2}; 8516 let Inst{21} = idx{1}; 8517 let Inst{20} = idx{0}; 8518 } 8519 8520 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8521 V64, V64, 8522 V128, VectorIndexS, 8523 asm, ".2s", ".2s", ".2s", ".s", 8524 [(set (v2i32 V64:$dst), 8525 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8526 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8527 bits<2> idx; 8528 let Inst{11} = idx{1}; 8529 let Inst{21} = idx{0}; 8530 } 8531 8532 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8533 V128, V128, 8534 V128, VectorIndexS, 8535 asm, ".4s", ".4s", ".4s", ".s", 8536 [(set (v4i32 V128:$dst), 8537 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8538 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8539 bits<2> idx; 8540 let Inst{11} = idx{1}; 8541 let Inst{21} = idx{0}; 8542 } 8543} 8544 8545multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8546 SDPatternOperator OpNode> { 8547 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8548 V128, V64, 8549 V128_lo, VectorIndexH, 8550 asm, ".4s", ".4s", ".4h", ".h", 8551 [(set (v4i32 V128:$Rd), 8552 (OpNode (v4i16 V64:$Rn), 8553 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8554 bits<3> idx; 8555 let Inst{11} = idx{2}; 8556 let Inst{21} = idx{1}; 8557 let Inst{20} = idx{0}; 8558 } 8559 8560 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8561 V128, V128, 8562 V128_lo, VectorIndexH, 8563 asm#"2", ".4s", ".4s", ".8h", ".h", 8564 [(set (v4i32 V128:$Rd), 8565 (OpNode (extract_high_v8i16 V128:$Rn), 8566 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8567 VectorIndexH:$idx))))]> { 8568 8569 bits<3> idx; 8570 let Inst{11} = idx{2}; 8571 let Inst{21} = idx{1}; 8572 let Inst{20} = idx{0}; 8573 } 8574 8575 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8576 V128, V64, 8577 V128, VectorIndexS, 8578 asm, ".2d", ".2d", ".2s", ".s", 8579 [(set (v2i64 V128:$Rd), 8580 (OpNode (v2i32 V64:$Rn), 8581 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8582 bits<2> idx; 8583 let Inst{11} = idx{1}; 8584 let Inst{21} = idx{0}; 8585 } 8586 8587 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8588 V128, V128, 8589 V128, VectorIndexS, 8590 asm#"2", ".2d", ".2d", ".4s", ".s", 8591 [(set (v2i64 V128:$Rd), 8592 (OpNode (extract_high_v4i32 V128:$Rn), 8593 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8594 VectorIndexS:$idx))))]> { 8595 bits<2> idx; 8596 let Inst{11} = idx{1}; 8597 let Inst{21} = idx{0}; 8598 } 8599 8600 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8601 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8602 asm, ".h", "", "", ".h", []> { 8603 bits<3> idx; 8604 let Inst{11} = idx{2}; 8605 let Inst{21} = idx{1}; 8606 let Inst{20} = idx{0}; 8607 } 8608 8609 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8610 FPR64Op, FPR32Op, V128, VectorIndexS, 8611 asm, ".s", "", "", ".s", []> { 8612 bits<2> idx; 8613 let Inst{11} = idx{1}; 8614 let Inst{21} = idx{0}; 8615 } 8616} 8617 8618multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8619 SDPatternOperator Accum> { 8620 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8621 V128, V64, 8622 V128_lo, VectorIndexH, 8623 asm, ".4s", ".4s", ".4h", ".h", 8624 [(set (v4i32 V128:$dst), 8625 (Accum (v4i32 V128:$Rd), 8626 (v4i32 (int_aarch64_neon_sqdmull 8627 (v4i16 V64:$Rn), 8628 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8629 VectorIndexH:$idx))))))]> { 8630 bits<3> idx; 8631 let Inst{11} = idx{2}; 8632 let Inst{21} = idx{1}; 8633 let Inst{20} = idx{0}; 8634 } 8635 8636 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8637 // intermediate EXTRACT_SUBREG would be untyped. 8638 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8639 (i32 (vector_extract (v4i32 8640 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8641 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8642 VectorIndexH:$idx)))), 8643 (i64 0))))), 8644 (EXTRACT_SUBREG 8645 (!cast<Instruction>(NAME # v4i16_indexed) 8646 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8647 V128_lo:$Rm, VectorIndexH:$idx), 8648 ssub)>; 8649 8650 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8651 V128, V128, 8652 V128_lo, VectorIndexH, 8653 asm#"2", ".4s", ".4s", ".8h", ".h", 8654 [(set (v4i32 V128:$dst), 8655 (Accum (v4i32 V128:$Rd), 8656 (v4i32 (int_aarch64_neon_sqdmull 8657 (extract_high_v8i16 V128:$Rn), 8658 (extract_high_v8i16 8659 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8660 VectorIndexH:$idx))))))]> { 8661 bits<3> idx; 8662 let Inst{11} = idx{2}; 8663 let Inst{21} = idx{1}; 8664 let Inst{20} = idx{0}; 8665 } 8666 8667 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8668 V128, V64, 8669 V128, VectorIndexS, 8670 asm, ".2d", ".2d", ".2s", ".s", 8671 [(set (v2i64 V128:$dst), 8672 (Accum (v2i64 V128:$Rd), 8673 (v2i64 (int_aarch64_neon_sqdmull 8674 (v2i32 V64:$Rn), 8675 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8676 VectorIndexS:$idx))))))]> { 8677 bits<2> idx; 8678 let Inst{11} = idx{1}; 8679 let Inst{21} = idx{0}; 8680 } 8681 8682 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8683 V128, V128, 8684 V128, VectorIndexS, 8685 asm#"2", ".2d", ".2d", ".4s", ".s", 8686 [(set (v2i64 V128:$dst), 8687 (Accum (v2i64 V128:$Rd), 8688 (v2i64 (int_aarch64_neon_sqdmull 8689 (extract_high_v4i32 V128:$Rn), 8690 (extract_high_v4i32 8691 (AArch64duplane32 (v4i32 V128:$Rm), 8692 VectorIndexS:$idx))))))]> { 8693 bits<2> idx; 8694 let Inst{11} = idx{1}; 8695 let Inst{21} = idx{0}; 8696 } 8697 8698 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8699 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8700 asm, ".h", "", "", ".h", []> { 8701 bits<3> idx; 8702 let Inst{11} = idx{2}; 8703 let Inst{21} = idx{1}; 8704 let Inst{20} = idx{0}; 8705 } 8706 8707 8708 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8709 FPR64Op, FPR32Op, V128, VectorIndexS, 8710 asm, ".s", "", "", ".s", 8711 [(set (i64 FPR64Op:$dst), 8712 (Accum (i64 FPR64Op:$Rd), 8713 (i64 (int_aarch64_neon_sqdmulls_scalar 8714 (i32 FPR32Op:$Rn), 8715 (i32 (vector_extract (v4i32 V128:$Rm), 8716 VectorIndexS:$idx))))))]> { 8717 8718 bits<2> idx; 8719 let Inst{11} = idx{1}; 8720 let Inst{21} = idx{0}; 8721 } 8722} 8723 8724multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8725 SDPatternOperator OpNode> { 8726 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8727 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8728 V128, V64, 8729 V128_lo, VectorIndexH, 8730 asm, ".4s", ".4s", ".4h", ".h", 8731 [(set (v4i32 V128:$Rd), 8732 (OpNode (v4i16 V64:$Rn), 8733 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8734 bits<3> idx; 8735 let Inst{11} = idx{2}; 8736 let Inst{21} = idx{1}; 8737 let Inst{20} = idx{0}; 8738 } 8739 8740 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8741 V128, V128, 8742 V128_lo, VectorIndexH, 8743 asm#"2", ".4s", ".4s", ".8h", ".h", 8744 [(set (v4i32 V128:$Rd), 8745 (OpNode (extract_high_v8i16 V128:$Rn), 8746 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8747 VectorIndexH:$idx))))]> { 8748 8749 bits<3> idx; 8750 let Inst{11} = idx{2}; 8751 let Inst{21} = idx{1}; 8752 let Inst{20} = idx{0}; 8753 } 8754 8755 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8756 V128, V64, 8757 V128, VectorIndexS, 8758 asm, ".2d", ".2d", ".2s", ".s", 8759 [(set (v2i64 V128:$Rd), 8760 (OpNode (v2i32 V64:$Rn), 8761 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8762 bits<2> idx; 8763 let Inst{11} = idx{1}; 8764 let Inst{21} = idx{0}; 8765 } 8766 8767 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8768 V128, V128, 8769 V128, VectorIndexS, 8770 asm#"2", ".2d", ".2d", ".4s", ".s", 8771 [(set (v2i64 V128:$Rd), 8772 (OpNode (extract_high_v4i32 V128:$Rn), 8773 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8774 VectorIndexS:$idx))))]> { 8775 bits<2> idx; 8776 let Inst{11} = idx{1}; 8777 let Inst{21} = idx{0}; 8778 } 8779 } 8780} 8781 8782multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8783 SDPatternOperator OpNode> { 8784 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8785 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8786 V128, V64, 8787 V128_lo, VectorIndexH, 8788 asm, ".4s", ".4s", ".4h", ".h", 8789 [(set (v4i32 V128:$dst), 8790 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8791 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8792 bits<3> idx; 8793 let Inst{11} = idx{2}; 8794 let Inst{21} = idx{1}; 8795 let Inst{20} = idx{0}; 8796 } 8797 8798 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8799 V128, V128, 8800 V128_lo, VectorIndexH, 8801 asm#"2", ".4s", ".4s", ".8h", ".h", 8802 [(set (v4i32 V128:$dst), 8803 (OpNode (v4i32 V128:$Rd), 8804 (extract_high_v8i16 V128:$Rn), 8805 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8806 VectorIndexH:$idx))))]> { 8807 bits<3> idx; 8808 let Inst{11} = idx{2}; 8809 let Inst{21} = idx{1}; 8810 let Inst{20} = idx{0}; 8811 } 8812 8813 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8814 V128, V64, 8815 V128, VectorIndexS, 8816 asm, ".2d", ".2d", ".2s", ".s", 8817 [(set (v2i64 V128:$dst), 8818 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8819 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8820 bits<2> idx; 8821 let Inst{11} = idx{1}; 8822 let Inst{21} = idx{0}; 8823 } 8824 8825 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8826 V128, V128, 8827 V128, VectorIndexS, 8828 asm#"2", ".2d", ".2d", ".4s", ".s", 8829 [(set (v2i64 V128:$dst), 8830 (OpNode (v2i64 V128:$Rd), 8831 (extract_high_v4i32 V128:$Rn), 8832 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8833 VectorIndexS:$idx))))]> { 8834 bits<2> idx; 8835 let Inst{11} = idx{1}; 8836 let Inst{21} = idx{0}; 8837 } 8838 } 8839} 8840 8841//---------------------------------------------------------------------------- 8842// AdvSIMD scalar shift by immediate 8843//---------------------------------------------------------------------------- 8844 8845let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8846class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8847 RegisterClass regtype1, RegisterClass regtype2, 8848 Operand immtype, string asm, list<dag> pattern> 8849 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8850 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8851 Sched<[WriteV]> { 8852 bits<5> Rd; 8853 bits<5> Rn; 8854 bits<7> imm; 8855 let Inst{31-30} = 0b01; 8856 let Inst{29} = U; 8857 let Inst{28-23} = 0b111110; 8858 let Inst{22-16} = fixed_imm; 8859 let Inst{15-11} = opc; 8860 let Inst{10} = 1; 8861 let Inst{9-5} = Rn; 8862 let Inst{4-0} = Rd; 8863} 8864 8865let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8866class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8867 RegisterClass regtype1, RegisterClass regtype2, 8868 Operand immtype, string asm, list<dag> pattern> 8869 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8870 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8871 Sched<[WriteV]> { 8872 bits<5> Rd; 8873 bits<5> Rn; 8874 bits<7> imm; 8875 let Inst{31-30} = 0b01; 8876 let Inst{29} = U; 8877 let Inst{28-23} = 0b111110; 8878 let Inst{22-16} = fixed_imm; 8879 let Inst{15-11} = opc; 8880 let Inst{10} = 1; 8881 let Inst{9-5} = Rn; 8882 let Inst{4-0} = Rd; 8883} 8884 8885 8886multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8887 let Predicates = [HasNEON, HasFullFP16] in { 8888 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8889 FPR16, FPR16, vecshiftR16, asm, []> { 8890 let Inst{19-16} = imm{3-0}; 8891 } 8892 } // Predicates = [HasNEON, HasFullFP16] 8893 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8894 FPR32, FPR32, vecshiftR32, asm, []> { 8895 let Inst{20-16} = imm{4-0}; 8896 } 8897 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8898 FPR64, FPR64, vecshiftR64, asm, []> { 8899 let Inst{21-16} = imm{5-0}; 8900 } 8901} 8902 8903multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8904 SDPatternOperator OpNode> { 8905 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8906 FPR64, FPR64, vecshiftR64, asm, 8907 [(set (i64 FPR64:$Rd), 8908 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8909 let Inst{21-16} = imm{5-0}; 8910 } 8911 8912 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8913 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8914} 8915 8916multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8917 SDPatternOperator OpNode = null_frag> { 8918 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8919 FPR64, FPR64, vecshiftR64, asm, 8920 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8921 (i32 vecshiftR64:$imm)))]> { 8922 let Inst{21-16} = imm{5-0}; 8923 } 8924 8925 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8926 (i32 vecshiftR64:$imm))), 8927 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8928 vecshiftR64:$imm)>; 8929} 8930 8931multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8932 SDPatternOperator OpNode> { 8933 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8934 FPR64, FPR64, vecshiftL64, asm, 8935 [(set (v1i64 FPR64:$Rd), 8936 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8937 let Inst{21-16} = imm{5-0}; 8938 } 8939} 8940 8941let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8942multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8943 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8944 FPR64, FPR64, vecshiftL64, asm, []> { 8945 let Inst{21-16} = imm{5-0}; 8946 } 8947} 8948 8949let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8950multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8951 SDPatternOperator OpNode = null_frag> { 8952 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8953 FPR8, FPR16, vecshiftR8, asm, []> { 8954 let Inst{18-16} = imm{2-0}; 8955 } 8956 8957 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8958 FPR16, FPR32, vecshiftR16, asm, []> { 8959 let Inst{19-16} = imm{3-0}; 8960 } 8961 8962 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8963 FPR32, FPR64, vecshiftR32, asm, 8964 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 8965 let Inst{20-16} = imm{4-0}; 8966 } 8967} 8968 8969multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 8970 SDPatternOperator OpNode> { 8971 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8972 FPR8, FPR8, vecshiftL8, asm, []> { 8973 let Inst{18-16} = imm{2-0}; 8974 } 8975 8976 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8977 FPR16, FPR16, vecshiftL16, asm, []> { 8978 let Inst{19-16} = imm{3-0}; 8979 } 8980 8981 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8982 FPR32, FPR32, vecshiftL32, asm, 8983 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 8984 let Inst{20-16} = imm{4-0}; 8985 } 8986 8987 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8988 FPR64, FPR64, vecshiftL64, asm, 8989 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8990 let Inst{21-16} = imm{5-0}; 8991 } 8992 8993 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8994 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8995} 8996 8997multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 8998 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8999 FPR8, FPR8, vecshiftR8, asm, []> { 9000 let Inst{18-16} = imm{2-0}; 9001 } 9002 9003 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9004 FPR16, FPR16, vecshiftR16, asm, []> { 9005 let Inst{19-16} = imm{3-0}; 9006 } 9007 9008 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9009 FPR32, FPR32, vecshiftR32, asm, []> { 9010 let Inst{20-16} = imm{4-0}; 9011 } 9012 9013 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9014 FPR64, FPR64, vecshiftR64, asm, []> { 9015 let Inst{21-16} = imm{5-0}; 9016 } 9017} 9018 9019//---------------------------------------------------------------------------- 9020// AdvSIMD vector x indexed element 9021//---------------------------------------------------------------------------- 9022 9023let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9024class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9025 RegisterOperand dst_reg, RegisterOperand src_reg, 9026 Operand immtype, 9027 string asm, string dst_kind, string src_kind, 9028 list<dag> pattern> 9029 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9030 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9031 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9032 Sched<[WriteV]> { 9033 bits<5> Rd; 9034 bits<5> Rn; 9035 let Inst{31} = 0; 9036 let Inst{30} = Q; 9037 let Inst{29} = U; 9038 let Inst{28-23} = 0b011110; 9039 let Inst{22-16} = fixed_imm; 9040 let Inst{15-11} = opc; 9041 let Inst{10} = 1; 9042 let Inst{9-5} = Rn; 9043 let Inst{4-0} = Rd; 9044} 9045 9046let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9047class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9048 RegisterOperand vectype1, RegisterOperand vectype2, 9049 Operand immtype, 9050 string asm, string dst_kind, string src_kind, 9051 list<dag> pattern> 9052 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9053 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9054 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9055 Sched<[WriteV]> { 9056 bits<5> Rd; 9057 bits<5> Rn; 9058 let Inst{31} = 0; 9059 let Inst{30} = Q; 9060 let Inst{29} = U; 9061 let Inst{28-23} = 0b011110; 9062 let Inst{22-16} = fixed_imm; 9063 let Inst{15-11} = opc; 9064 let Inst{10} = 1; 9065 let Inst{9-5} = Rn; 9066 let Inst{4-0} = Rd; 9067} 9068 9069multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9070 Intrinsic OpNode> { 9071 let Predicates = [HasNEON, HasFullFP16] in { 9072 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9073 V64, V64, vecshiftR16, 9074 asm, ".4h", ".4h", 9075 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9076 bits<4> imm; 9077 let Inst{19-16} = imm; 9078 } 9079 9080 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9081 V128, V128, vecshiftR16, 9082 asm, ".8h", ".8h", 9083 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9084 bits<4> imm; 9085 let Inst{19-16} = imm; 9086 } 9087 } // Predicates = [HasNEON, HasFullFP16] 9088 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9089 V64, V64, vecshiftR32, 9090 asm, ".2s", ".2s", 9091 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9092 bits<5> imm; 9093 let Inst{20-16} = imm; 9094 } 9095 9096 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9097 V128, V128, vecshiftR32, 9098 asm, ".4s", ".4s", 9099 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9100 bits<5> imm; 9101 let Inst{20-16} = imm; 9102 } 9103 9104 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9105 V128, V128, vecshiftR64, 9106 asm, ".2d", ".2d", 9107 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9108 bits<6> imm; 9109 let Inst{21-16} = imm; 9110 } 9111} 9112 9113multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9114 Intrinsic OpNode> { 9115 let Predicates = [HasNEON, HasFullFP16] in { 9116 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9117 V64, V64, vecshiftR16, 9118 asm, ".4h", ".4h", 9119 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9120 bits<4> imm; 9121 let Inst{19-16} = imm; 9122 } 9123 9124 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9125 V128, V128, vecshiftR16, 9126 asm, ".8h", ".8h", 9127 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9128 bits<4> imm; 9129 let Inst{19-16} = imm; 9130 } 9131 } // Predicates = [HasNEON, HasFullFP16] 9132 9133 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9134 V64, V64, vecshiftR32, 9135 asm, ".2s", ".2s", 9136 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9137 bits<5> imm; 9138 let Inst{20-16} = imm; 9139 } 9140 9141 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9142 V128, V128, vecshiftR32, 9143 asm, ".4s", ".4s", 9144 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9145 bits<5> imm; 9146 let Inst{20-16} = imm; 9147 } 9148 9149 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9150 V128, V128, vecshiftR64, 9151 asm, ".2d", ".2d", 9152 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9153 bits<6> imm; 9154 let Inst{21-16} = imm; 9155 } 9156} 9157 9158multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9159 SDPatternOperator OpNode> { 9160 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9161 V64, V128, vecshiftR16Narrow, 9162 asm, ".8b", ".8h", 9163 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9164 bits<3> imm; 9165 let Inst{18-16} = imm; 9166 } 9167 9168 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9169 V128, V128, vecshiftR16Narrow, 9170 asm#"2", ".16b", ".8h", []> { 9171 bits<3> imm; 9172 let Inst{18-16} = imm; 9173 let hasSideEffects = 0; 9174 } 9175 9176 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9177 V64, V128, vecshiftR32Narrow, 9178 asm, ".4h", ".4s", 9179 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9180 bits<4> imm; 9181 let Inst{19-16} = imm; 9182 } 9183 9184 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9185 V128, V128, vecshiftR32Narrow, 9186 asm#"2", ".8h", ".4s", []> { 9187 bits<4> imm; 9188 let Inst{19-16} = imm; 9189 let hasSideEffects = 0; 9190 } 9191 9192 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9193 V64, V128, vecshiftR64Narrow, 9194 asm, ".2s", ".2d", 9195 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9196 bits<5> imm; 9197 let Inst{20-16} = imm; 9198 } 9199 9200 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9201 V128, V128, vecshiftR64Narrow, 9202 asm#"2", ".4s", ".2d", []> { 9203 bits<5> imm; 9204 let Inst{20-16} = imm; 9205 let hasSideEffects = 0; 9206 } 9207 9208 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9209 // themselves, so put them here instead. 9210 9211 // Patterns involving what's effectively an insert high and a normal 9212 // intrinsic, represented by CONCAT_VECTORS. 9213 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9214 vecshiftR16Narrow:$imm)), 9215 (!cast<Instruction>(NAME # "v16i8_shift") 9216 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9217 V128:$Rn, vecshiftR16Narrow:$imm)>; 9218 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9219 vecshiftR32Narrow:$imm)), 9220 (!cast<Instruction>(NAME # "v8i16_shift") 9221 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9222 V128:$Rn, vecshiftR32Narrow:$imm)>; 9223 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9224 vecshiftR64Narrow:$imm)), 9225 (!cast<Instruction>(NAME # "v4i32_shift") 9226 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9227 V128:$Rn, vecshiftR64Narrow:$imm)>; 9228} 9229 9230multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9231 SDPatternOperator OpNode> { 9232 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9233 V64, V64, vecshiftL8, 9234 asm, ".8b", ".8b", 9235 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9236 (i32 vecshiftL8:$imm)))]> { 9237 bits<3> imm; 9238 let Inst{18-16} = imm; 9239 } 9240 9241 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9242 V128, V128, vecshiftL8, 9243 asm, ".16b", ".16b", 9244 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9245 (i32 vecshiftL8:$imm)))]> { 9246 bits<3> imm; 9247 let Inst{18-16} = imm; 9248 } 9249 9250 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9251 V64, V64, vecshiftL16, 9252 asm, ".4h", ".4h", 9253 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9254 (i32 vecshiftL16:$imm)))]> { 9255 bits<4> imm; 9256 let Inst{19-16} = imm; 9257 } 9258 9259 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9260 V128, V128, vecshiftL16, 9261 asm, ".8h", ".8h", 9262 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9263 (i32 vecshiftL16:$imm)))]> { 9264 bits<4> imm; 9265 let Inst{19-16} = imm; 9266 } 9267 9268 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9269 V64, V64, vecshiftL32, 9270 asm, ".2s", ".2s", 9271 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9272 (i32 vecshiftL32:$imm)))]> { 9273 bits<5> imm; 9274 let Inst{20-16} = imm; 9275 } 9276 9277 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9278 V128, V128, vecshiftL32, 9279 asm, ".4s", ".4s", 9280 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9281 (i32 vecshiftL32:$imm)))]> { 9282 bits<5> imm; 9283 let Inst{20-16} = imm; 9284 } 9285 9286 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9287 V128, V128, vecshiftL64, 9288 asm, ".2d", ".2d", 9289 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9290 (i32 vecshiftL64:$imm)))]> { 9291 bits<6> imm; 9292 let Inst{21-16} = imm; 9293 } 9294} 9295 9296multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9297 SDPatternOperator OpNode> { 9298 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9299 V64, V64, vecshiftR8, 9300 asm, ".8b", ".8b", 9301 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9302 (i32 vecshiftR8:$imm)))]> { 9303 bits<3> imm; 9304 let Inst{18-16} = imm; 9305 } 9306 9307 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9308 V128, V128, vecshiftR8, 9309 asm, ".16b", ".16b", 9310 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9311 (i32 vecshiftR8:$imm)))]> { 9312 bits<3> imm; 9313 let Inst{18-16} = imm; 9314 } 9315 9316 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9317 V64, V64, vecshiftR16, 9318 asm, ".4h", ".4h", 9319 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9320 (i32 vecshiftR16:$imm)))]> { 9321 bits<4> imm; 9322 let Inst{19-16} = imm; 9323 } 9324 9325 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9326 V128, V128, vecshiftR16, 9327 asm, ".8h", ".8h", 9328 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9329 (i32 vecshiftR16:$imm)))]> { 9330 bits<4> imm; 9331 let Inst{19-16} = imm; 9332 } 9333 9334 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9335 V64, V64, vecshiftR32, 9336 asm, ".2s", ".2s", 9337 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9338 (i32 vecshiftR32:$imm)))]> { 9339 bits<5> imm; 9340 let Inst{20-16} = imm; 9341 } 9342 9343 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9344 V128, V128, vecshiftR32, 9345 asm, ".4s", ".4s", 9346 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9347 (i32 vecshiftR32:$imm)))]> { 9348 bits<5> imm; 9349 let Inst{20-16} = imm; 9350 } 9351 9352 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9353 V128, V128, vecshiftR64, 9354 asm, ".2d", ".2d", 9355 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9356 (i32 vecshiftR64:$imm)))]> { 9357 bits<6> imm; 9358 let Inst{21-16} = imm; 9359 } 9360} 9361 9362let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9363multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9364 SDPatternOperator OpNode = null_frag> { 9365 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9366 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9367 [(set (v8i8 V64:$dst), 9368 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9369 (i32 vecshiftR8:$imm)))]> { 9370 bits<3> imm; 9371 let Inst{18-16} = imm; 9372 } 9373 9374 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9375 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9376 [(set (v16i8 V128:$dst), 9377 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9378 (i32 vecshiftR8:$imm)))]> { 9379 bits<3> imm; 9380 let Inst{18-16} = imm; 9381 } 9382 9383 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9384 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9385 [(set (v4i16 V64:$dst), 9386 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9387 (i32 vecshiftR16:$imm)))]> { 9388 bits<4> imm; 9389 let Inst{19-16} = imm; 9390 } 9391 9392 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9393 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9394 [(set (v8i16 V128:$dst), 9395 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9396 (i32 vecshiftR16:$imm)))]> { 9397 bits<4> imm; 9398 let Inst{19-16} = imm; 9399 } 9400 9401 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9402 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9403 [(set (v2i32 V64:$dst), 9404 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9405 (i32 vecshiftR32:$imm)))]> { 9406 bits<5> imm; 9407 let Inst{20-16} = imm; 9408 } 9409 9410 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9411 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9412 [(set (v4i32 V128:$dst), 9413 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9414 (i32 vecshiftR32:$imm)))]> { 9415 bits<5> imm; 9416 let Inst{20-16} = imm; 9417 } 9418 9419 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9420 V128, V128, vecshiftR64, 9421 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9422 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9423 (i32 vecshiftR64:$imm)))]> { 9424 bits<6> imm; 9425 let Inst{21-16} = imm; 9426 } 9427} 9428 9429multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9430 SDPatternOperator OpNode = null_frag> { 9431 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9432 V64, V64, vecshiftL8, 9433 asm, ".8b", ".8b", 9434 [(set (v8i8 V64:$dst), 9435 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9436 (i32 vecshiftL8:$imm)))]> { 9437 bits<3> imm; 9438 let Inst{18-16} = imm; 9439 } 9440 9441 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9442 V128, V128, vecshiftL8, 9443 asm, ".16b", ".16b", 9444 [(set (v16i8 V128:$dst), 9445 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9446 (i32 vecshiftL8:$imm)))]> { 9447 bits<3> imm; 9448 let Inst{18-16} = imm; 9449 } 9450 9451 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9452 V64, V64, vecshiftL16, 9453 asm, ".4h", ".4h", 9454 [(set (v4i16 V64:$dst), 9455 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9456 (i32 vecshiftL16:$imm)))]> { 9457 bits<4> imm; 9458 let Inst{19-16} = imm; 9459 } 9460 9461 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9462 V128, V128, vecshiftL16, 9463 asm, ".8h", ".8h", 9464 [(set (v8i16 V128:$dst), 9465 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9466 (i32 vecshiftL16:$imm)))]> { 9467 bits<4> imm; 9468 let Inst{19-16} = imm; 9469 } 9470 9471 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9472 V64, V64, vecshiftL32, 9473 asm, ".2s", ".2s", 9474 [(set (v2i32 V64:$dst), 9475 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9476 (i32 vecshiftL32:$imm)))]> { 9477 bits<5> imm; 9478 let Inst{20-16} = imm; 9479 } 9480 9481 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9482 V128, V128, vecshiftL32, 9483 asm, ".4s", ".4s", 9484 [(set (v4i32 V128:$dst), 9485 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9486 (i32 vecshiftL32:$imm)))]> { 9487 bits<5> imm; 9488 let Inst{20-16} = imm; 9489 } 9490 9491 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9492 V128, V128, vecshiftL64, 9493 asm, ".2d", ".2d", 9494 [(set (v2i64 V128:$dst), 9495 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9496 (i32 vecshiftL64:$imm)))]> { 9497 bits<6> imm; 9498 let Inst{21-16} = imm; 9499 } 9500} 9501 9502multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9503 SDPatternOperator OpNode> { 9504 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9505 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9506 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9507 bits<3> imm; 9508 let Inst{18-16} = imm; 9509 } 9510 9511 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9512 V128, V128, vecshiftL8, 9513 asm#"2", ".8h", ".16b", 9514 [(set (v8i16 V128:$Rd), 9515 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9516 bits<3> imm; 9517 let Inst{18-16} = imm; 9518 } 9519 9520 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9521 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9522 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9523 bits<4> imm; 9524 let Inst{19-16} = imm; 9525 } 9526 9527 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9528 V128, V128, vecshiftL16, 9529 asm#"2", ".4s", ".8h", 9530 [(set (v4i32 V128:$Rd), 9531 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9532 9533 bits<4> imm; 9534 let Inst{19-16} = imm; 9535 } 9536 9537 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9538 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9539 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9540 bits<5> imm; 9541 let Inst{20-16} = imm; 9542 } 9543 9544 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9545 V128, V128, vecshiftL32, 9546 asm#"2", ".2d", ".4s", 9547 [(set (v2i64 V128:$Rd), 9548 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9549 bits<5> imm; 9550 let Inst{20-16} = imm; 9551 } 9552} 9553 9554 9555//--- 9556// Vector load/store 9557//--- 9558// SIMD ldX/stX no-index memory references don't allow the optional 9559// ", #0" constant and handle post-indexing explicitly, so we use 9560// a more specialized parse method for them. Otherwise, it's the same as 9561// the general GPR64sp handling. 9562 9563class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9564 string asm, dag oops, dag iops, list<dag> pattern> 9565 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9566 bits<5> Vt; 9567 bits<5> Rn; 9568 let Inst{31} = 0; 9569 let Inst{30} = Q; 9570 let Inst{29-23} = 0b0011000; 9571 let Inst{22} = L; 9572 let Inst{21-16} = 0b000000; 9573 let Inst{15-12} = opcode; 9574 let Inst{11-10} = size; 9575 let Inst{9-5} = Rn; 9576 let Inst{4-0} = Vt; 9577} 9578 9579class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9580 string asm, dag oops, dag iops> 9581 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9582 bits<5> Vt; 9583 bits<5> Rn; 9584 bits<5> Xm; 9585 let Inst{31} = 0; 9586 let Inst{30} = Q; 9587 let Inst{29-23} = 0b0011001; 9588 let Inst{22} = L; 9589 let Inst{21} = 0; 9590 let Inst{20-16} = Xm; 9591 let Inst{15-12} = opcode; 9592 let Inst{11-10} = size; 9593 let Inst{9-5} = Rn; 9594 let Inst{4-0} = Vt; 9595} 9596 9597// The immediate form of AdvSIMD post-indexed addressing is encoded with 9598// register post-index addressing from the zero register. 9599multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9600 int Offset, int Size> { 9601 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9602 // "ld1\t$Vt, [$Rn], #16" 9603 // may get mapped to 9604 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9605 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9606 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9607 GPR64sp:$Rn, 9608 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9609 XZR), 1>; 9610 9611 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9612 // "ld1.8b\t$Vt, [$Rn], #16" 9613 // may get mapped to 9614 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9615 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9616 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9617 GPR64sp:$Rn, 9618 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9619 XZR), 0>; 9620 9621 // E.g. "ld1.8b { v0, v1 }, [x1]" 9622 // "ld1\t$Vt, [$Rn]" 9623 // may get mapped to 9624 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9625 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9626 (!cast<Instruction>(BaseName # Count # "v" # layout) 9627 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9628 GPR64sp:$Rn), 0>; 9629 9630 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9631 // "ld1\t$Vt, [$Rn], $Xm" 9632 // may get mapped to 9633 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9634 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9635 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9636 GPR64sp:$Rn, 9637 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9638 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9639} 9640 9641multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9642 int Offset128, int Offset64, bits<4> opcode> { 9643 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9644 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9645 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9646 (ins GPR64sp:$Rn), []>; 9647 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9648 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9649 (ins GPR64sp:$Rn), []>; 9650 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9651 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9652 (ins GPR64sp:$Rn), []>; 9653 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9654 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9655 (ins GPR64sp:$Rn), []>; 9656 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9657 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9658 (ins GPR64sp:$Rn), []>; 9659 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9660 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9661 (ins GPR64sp:$Rn), []>; 9662 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9663 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9664 (ins GPR64sp:$Rn), []>; 9665 9666 9667 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9668 (outs GPR64sp:$wback, 9669 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9670 (ins GPR64sp:$Rn, 9671 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9672 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9673 (outs GPR64sp:$wback, 9674 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9675 (ins GPR64sp:$Rn, 9676 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9677 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9678 (outs GPR64sp:$wback, 9679 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9680 (ins GPR64sp:$Rn, 9681 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9682 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9683 (outs GPR64sp:$wback, 9684 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9685 (ins GPR64sp:$Rn, 9686 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9687 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9688 (outs GPR64sp:$wback, 9689 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9690 (ins GPR64sp:$Rn, 9691 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9692 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9693 (outs GPR64sp:$wback, 9694 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9695 (ins GPR64sp:$Rn, 9696 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9697 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9698 (outs GPR64sp:$wback, 9699 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9700 (ins GPR64sp:$Rn, 9701 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9702 } 9703 9704 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9705 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9706 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9707 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9708 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9709 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9710 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9711} 9712 9713// Only ld1/st1 has a v1d version. 9714multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9715 int Offset128, int Offset64, bits<4> opcode> { 9716 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9717 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9718 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9719 GPR64sp:$Rn), []>; 9720 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9721 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9722 GPR64sp:$Rn), []>; 9723 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9724 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9725 GPR64sp:$Rn), []>; 9726 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9727 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9728 GPR64sp:$Rn), []>; 9729 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9730 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9731 GPR64sp:$Rn), []>; 9732 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9733 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9734 GPR64sp:$Rn), []>; 9735 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9736 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9737 GPR64sp:$Rn), []>; 9738 9739 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9740 (outs GPR64sp:$wback), 9741 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9742 GPR64sp:$Rn, 9743 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9744 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9745 (outs GPR64sp:$wback), 9746 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9747 GPR64sp:$Rn, 9748 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9749 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9750 (outs GPR64sp:$wback), 9751 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9752 GPR64sp:$Rn, 9753 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9754 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9755 (outs GPR64sp:$wback), 9756 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9757 GPR64sp:$Rn, 9758 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9759 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9760 (outs GPR64sp:$wback), 9761 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9762 GPR64sp:$Rn, 9763 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9764 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9765 (outs GPR64sp:$wback), 9766 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9767 GPR64sp:$Rn, 9768 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9769 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9770 (outs GPR64sp:$wback), 9771 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9772 GPR64sp:$Rn, 9773 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9774 } 9775 9776 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9777 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9778 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9779 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9780 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9781 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9782 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9783} 9784 9785multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9786 int Offset128, int Offset64, bits<4> opcode> 9787 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9788 9789 // LD1 instructions have extra "1d" variants. 9790 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9791 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9792 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9793 (ins GPR64sp:$Rn), []>; 9794 9795 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9796 (outs GPR64sp:$wback, 9797 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9798 (ins GPR64sp:$Rn, 9799 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9800 } 9801 9802 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9803} 9804 9805multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9806 int Offset128, int Offset64, bits<4> opcode> 9807 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9808 9809 // ST1 instructions have extra "1d" variants. 9810 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9811 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9812 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9813 GPR64sp:$Rn), []>; 9814 9815 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9816 (outs GPR64sp:$wback), 9817 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9818 GPR64sp:$Rn, 9819 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9820 } 9821 9822 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9823} 9824 9825multiclass SIMDLd1Multiple<string asm> { 9826 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9827 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9828 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9829 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9830} 9831 9832multiclass SIMDSt1Multiple<string asm> { 9833 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9834 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9835 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9836 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9837} 9838 9839multiclass SIMDLd2Multiple<string asm> { 9840 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9841} 9842 9843multiclass SIMDSt2Multiple<string asm> { 9844 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9845} 9846 9847multiclass SIMDLd3Multiple<string asm> { 9848 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9849} 9850 9851multiclass SIMDSt3Multiple<string asm> { 9852 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9853} 9854 9855multiclass SIMDLd4Multiple<string asm> { 9856 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9857} 9858 9859multiclass SIMDSt4Multiple<string asm> { 9860 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9861} 9862 9863//--- 9864// AdvSIMD Load/store single-element 9865//--- 9866 9867class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9868 string asm, string operands, string cst, 9869 dag oops, dag iops, list<dag> pattern> 9870 : I<oops, iops, asm, operands, cst, pattern> { 9871 bits<5> Vt; 9872 bits<5> Rn; 9873 let Inst{31} = 0; 9874 let Inst{29-24} = 0b001101; 9875 let Inst{22} = L; 9876 let Inst{21} = R; 9877 let Inst{15-13} = opcode; 9878 let Inst{9-5} = Rn; 9879 let Inst{4-0} = Vt; 9880} 9881 9882class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9883 string asm, string operands, string cst, 9884 dag oops, dag iops, list<dag> pattern> 9885 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9886 bits<5> Vt; 9887 bits<5> Rn; 9888 let Inst{31} = 0; 9889 let Inst{29-24} = 0b001101; 9890 let Inst{22} = L; 9891 let Inst{21} = R; 9892 let Inst{15-13} = opcode; 9893 let Inst{9-5} = Rn; 9894 let Inst{4-0} = Vt; 9895} 9896 9897 9898let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9899class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9900 DAGOperand listtype> 9901 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9902 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9903 []> { 9904 let Inst{30} = Q; 9905 let Inst{23} = 0; 9906 let Inst{20-16} = 0b00000; 9907 let Inst{12} = S; 9908 let Inst{11-10} = size; 9909} 9910let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9911class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9912 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9913 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9914 "$Rn = $wback", 9915 (outs GPR64sp:$wback, listtype:$Vt), 9916 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9917 bits<5> Xm; 9918 let Inst{30} = Q; 9919 let Inst{23} = 1; 9920 let Inst{20-16} = Xm; 9921 let Inst{12} = S; 9922 let Inst{11-10} = size; 9923} 9924 9925multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9926 int Offset, int Size> { 9927 // E.g. "ld1r { v0.8b }, [x1], #1" 9928 // "ld1r.8b\t$Vt, [$Rn], #1" 9929 // may get mapped to 9930 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9931 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9932 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9933 GPR64sp:$Rn, 9934 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9935 XZR), 1>; 9936 9937 // E.g. "ld1r.8b { v0 }, [x1], #1" 9938 // "ld1r.8b\t$Vt, [$Rn], #1" 9939 // may get mapped to 9940 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9941 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9942 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9943 GPR64sp:$Rn, 9944 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9945 XZR), 0>; 9946 9947 // E.g. "ld1r.8b { v0 }, [x1]" 9948 // "ld1r.8b\t$Vt, [$Rn]" 9949 // may get mapped to 9950 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9951 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9952 (!cast<Instruction>(BaseName # "v" # layout) 9953 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9954 GPR64sp:$Rn), 0>; 9955 9956 // E.g. "ld1r.8b { v0 }, [x1], x2" 9957 // "ld1r.8b\t$Vt, [$Rn], $Xm" 9958 // may get mapped to 9959 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9960 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9961 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9962 GPR64sp:$Rn, 9963 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9964 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9965} 9966 9967multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 9968 int Offset1, int Offset2, int Offset4, int Offset8> { 9969 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 9970 !cast<DAGOperand>("VecList" # Count # "8b")>; 9971 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 9972 !cast<DAGOperand>("VecList" # Count #"16b")>; 9973 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 9974 !cast<DAGOperand>("VecList" # Count #"4h")>; 9975 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 9976 !cast<DAGOperand>("VecList" # Count #"8h")>; 9977 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 9978 !cast<DAGOperand>("VecList" # Count #"2s")>; 9979 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 9980 !cast<DAGOperand>("VecList" # Count #"4s")>; 9981 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 9982 !cast<DAGOperand>("VecList" # Count #"1d")>; 9983 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 9984 !cast<DAGOperand>("VecList" # Count #"2d")>; 9985 9986 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 9987 !cast<DAGOperand>("VecList" # Count # "8b"), 9988 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9989 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 9990 !cast<DAGOperand>("VecList" # Count # "16b"), 9991 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9992 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 9993 !cast<DAGOperand>("VecList" # Count # "4h"), 9994 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9995 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 9996 !cast<DAGOperand>("VecList" # Count # "8h"), 9997 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9998 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 9999 !cast<DAGOperand>("VecList" # Count # "2s"), 10000 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10001 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10002 !cast<DAGOperand>("VecList" # Count # "4s"), 10003 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10004 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10005 !cast<DAGOperand>("VecList" # Count # "1d"), 10006 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10007 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10008 !cast<DAGOperand>("VecList" # Count # "2d"), 10009 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10010 10011 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10012 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10013 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10014 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10015 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10016 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10017 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10018 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10019} 10020 10021class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10022 dag oops, dag iops, list<dag> pattern> 10023 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10024 pattern> { 10025 // idx encoded in Q:S:size fields. 10026 bits<4> idx; 10027 let Inst{30} = idx{3}; 10028 let Inst{23} = 0; 10029 let Inst{20-16} = 0b00000; 10030 let Inst{12} = idx{2}; 10031 let Inst{11-10} = idx{1-0}; 10032} 10033class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10034 dag oops, dag iops, list<dag> pattern> 10035 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10036 oops, iops, pattern> { 10037 // idx encoded in Q:S:size fields. 10038 bits<4> idx; 10039 let Inst{30} = idx{3}; 10040 let Inst{23} = 0; 10041 let Inst{20-16} = 0b00000; 10042 let Inst{12} = idx{2}; 10043 let Inst{11-10} = idx{1-0}; 10044} 10045class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10046 dag oops, dag iops> 10047 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10048 "$Rn = $wback", oops, iops, []> { 10049 // idx encoded in Q:S:size fields. 10050 bits<4> idx; 10051 bits<5> Xm; 10052 let Inst{30} = idx{3}; 10053 let Inst{23} = 1; 10054 let Inst{20-16} = Xm; 10055 let Inst{12} = idx{2}; 10056 let Inst{11-10} = idx{1-0}; 10057} 10058class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10059 dag oops, dag iops> 10060 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10061 "$Rn = $wback", oops, iops, []> { 10062 // idx encoded in Q:S:size fields. 10063 bits<4> idx; 10064 bits<5> Xm; 10065 let Inst{30} = idx{3}; 10066 let Inst{23} = 1; 10067 let Inst{20-16} = Xm; 10068 let Inst{12} = idx{2}; 10069 let Inst{11-10} = idx{1-0}; 10070} 10071 10072class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10073 dag oops, dag iops, list<dag> pattern> 10074 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10075 pattern> { 10076 // idx encoded in Q:S:size<1> fields. 10077 bits<3> idx; 10078 let Inst{30} = idx{2}; 10079 let Inst{23} = 0; 10080 let Inst{20-16} = 0b00000; 10081 let Inst{12} = idx{1}; 10082 let Inst{11} = idx{0}; 10083 let Inst{10} = size; 10084} 10085class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10086 dag oops, dag iops, list<dag> pattern> 10087 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10088 oops, iops, pattern> { 10089 // idx encoded in Q:S:size<1> fields. 10090 bits<3> idx; 10091 let Inst{30} = idx{2}; 10092 let Inst{23} = 0; 10093 let Inst{20-16} = 0b00000; 10094 let Inst{12} = idx{1}; 10095 let Inst{11} = idx{0}; 10096 let Inst{10} = size; 10097} 10098 10099class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10100 dag oops, dag iops> 10101 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10102 "$Rn = $wback", oops, iops, []> { 10103 // idx encoded in Q:S:size<1> fields. 10104 bits<3> idx; 10105 bits<5> Xm; 10106 let Inst{30} = idx{2}; 10107 let Inst{23} = 1; 10108 let Inst{20-16} = Xm; 10109 let Inst{12} = idx{1}; 10110 let Inst{11} = idx{0}; 10111 let Inst{10} = size; 10112} 10113class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10114 dag oops, dag iops> 10115 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10116 "$Rn = $wback", oops, iops, []> { 10117 // idx encoded in Q:S:size<1> fields. 10118 bits<3> idx; 10119 bits<5> Xm; 10120 let Inst{30} = idx{2}; 10121 let Inst{23} = 1; 10122 let Inst{20-16} = Xm; 10123 let Inst{12} = idx{1}; 10124 let Inst{11} = idx{0}; 10125 let Inst{10} = size; 10126} 10127class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10128 dag oops, dag iops, list<dag> pattern> 10129 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10130 pattern> { 10131 // idx encoded in Q:S fields. 10132 bits<2> idx; 10133 let Inst{30} = idx{1}; 10134 let Inst{23} = 0; 10135 let Inst{20-16} = 0b00000; 10136 let Inst{12} = idx{0}; 10137 let Inst{11-10} = size; 10138} 10139class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10140 dag oops, dag iops, list<dag> pattern> 10141 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10142 oops, iops, pattern> { 10143 // idx encoded in Q:S fields. 10144 bits<2> idx; 10145 let Inst{30} = idx{1}; 10146 let Inst{23} = 0; 10147 let Inst{20-16} = 0b00000; 10148 let Inst{12} = idx{0}; 10149 let Inst{11-10} = size; 10150} 10151class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10152 string asm, dag oops, dag iops> 10153 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10154 "$Rn = $wback", oops, iops, []> { 10155 // idx encoded in Q:S fields. 10156 bits<2> idx; 10157 bits<5> Xm; 10158 let Inst{30} = idx{1}; 10159 let Inst{23} = 1; 10160 let Inst{20-16} = Xm; 10161 let Inst{12} = idx{0}; 10162 let Inst{11-10} = size; 10163} 10164class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10165 string asm, dag oops, dag iops> 10166 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10167 "$Rn = $wback", oops, iops, []> { 10168 // idx encoded in Q:S fields. 10169 bits<2> idx; 10170 bits<5> Xm; 10171 let Inst{30} = idx{1}; 10172 let Inst{23} = 1; 10173 let Inst{20-16} = Xm; 10174 let Inst{12} = idx{0}; 10175 let Inst{11-10} = size; 10176} 10177class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10178 dag oops, dag iops, list<dag> pattern> 10179 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10180 pattern> { 10181 // idx encoded in Q field. 10182 bits<1> idx; 10183 let Inst{30} = idx; 10184 let Inst{23} = 0; 10185 let Inst{20-16} = 0b00000; 10186 let Inst{12} = 0; 10187 let Inst{11-10} = size; 10188} 10189class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10190 dag oops, dag iops, list<dag> pattern> 10191 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10192 oops, iops, pattern> { 10193 // idx encoded in Q field. 10194 bits<1> idx; 10195 let Inst{30} = idx; 10196 let Inst{23} = 0; 10197 let Inst{20-16} = 0b00000; 10198 let Inst{12} = 0; 10199 let Inst{11-10} = size; 10200} 10201class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10202 string asm, dag oops, dag iops> 10203 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10204 "$Rn = $wback", oops, iops, []> { 10205 // idx encoded in Q field. 10206 bits<1> idx; 10207 bits<5> Xm; 10208 let Inst{30} = idx; 10209 let Inst{23} = 1; 10210 let Inst{20-16} = Xm; 10211 let Inst{12} = 0; 10212 let Inst{11-10} = size; 10213} 10214class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10215 string asm, dag oops, dag iops> 10216 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10217 "$Rn = $wback", oops, iops, []> { 10218 // idx encoded in Q field. 10219 bits<1> idx; 10220 bits<5> Xm; 10221 let Inst{30} = idx; 10222 let Inst{23} = 1; 10223 let Inst{20-16} = Xm; 10224 let Inst{12} = 0; 10225 let Inst{11-10} = size; 10226} 10227 10228let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10229multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10230 RegisterOperand listtype, 10231 RegisterOperand GPR64pi> { 10232 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10233 (outs listtype:$dst), 10234 (ins listtype:$Vt, VectorIndexB:$idx, 10235 GPR64sp:$Rn), []>; 10236 10237 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10238 (outs GPR64sp:$wback, listtype:$dst), 10239 (ins listtype:$Vt, VectorIndexB:$idx, 10240 GPR64sp:$Rn, GPR64pi:$Xm)>; 10241} 10242let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10243multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10244 RegisterOperand listtype, 10245 RegisterOperand GPR64pi> { 10246 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10247 (outs listtype:$dst), 10248 (ins listtype:$Vt, VectorIndexH:$idx, 10249 GPR64sp:$Rn), []>; 10250 10251 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10252 (outs GPR64sp:$wback, listtype:$dst), 10253 (ins listtype:$Vt, VectorIndexH:$idx, 10254 GPR64sp:$Rn, GPR64pi:$Xm)>; 10255} 10256let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10257multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10258 RegisterOperand listtype, 10259 RegisterOperand GPR64pi> { 10260 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10261 (outs listtype:$dst), 10262 (ins listtype:$Vt, VectorIndexS:$idx, 10263 GPR64sp:$Rn), []>; 10264 10265 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10266 (outs GPR64sp:$wback, listtype:$dst), 10267 (ins listtype:$Vt, VectorIndexS:$idx, 10268 GPR64sp:$Rn, GPR64pi:$Xm)>; 10269} 10270let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10271multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10272 RegisterOperand listtype, RegisterOperand GPR64pi> { 10273 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10274 (outs listtype:$dst), 10275 (ins listtype:$Vt, VectorIndexD:$idx, 10276 GPR64sp:$Rn), []>; 10277 10278 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10279 (outs GPR64sp:$wback, listtype:$dst), 10280 (ins listtype:$Vt, VectorIndexD:$idx, 10281 GPR64sp:$Rn, GPR64pi:$Xm)>; 10282} 10283let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10284multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10285 RegisterOperand listtype, RegisterOperand GPR64pi> { 10286 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10287 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10288 GPR64sp:$Rn), []>; 10289 10290 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10291 (outs GPR64sp:$wback), 10292 (ins listtype:$Vt, VectorIndexB:$idx, 10293 GPR64sp:$Rn, GPR64pi:$Xm)>; 10294} 10295let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10296multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10297 RegisterOperand listtype, RegisterOperand GPR64pi> { 10298 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10299 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10300 GPR64sp:$Rn), []>; 10301 10302 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10303 (outs GPR64sp:$wback), 10304 (ins listtype:$Vt, VectorIndexH:$idx, 10305 GPR64sp:$Rn, GPR64pi:$Xm)>; 10306} 10307let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10308multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10309 RegisterOperand listtype, RegisterOperand GPR64pi> { 10310 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10311 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10312 GPR64sp:$Rn), []>; 10313 10314 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10315 (outs GPR64sp:$wback), 10316 (ins listtype:$Vt, VectorIndexS:$idx, 10317 GPR64sp:$Rn, GPR64pi:$Xm)>; 10318} 10319let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10320multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10321 RegisterOperand listtype, RegisterOperand GPR64pi> { 10322 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10323 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10324 GPR64sp:$Rn), []>; 10325 10326 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10327 (outs GPR64sp:$wback), 10328 (ins listtype:$Vt, VectorIndexD:$idx, 10329 GPR64sp:$Rn, GPR64pi:$Xm)>; 10330} 10331 10332multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10333 string Count, int Offset, Operand idxtype> { 10334 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10335 // "ld1\t$Vt, [$Rn], #1" 10336 // may get mapped to 10337 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10338 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10339 (!cast<Instruction>(NAME # Type # "_POST") 10340 GPR64sp:$Rn, 10341 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10342 idxtype:$idx, XZR), 1>; 10343 10344 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10345 // "ld1.8b\t$Vt, [$Rn], #1" 10346 // may get mapped to 10347 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10348 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10349 (!cast<Instruction>(NAME # Type # "_POST") 10350 GPR64sp:$Rn, 10351 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10352 idxtype:$idx, XZR), 0>; 10353 10354 // E.g. "ld1.8b { v0 }[0], [x1]" 10355 // "ld1.8b\t$Vt, [$Rn]" 10356 // may get mapped to 10357 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10358 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10359 (!cast<Instruction>(NAME # Type) 10360 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10361 idxtype:$idx, GPR64sp:$Rn), 0>; 10362 10363 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10364 // "ld1.8b\t$Vt, [$Rn], $Xm" 10365 // may get mapped to 10366 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10367 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10368 (!cast<Instruction>(NAME # Type # "_POST") 10369 GPR64sp:$Rn, 10370 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10371 idxtype:$idx, 10372 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10373} 10374 10375multiclass SIMDLdSt1SingleAliases<string asm> { 10376 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10377 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10378 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10379 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10380} 10381 10382multiclass SIMDLdSt2SingleAliases<string asm> { 10383 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10384 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10385 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10386 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10387} 10388 10389multiclass SIMDLdSt3SingleAliases<string asm> { 10390 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10391 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10392 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10393 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10394} 10395 10396multiclass SIMDLdSt4SingleAliases<string asm> { 10397 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10398 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10399 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10400 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10401} 10402} // end of 'let Predicates = [HasNEON]' 10403 10404//---------------------------------------------------------------------------- 10405// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10406//---------------------------------------------------------------------------- 10407 10408let Predicates = [HasNEON, HasRDM] in { 10409 10410class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10411 RegisterOperand regtype, string asm, 10412 string kind, list<dag> pattern> 10413 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10414 pattern> { 10415} 10416multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10417 SDPatternOperator Accum> { 10418 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10419 [(set (v4i16 V64:$dst), 10420 (Accum (v4i16 V64:$Rd), 10421 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 10422 (v4i16 V64:$Rm)))))]>; 10423 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10424 [(set (v8i16 V128:$dst), 10425 (Accum (v8i16 V128:$Rd), 10426 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 10427 (v8i16 V128:$Rm)))))]>; 10428 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10429 [(set (v2i32 V64:$dst), 10430 (Accum (v2i32 V64:$Rd), 10431 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 10432 (v2i32 V64:$Rm)))))]>; 10433 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10434 [(set (v4i32 V128:$dst), 10435 (Accum (v4i32 V128:$Rd), 10436 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 10437 (v4i32 V128:$Rm)))))]>; 10438} 10439 10440multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10441 SDPatternOperator Accum> { 10442 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10443 V64, V64, V128_lo, VectorIndexH, 10444 asm, ".4h", ".4h", ".4h", ".h", 10445 [(set (v4i16 V64:$dst), 10446 (Accum (v4i16 V64:$Rd), 10447 (v4i16 (int_aarch64_neon_sqrdmulh 10448 (v4i16 V64:$Rn), 10449 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10450 VectorIndexH:$idx))))))]> { 10451 bits<3> idx; 10452 let Inst{11} = idx{2}; 10453 let Inst{21} = idx{1}; 10454 let Inst{20} = idx{0}; 10455 } 10456 10457 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10458 V128, V128, V128_lo, VectorIndexH, 10459 asm, ".8h", ".8h", ".8h", ".h", 10460 [(set (v8i16 V128:$dst), 10461 (Accum (v8i16 V128:$Rd), 10462 (v8i16 (int_aarch64_neon_sqrdmulh 10463 (v8i16 V128:$Rn), 10464 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10465 VectorIndexH:$idx))))))]> { 10466 bits<3> idx; 10467 let Inst{11} = idx{2}; 10468 let Inst{21} = idx{1}; 10469 let Inst{20} = idx{0}; 10470 } 10471 10472 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10473 V64, V64, V128, VectorIndexS, 10474 asm, ".2s", ".2s", ".2s", ".s", 10475 [(set (v2i32 V64:$dst), 10476 (Accum (v2i32 V64:$Rd), 10477 (v2i32 (int_aarch64_neon_sqrdmulh 10478 (v2i32 V64:$Rn), 10479 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10480 VectorIndexS:$idx))))))]> { 10481 bits<2> idx; 10482 let Inst{11} = idx{1}; 10483 let Inst{21} = idx{0}; 10484 } 10485 10486 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10487 // an intermediate EXTRACT_SUBREG would be untyped. 10488 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 10489 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 10490 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10491 (i32 (vector_extract 10492 (v4i32 (insert_subvector 10493 (undef), 10494 (v2i32 (int_aarch64_neon_sqrdmulh 10495 (v2i32 V64:$Rn), 10496 (v2i32 (AArch64duplane32 10497 (v4i32 V128:$Rm), 10498 VectorIndexS:$idx)))), 10499 (i32 0))), 10500 (i64 0))))), 10501 (EXTRACT_SUBREG 10502 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 10503 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 10504 FPR32Op:$Rd, 10505 ssub)), 10506 V64:$Rn, 10507 V128:$Rm, 10508 VectorIndexS:$idx)), 10509 ssub)>; 10510 10511 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10512 V128, V128, V128, VectorIndexS, 10513 asm, ".4s", ".4s", ".4s", ".s", 10514 [(set (v4i32 V128:$dst), 10515 (Accum (v4i32 V128:$Rd), 10516 (v4i32 (int_aarch64_neon_sqrdmulh 10517 (v4i32 V128:$Rn), 10518 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10519 VectorIndexS:$idx))))))]> { 10520 bits<2> idx; 10521 let Inst{11} = idx{1}; 10522 let Inst{21} = idx{0}; 10523 } 10524 10525 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10526 // an intermediate EXTRACT_SUBREG would be untyped. 10527 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10528 (i32 (vector_extract 10529 (v4i32 (int_aarch64_neon_sqrdmulh 10530 (v4i32 V128:$Rn), 10531 (v4i32 (AArch64duplane32 10532 (v4i32 V128:$Rm), 10533 VectorIndexS:$idx)))), 10534 (i64 0))))), 10535 (EXTRACT_SUBREG 10536 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 10537 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 10538 FPR32Op:$Rd, 10539 ssub)), 10540 V128:$Rn, 10541 V128:$Rm, 10542 VectorIndexS:$idx)), 10543 ssub)>; 10544 10545 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10546 FPR16Op, FPR16Op, V128_lo, 10547 VectorIndexH, asm, ".h", "", "", ".h", 10548 []> { 10549 bits<3> idx; 10550 let Inst{11} = idx{2}; 10551 let Inst{21} = idx{1}; 10552 let Inst{20} = idx{0}; 10553 } 10554 10555 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10556 FPR32Op, FPR32Op, V128, VectorIndexS, 10557 asm, ".s", "", "", ".s", 10558 [(set (i32 FPR32Op:$dst), 10559 (Accum (i32 FPR32Op:$Rd), 10560 (i32 (int_aarch64_neon_sqrdmulh 10561 (i32 FPR32Op:$Rn), 10562 (i32 (vector_extract (v4i32 V128:$Rm), 10563 VectorIndexS:$idx))))))]> { 10564 bits<2> idx; 10565 let Inst{11} = idx{1}; 10566 let Inst{21} = idx{0}; 10567 } 10568} 10569} // let Predicates = [HasNeon, HasRDM] 10570 10571//---------------------------------------------------------------------------- 10572// ARMv8.3 Complex ADD/MLA instructions 10573//---------------------------------------------------------------------------- 10574 10575class ComplexRotationOperand<int Angle, int Remainder, string Type> 10576 : AsmOperandClass { 10577 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10578 let DiagnosticType = "InvalidComplexRotation" # Type; 10579 let Name = "ComplexRotation" # Type; 10580} 10581def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10582 SDNodeXForm<imm, [{ 10583 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10584}]>> { 10585 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10586 let PrintMethod = "printComplexRotationOp<90, 0>"; 10587} 10588def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10589 SDNodeXForm<imm, [{ 10590 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10591}]>> { 10592 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10593 let PrintMethod = "printComplexRotationOp<180, 90>"; 10594} 10595let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10596class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10597 RegisterOperand regtype, Operand rottype, 10598 string asm, string kind, list<dag> pattern> 10599 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10600 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10601 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10602 Sched<[WriteV]> { 10603 bits<5> Rd; 10604 bits<5> Rn; 10605 bits<5> Rm; 10606 bits<1> rot; 10607 let Inst{31} = 0; 10608 let Inst{30} = Q; 10609 let Inst{29} = U; 10610 let Inst{28-24} = 0b01110; 10611 let Inst{23-22} = size; 10612 let Inst{21} = 0; 10613 let Inst{20-16} = Rm; 10614 let Inst{15-13} = opcode; 10615 // Non-tied version (FCADD) only has one rotation bit 10616 let Inst{12} = rot; 10617 let Inst{11} = 0; 10618 let Inst{10} = 1; 10619 let Inst{9-5} = Rn; 10620 let Inst{4-0} = Rd; 10621} 10622 10623//8.3 CompNum - Floating-point complex number support 10624multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10625 string asm, SDPatternOperator OpNode>{ 10626 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10627 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10628 asm, ".4h", 10629 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10630 (v4f16 V64:$Rn), 10631 (v4f16 V64:$Rm), 10632 (i32 rottype:$rot)))]>; 10633 10634 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10635 asm, ".8h", 10636 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10637 (v8f16 V128:$Rn), 10638 (v8f16 V128:$Rm), 10639 (i32 rottype:$rot)))]>; 10640 } 10641 10642 let Predicates = [HasComplxNum, HasNEON] in { 10643 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10644 asm, ".2s", 10645 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10646 (v2f32 V64:$Rn), 10647 (v2f32 V64:$Rm), 10648 (i32 rottype:$rot)))]>; 10649 10650 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10651 asm, ".4s", 10652 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10653 (v4f32 V128:$Rn), 10654 (v4f32 V128:$Rm), 10655 (i32 rottype:$rot)))]>; 10656 10657 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10658 asm, ".2d", 10659 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10660 (v2f64 V128:$Rn), 10661 (v2f64 V128:$Rm), 10662 (i32 rottype:$rot)))]>; 10663 } 10664} 10665 10666let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10667class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10668 bits<3> opcode, 10669 RegisterOperand regtype, 10670 Operand rottype, string asm, 10671 string kind, list<dag> pattern> 10672 : I<(outs regtype:$dst), 10673 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10674 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10675 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10676 Sched<[WriteV]> { 10677 bits<5> Rd; 10678 bits<5> Rn; 10679 bits<5> Rm; 10680 bits<2> rot; 10681 let Inst{31} = 0; 10682 let Inst{30} = Q; 10683 let Inst{29} = U; 10684 let Inst{28-24} = 0b01110; 10685 let Inst{23-22} = size; 10686 let Inst{21} = 0; 10687 let Inst{20-16} = Rm; 10688 let Inst{15-13} = opcode; 10689 let Inst{12-11} = rot; 10690 let Inst{10} = 1; 10691 let Inst{9-5} = Rn; 10692 let Inst{4-0} = Rd; 10693} 10694 10695multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10696 Operand rottype, string asm, 10697 SDPatternOperator OpNode> { 10698 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10699 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10700 rottype, asm, ".4h", 10701 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10702 (v4f16 V64:$Rn), 10703 (v4f16 V64:$Rm), 10704 (i32 rottype:$rot)))]>; 10705 10706 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10707 rottype, asm, ".8h", 10708 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10709 (v8f16 V128:$Rn), 10710 (v8f16 V128:$Rm), 10711 (i32 rottype:$rot)))]>; 10712 } 10713 10714 let Predicates = [HasComplxNum, HasNEON] in { 10715 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10716 rottype, asm, ".2s", 10717 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10718 (v2f32 V64:$Rn), 10719 (v2f32 V64:$Rm), 10720 (i32 rottype:$rot)))]>; 10721 10722 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10723 rottype, asm, ".4s", 10724 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10725 (v4f32 V128:$Rn), 10726 (v4f32 V128:$Rm), 10727 (i32 rottype:$rot)))]>; 10728 10729 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10730 rottype, asm, ".2d", 10731 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10732 (v2f64 V128:$Rn), 10733 (v2f64 V128:$Rm), 10734 (i32 rottype:$rot)))]>; 10735 } 10736} 10737 10738let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10739class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10740 bit opc1, bit opc2, RegisterOperand dst_reg, 10741 RegisterOperand lhs_reg, 10742 RegisterOperand rhs_reg, Operand vec_idx, 10743 Operand rottype, string asm, string apple_kind, 10744 string dst_kind, string lhs_kind, 10745 string rhs_kind, list<dag> pattern> 10746 : I<(outs dst_reg:$dst), 10747 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10748 asm, 10749 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10750 "$idx, $rot" # "|" # apple_kind # 10751 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10752 Sched<[WriteV]> { 10753 bits<5> Rd; 10754 bits<5> Rn; 10755 bits<5> Rm; 10756 bits<2> rot; 10757 10758 let Inst{31} = 0; 10759 let Inst{30} = Q; 10760 let Inst{29} = U; 10761 let Inst{28} = Scalar; 10762 let Inst{27-24} = 0b1111; 10763 let Inst{23-22} = size; 10764 // Bit 21 must be set by the derived class. 10765 let Inst{20-16} = Rm; 10766 let Inst{15} = opc1; 10767 let Inst{14-13} = rot; 10768 let Inst{12} = opc2; 10769 // Bit 11 must be set by the derived class. 10770 let Inst{10} = 0; 10771 let Inst{9-5} = Rn; 10772 let Inst{4-0} = Rd; 10773} 10774 10775// The complex instructions index by pairs of elements, so the VectorIndexes 10776// don't match the lane types, and the index bits are different to the other 10777// classes. 10778multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10779 string asm, SDPatternOperator OpNode> { 10780 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10781 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10782 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10783 ".4h", ".h", []> { 10784 bits<1> idx; 10785 let Inst{11} = 0; 10786 let Inst{21} = idx{0}; 10787 } 10788 10789 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10790 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10791 ".8h", ".8h", ".h", []> { 10792 bits<2> idx; 10793 let Inst{11} = idx{1}; 10794 let Inst{21} = idx{0}; 10795 } 10796 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10797 10798 let Predicates = [HasComplxNum, HasNEON] in { 10799 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10800 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10801 ".4s", ".4s", ".s", []> { 10802 bits<1> idx; 10803 let Inst{11} = idx{0}; 10804 let Inst{21} = 0; 10805 } 10806 } // Predicates = [HasComplxNum, HasNEON] 10807} 10808 10809//---------------------------------------------------------------------------- 10810// Crypto extensions 10811//---------------------------------------------------------------------------- 10812 10813let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10814class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10815 list<dag> pat> 10816 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10817 Sched<[WriteV]>{ 10818 bits<5> Rd; 10819 bits<5> Rn; 10820 let Inst{31-16} = 0b0100111000101000; 10821 let Inst{15-12} = opc; 10822 let Inst{11-10} = 0b10; 10823 let Inst{9-5} = Rn; 10824 let Inst{4-0} = Rd; 10825} 10826 10827class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10828 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10829 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10830 10831class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10832 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10833 "$Rd = $dst", 10834 [(set (v16i8 V128:$dst), 10835 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10836 10837let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10838class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10839 dag oops, dag iops, list<dag> pat> 10840 : I<oops, iops, asm, 10841 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10842 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10843 Sched<[WriteV]>{ 10844 bits<5> Rd; 10845 bits<5> Rn; 10846 bits<5> Rm; 10847 let Inst{31-21} = 0b01011110000; 10848 let Inst{20-16} = Rm; 10849 let Inst{15} = 0; 10850 let Inst{14-12} = opc; 10851 let Inst{11-10} = 0b00; 10852 let Inst{9-5} = Rn; 10853 let Inst{4-0} = Rd; 10854} 10855 10856class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10857 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10858 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10859 [(set (v4i32 FPR128:$dst), 10860 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10861 (v4i32 V128:$Rm)))]>; 10862 10863class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10864 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10865 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10866 [(set (v4i32 V128:$dst), 10867 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10868 (v4i32 V128:$Rm)))]>; 10869 10870class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10871 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10872 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10873 [(set (v4i32 FPR128:$dst), 10874 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10875 (v4i32 V128:$Rm)))]>; 10876 10877let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10878class SHA2OpInst<bits<4> opc, string asm, string kind, 10879 string cstr, dag oops, dag iops, 10880 list<dag> pat> 10881 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10882 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10883 Sched<[WriteV]>{ 10884 bits<5> Rd; 10885 bits<5> Rn; 10886 let Inst{31-16} = 0b0101111000101000; 10887 let Inst{15-12} = opc; 10888 let Inst{11-10} = 0b10; 10889 let Inst{9-5} = Rn; 10890 let Inst{4-0} = Rd; 10891} 10892 10893class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10894 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10895 (ins V128:$Rd, V128:$Rn), 10896 [(set (v4i32 V128:$dst), 10897 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10898 10899class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10900 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10901 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10902 10903// Armv8.2-A Crypto extensions 10904class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10905 list<dag> pattern> 10906 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10907 bits<5> Vd; 10908 bits<5> Vn; 10909 let Inst{31-25} = 0b1100111; 10910 let Inst{9-5} = Vn; 10911 let Inst{4-0} = Vd; 10912} 10913 10914class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10915 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops, 10916 "$Vm = $Vd", []> { 10917 let Inst{31-25} = 0b1100111; 10918 let Inst{24-21} = 0b0110; 10919 let Inst{20-15} = 0b000001; 10920 let Inst{14} = op0; 10921 let Inst{13-12} = 0b00; 10922 let Inst{11-10} = op1; 10923} 10924class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10925 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 10926class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10927 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 10928 10929class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10930 string asmops, string cst> 10931 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10932 bits<5> Vm; 10933 let Inst{24-21} = 0b0011; 10934 let Inst{20-16} = Vm; 10935 let Inst{15} = 0b1; 10936 let Inst{14} = op0; 10937 let Inst{13-12} = 0b00; 10938 let Inst{11-10} = op1; 10939} 10940class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10941 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10942 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 10943class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10944 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10945 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10946class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10947 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10948 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 10949class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10950 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10951 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10952class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 10953 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 10954 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10955 10956class CryptoRRRR<bits<2>op0, string asm, string asmops> 10957 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 10958 asmops, "", []> { 10959 bits<5> Vm; 10960 bits<5> Va; 10961 let Inst{24-23} = 0b00; 10962 let Inst{22-21} = op0; 10963 let Inst{20-16} = Vm; 10964 let Inst{15} = 0b0; 10965 let Inst{14-10} = Va; 10966} 10967class CryptoRRRR_16B<bits<2>op0, string asm> 10968 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 10969 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 10970} 10971class CryptoRRRR_4S<bits<2>op0, string asm> 10972 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 10973 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 10974} 10975 10976class CryptoRRRi6<string asm> 10977 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 10978 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 10979 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 10980 bits<6> imm; 10981 bits<5> Vm; 10982 let Inst{24-21} = 0b0100; 10983 let Inst{20-16} = Vm; 10984 let Inst{15-10} = imm; 10985 let Inst{9-5} = Vn; 10986 let Inst{4-0} = Vd; 10987} 10988 10989class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 10990 : BaseCryptoV82<(outs V128:$Vdst), 10991 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 10992 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 10993 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 10994 bits<2> imm; 10995 bits<5> Vm; 10996 let Inst{24-21} = 0b0010; 10997 let Inst{20-16} = Vm; 10998 let Inst{15} = 0b1; 10999 let Inst{14} = op0; 11000 let Inst{13-12} = imm; 11001 let Inst{11-10} = op1; 11002} 11003 11004//---------------------------------------------------------------------------- 11005// v8.1 atomic instructions extension: 11006// * CAS 11007// * CASP 11008// * SWP 11009// * LDOPregister<OP>, and aliases STOPregister<OP> 11010 11011// Instruction encodings: 11012// 11013// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11014// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11015// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11016// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11017// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11018// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11019 11020// Instruction syntax: 11021// 11022// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11023// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11024// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11025// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11026// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11027// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11028// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11029// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11030// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11031// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11032 11033let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11034class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11035 string cstr, list<dag> pattern> 11036 : I<oops, iops, asm, operands, cstr, pattern> { 11037 bits<2> Sz; 11038 bit NP; 11039 bit Acq; 11040 bit Rel; 11041 bits<5> Rs; 11042 bits<5> Rn; 11043 bits<5> Rt; 11044 let Inst{31-30} = Sz; 11045 let Inst{29-24} = 0b001000; 11046 let Inst{23} = NP; 11047 let Inst{22} = Acq; 11048 let Inst{21} = 0b1; 11049 let Inst{20-16} = Rs; 11050 let Inst{15} = Rel; 11051 let Inst{14-10} = 0b11111; 11052 let Inst{9-5} = Rn; 11053 let Inst{4-0} = Rt; 11054 let Predicates = [HasLSE]; 11055} 11056 11057class BaseCAS<string order, string size, RegisterClass RC> 11058 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11059 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11060 "$out = $Rs",[]>, 11061 Sched<[WriteAtomic]> { 11062 let NP = 1; 11063} 11064 11065multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11066 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11067 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11068 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11069 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11070} 11071 11072class BaseCASP<string order, string size, RegisterOperand RC> 11073 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11074 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11075 "$out = $Rs",[]>, 11076 Sched<[WriteAtomic]> { 11077 let NP = 0; 11078} 11079 11080multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11081 let Sz = 0b00, Acq = Acq, Rel = Rel in 11082 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11083 let Sz = 0b01, Acq = Acq, Rel = Rel in 11084 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11085} 11086 11087let Predicates = [HasLSE] in 11088class BaseSWP<string order, string size, RegisterClass RC> 11089 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11090 "\t$Rs, $Rt, [$Rn]","",[]>, 11091 Sched<[WriteAtomic]> { 11092 bits<2> Sz; 11093 bit Acq; 11094 bit Rel; 11095 bits<5> Rs; 11096 bits<3> opc = 0b000; 11097 bits<5> Rn; 11098 bits<5> Rt; 11099 let Inst{31-30} = Sz; 11100 let Inst{29-24} = 0b111000; 11101 let Inst{23} = Acq; 11102 let Inst{22} = Rel; 11103 let Inst{21} = 0b1; 11104 let Inst{20-16} = Rs; 11105 let Inst{15} = 0b1; 11106 let Inst{14-12} = opc; 11107 let Inst{11-10} = 0b00; 11108 let Inst{9-5} = Rn; 11109 let Inst{4-0} = Rt; 11110 let Predicates = [HasLSE]; 11111} 11112 11113multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11114 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11115 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11116 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11117 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11118} 11119 11120let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11121class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11122 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11123 "\t$Rs, $Rt, [$Rn]","",[]>, 11124 Sched<[WriteAtomic]> { 11125 bits<2> Sz; 11126 bit Acq; 11127 bit Rel; 11128 bits<5> Rs; 11129 bits<3> opc; 11130 bits<5> Rn; 11131 bits<5> Rt; 11132 let Inst{31-30} = Sz; 11133 let Inst{29-24} = 0b111000; 11134 let Inst{23} = Acq; 11135 let Inst{22} = Rel; 11136 let Inst{21} = 0b1; 11137 let Inst{20-16} = Rs; 11138 let Inst{15} = 0b0; 11139 let Inst{14-12} = opc; 11140 let Inst{11-10} = 0b00; 11141 let Inst{9-5} = Rn; 11142 let Inst{4-0} = Rt; 11143 let Predicates = [HasLSE]; 11144} 11145 11146multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11147 string order> { 11148 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11149 def B : BaseLDOPregister<op, order, "b", GPR32>; 11150 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11151 def H : BaseLDOPregister<op, order, "h", GPR32>; 11152 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11153 def W : BaseLDOPregister<op, order, "", GPR32>; 11154 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11155 def X : BaseLDOPregister<op, order, "", GPR64>; 11156} 11157 11158// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11159// complex DAG for DstRHS. 11160let Predicates = [HasLSE] in 11161multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11162 string size, dag SrcRHS, dag DstRHS> { 11163 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11164 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11165 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11166 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11167 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11168 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11169 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11170 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11171 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11172 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11173} 11174 11175multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11176 string size, dag RHS> { 11177 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11178} 11179 11180multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11181 string size, dag LHS, dag RHS> { 11182 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11183} 11184 11185multiclass LDOPregister_patterns<string inst, string op> { 11186 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11187 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11188 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11189 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11190} 11191 11192multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11193 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11194 (i64 GPR64:$Rm), 11195 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11196 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11197 (i32 GPR32:$Rm), 11198 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11199 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11200 (i32 GPR32:$Rm), 11201 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11202 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11203 (i32 GPR32:$Rm), 11204 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11205} 11206 11207let Predicates = [HasLSE] in 11208multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11209 string size, dag OLD, dag NEW> { 11210 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11211 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11212 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11213 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11214 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11215 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11216 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11217 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11218 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11219 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11220} 11221 11222multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11223 string size, dag OLD, dag NEW> { 11224 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11225} 11226 11227multiclass CASregister_patterns<string inst, string op> { 11228 defm : CASregister_patterns_ord<inst, "X", op, "64", 11229 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11230 defm : CASregister_patterns_ord<inst, "W", op, "32", 11231 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11232 defm : CASregister_patterns_ord<inst, "H", op, "16", 11233 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11234 defm : CASregister_patterns_ord<inst, "B", op, "8", 11235 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11236} 11237 11238let Predicates = [HasLSE] in 11239class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11240 Instruction inst> : 11241 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11242 11243multiclass STOPregister<string asm, string instr> { 11244 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11245 !cast<Instruction>(instr # "LB")>; 11246 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11247 !cast<Instruction>(instr # "LH")>; 11248 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11249 !cast<Instruction>(instr # "LW")>; 11250 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11251 !cast<Instruction>(instr # "LX")>; 11252 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11253 !cast<Instruction>(instr # "B")>; 11254 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11255 !cast<Instruction>(instr # "H")>; 11256 def : BaseSTOPregister<asm, GPR32, WZR, 11257 !cast<Instruction>(instr # "W")>; 11258 def : BaseSTOPregister<asm, GPR64, XZR, 11259 !cast<Instruction>(instr # "X")>; 11260} 11261 11262class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11263 dag iops, dag oops, list<dag> pat> 11264 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11265 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11266 bits<5> Rt; 11267 bits<5> Rn; 11268 let Inst{31-21} = 0b11111000001; 11269 let Inst{15} = 1; 11270 let Inst{14-12} = opc; 11271 let Inst{11-10} = 0b00; 11272 let Inst{9-5} = Rn; 11273 let Inst{4-0} = Rt; 11274 11275 let Predicates = [HasV8_7a]; 11276} 11277 11278class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11279 list<dag> pat = []> 11280 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11281 let Inst{20-16} = 0b11111; 11282} 11283 11284class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11285 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11286 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11287 bits<5> Rs; 11288 let Inst{20-16} = Rs; 11289} 11290 11291//---------------------------------------------------------------------------- 11292// Allow the size specifier tokens to be upper case, not just lower. 11293def : TokenAlias<".4B", ".4b">; // Add dot product 11294def : TokenAlias<".8B", ".8b">; 11295def : TokenAlias<".4H", ".4h">; 11296def : TokenAlias<".2S", ".2s">; 11297def : TokenAlias<".1D", ".1d">; 11298def : TokenAlias<".16B", ".16b">; 11299def : TokenAlias<".8H", ".8h">; 11300def : TokenAlias<".4S", ".4s">; 11301def : TokenAlias<".2D", ".2d">; 11302def : TokenAlias<".1Q", ".1q">; 11303def : TokenAlias<".2H", ".2h">; 11304def : TokenAlias<".B", ".b">; 11305def : TokenAlias<".H", ".h">; 11306def : TokenAlias<".S", ".s">; 11307def : TokenAlias<".D", ".d">; 11308def : TokenAlias<".Q", ".q">; 11309