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 FalseLanesEnum FalseLanes = FalseLanesNone; 64 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 65 ElementSizeEnum ElementSize = ElementSizeNone; 66 67 let TSFlags{8-7} = FalseLanes.Value; 68 let TSFlags{6-3} = DestructiveInstType.Value; 69 let TSFlags{2-0} = ElementSize.Value; 70 71 let Pattern = []; 72 let Constraints = cstr; 73} 74 75class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 76 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 77 78// Pseudo instructions (don't have encoding information) 79class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 80 : AArch64Inst<PseudoFrm, cstr> { 81 dag OutOperandList = oops; 82 dag InOperandList = iops; 83 let Pattern = pattern; 84 let isCodeGenOnly = 1; 85 let isPseudo = 1; 86} 87 88// Real instructions (have encoding information) 89class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 90 let Pattern = pattern; 91 let Size = 4; 92} 93 94// Normal instructions 95class I<dag oops, dag iops, string asm, string operands, string cstr, 96 list<dag> pattern> 97 : EncodedI<cstr, pattern> { 98 dag OutOperandList = oops; 99 dag InOperandList = iops; 100 let AsmString = !strconcat(asm, operands); 101} 102 103class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 104class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 105class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 106 107// Helper fragment for an extract of the high portion of a 128-bit vector. 108def extract_high_v16i8 : 109 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>; 110def extract_high_v8i16 : 111 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>; 112def extract_high_v4i32 : 113 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>; 114def extract_high_v2i64 : 115 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>; 116 117//===----------------------------------------------------------------------===// 118// Asm Operand Classes. 119// 120 121// Shifter operand for arithmetic shifted encodings. 122def ShifterOperand : AsmOperandClass { 123 let Name = "Shifter"; 124} 125 126// Shifter operand for mov immediate encodings. 127def MovImm32ShifterOperand : AsmOperandClass { 128 let SuperClasses = [ShifterOperand]; 129 let Name = "MovImm32Shifter"; 130 let RenderMethod = "addShifterOperands"; 131 let DiagnosticType = "InvalidMovImm32Shift"; 132} 133def MovImm64ShifterOperand : AsmOperandClass { 134 let SuperClasses = [ShifterOperand]; 135 let Name = "MovImm64Shifter"; 136 let RenderMethod = "addShifterOperands"; 137 let DiagnosticType = "InvalidMovImm64Shift"; 138} 139 140// Shifter operand for arithmetic register shifted encodings. 141class ArithmeticShifterOperand<int width> : AsmOperandClass { 142 let SuperClasses = [ShifterOperand]; 143 let Name = "ArithmeticShifter" # width; 144 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 145 let RenderMethod = "addShifterOperands"; 146 let DiagnosticType = "AddSubRegShift" # width; 147} 148 149def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 150def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 151 152// Shifter operand for logical register shifted encodings. 153class LogicalShifterOperand<int width> : AsmOperandClass { 154 let SuperClasses = [ShifterOperand]; 155 let Name = "LogicalShifter" # width; 156 let PredicateMethod = "isLogicalShifter<" # width # ">"; 157 let RenderMethod = "addShifterOperands"; 158 let DiagnosticType = "AddSubRegShift" # width; 159} 160 161def LogicalShifterOperand32 : LogicalShifterOperand<32>; 162def LogicalShifterOperand64 : LogicalShifterOperand<64>; 163 164// Shifter operand for logical vector 128/64-bit shifted encodings. 165def LogicalVecShifterOperand : AsmOperandClass { 166 let SuperClasses = [ShifterOperand]; 167 let Name = "LogicalVecShifter"; 168 let RenderMethod = "addShifterOperands"; 169} 170def LogicalVecHalfWordShifterOperand : AsmOperandClass { 171 let SuperClasses = [LogicalVecShifterOperand]; 172 let Name = "LogicalVecHalfWordShifter"; 173 let RenderMethod = "addShifterOperands"; 174} 175 176// The "MSL" shifter on the vector MOVI instruction. 177def MoveVecShifterOperand : AsmOperandClass { 178 let SuperClasses = [ShifterOperand]; 179 let Name = "MoveVecShifter"; 180 let RenderMethod = "addShifterOperands"; 181} 182 183// Extend operand for arithmetic encodings. 184def ExtendOperand : AsmOperandClass { 185 let Name = "Extend"; 186 let DiagnosticType = "AddSubRegExtendLarge"; 187} 188def ExtendOperand64 : AsmOperandClass { 189 let SuperClasses = [ExtendOperand]; 190 let Name = "Extend64"; 191 let DiagnosticType = "AddSubRegExtendSmall"; 192} 193// 'extend' that's a lsl of a 64-bit register. 194def ExtendOperandLSL64 : AsmOperandClass { 195 let SuperClasses = [ExtendOperand]; 196 let Name = "ExtendLSL64"; 197 let RenderMethod = "addExtend64Operands"; 198 let DiagnosticType = "AddSubRegExtendLarge"; 199} 200 201// 8-bit floating-point immediate encodings. 202def FPImmOperand : AsmOperandClass { 203 let Name = "FPImm"; 204 let ParserMethod = "tryParseFPImm<true>"; 205 let DiagnosticType = "InvalidFPImm"; 206} 207 208def CondCode : AsmOperandClass { 209 let Name = "CondCode"; 210 let DiagnosticType = "InvalidCondCode"; 211} 212 213// A 32-bit register pasrsed as 64-bit 214def GPR32as64Operand : AsmOperandClass { 215 let Name = "GPR32as64"; 216 let ParserMethod = 217 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 218} 219def GPR32as64 : RegisterOperand<GPR32> { 220 let ParserMatchClass = GPR32as64Operand; 221} 222 223// A 64-bit register pasrsed as 32-bit 224def GPR64as32Operand : AsmOperandClass { 225 let Name = "GPR64as32"; 226 let ParserMethod = 227 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 228} 229def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 230 let ParserMatchClass = GPR64as32Operand; 231} 232 233// 8-bit immediate for AdvSIMD where 64-bit values of the form: 234// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 235// are encoded as the eight bit value 'abcdefgh'. 236def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 237 238class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 239 let Name = "UImm" # Width # "s" # Scale; 240 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 241 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 242 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 243} 244 245class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 246 let Name = "SImm" # Width # "s" # Scale; 247 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 248 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 249 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 250} 251 252//===----------------------------------------------------------------------===// 253// Operand Definitions. 254// 255 256// ADR[P] instruction labels. 257def AdrpOperand : AsmOperandClass { 258 let Name = "AdrpLabel"; 259 let ParserMethod = "tryParseAdrpLabel"; 260 let DiagnosticType = "InvalidLabel"; 261} 262def adrplabel : Operand<i64> { 263 let EncoderMethod = "getAdrLabelOpValue"; 264 let PrintMethod = "printAdrpLabel"; 265 let ParserMatchClass = AdrpOperand; 266} 267 268def AdrOperand : AsmOperandClass { 269 let Name = "AdrLabel"; 270 let ParserMethod = "tryParseAdrLabel"; 271 let DiagnosticType = "InvalidLabel"; 272} 273def adrlabel : Operand<i64> { 274 let EncoderMethod = "getAdrLabelOpValue"; 275 let ParserMatchClass = AdrOperand; 276} 277 278class SImmOperand<int width> : AsmOperandClass { 279 let Name = "SImm" # width; 280 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 281 let RenderMethod = "addImmOperands"; 282 let PredicateMethod = "isSImm<" # width # ">"; 283} 284 285 286class AsmImmRange<int Low, int High> : AsmOperandClass { 287 let Name = "Imm" # Low # "_" # High; 288 let DiagnosticType = "InvalidImm" # Low # "_" # High; 289 let RenderMethod = "addImmOperands"; 290 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 291} 292 293// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 294def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 295def simm10Scaled : Operand<i64> { 296 let ParserMatchClass = SImm10s8Operand; 297 let DecoderMethod = "DecodeSImm<10>"; 298 let PrintMethod = "printImmScale<8>"; 299} 300 301def simm9s16 : Operand<i64> { 302 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 303 let DecoderMethod = "DecodeSImm<9>"; 304 let PrintMethod = "printImmScale<16>"; 305} 306 307// uimm6 predicate - True if the immediate is in the range [0, 63]. 308def UImm6Operand : AsmOperandClass { 309 let Name = "UImm6"; 310 let DiagnosticType = "InvalidImm0_63"; 311} 312 313def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 314 let ParserMatchClass = UImm6Operand; 315} 316 317def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 318 let ParserMatchClass = AsmImmRange<0, 65535>; 319} 320 321def SImm9Operand : SImmOperand<9>; 322def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 323 let ParserMatchClass = SImm9Operand; 324 let DecoderMethod = "DecodeSImm<9>"; 325} 326 327def SImm8Operand : SImmOperand<8>; 328def simm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 127; }]> { 329 let ParserMatchClass = SImm8Operand; 330 let DecoderMethod = "DecodeSImm<8>"; 331} 332 333def SImm6Operand : SImmOperand<6>; 334def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 335 let ParserMatchClass = SImm6Operand; 336 let DecoderMethod = "DecodeSImm<6>"; 337} 338 339def SImm5Operand : SImmOperand<5>; 340def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 341 let ParserMatchClass = SImm5Operand; 342 let DecoderMethod = "DecodeSImm<5>"; 343} 344 345def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 346 let ParserMatchClass = SImm5Operand; 347 let DecoderMethod = "DecodeSImm<5>"; 348} 349 350def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 351 let ParserMatchClass = SImm5Operand; 352 let DecoderMethod = "DecodeSImm<5>"; 353 let PrintMethod = "printSImm<8>"; 354} 355 356def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 357 let ParserMatchClass = SImm5Operand; 358 let DecoderMethod = "DecodeSImm<5>"; 359 let PrintMethod = "printSImm<16>"; 360} 361 362// simm7sN predicate - True if the immediate is a multiple of N in the range 363// [-64 * N, 63 * N]. 364 365def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 366def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 367def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 368 369def simm7s4 : Operand<i32> { 370 let ParserMatchClass = SImm7s4Operand; 371 let PrintMethod = "printImmScale<4>"; 372} 373 374def simm7s8 : Operand<i32> { 375 let ParserMatchClass = SImm7s8Operand; 376 let PrintMethod = "printImmScale<8>"; 377} 378 379def simm7s16 : Operand<i32> { 380 let ParserMatchClass = SImm7s16Operand; 381 let PrintMethod = "printImmScale<16>"; 382} 383 384def am_sve_fi : ComplexPattern<i64, 2, "SelectAddrModeFrameIndexSVE", []>; 385 386def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>; 387def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>; 388def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>; 389def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>; 390def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>; 391 392def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>; 393def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>; 394 395def UImmS1XForm : SDNodeXForm<imm, [{ 396 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 397}]>; 398def UImmS2XForm : SDNodeXForm<imm, [{ 399 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 400}]>; 401def UImmS4XForm : SDNodeXForm<imm, [{ 402 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 403}]>; 404def UImmS8XForm : SDNodeXForm<imm, [{ 405 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 406}]>; 407 408// uimm5sN predicate - True if the immediate is a multiple of N in the range 409// [0 * N, 32 * N]. 410def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 411def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 412def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 413 414def uimm5s2 : Operand<i64>, ImmLeaf<i64, 415 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 416 UImmS2XForm> { 417 let ParserMatchClass = UImm5s2Operand; 418 let PrintMethod = "printImmScale<2>"; 419} 420def uimm5s4 : Operand<i64>, ImmLeaf<i64, 421 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 422 UImmS4XForm> { 423 let ParserMatchClass = UImm5s4Operand; 424 let PrintMethod = "printImmScale<4>"; 425} 426def uimm5s8 : Operand<i64>, ImmLeaf<i64, 427 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 428 UImmS8XForm> { 429 let ParserMatchClass = UImm5s8Operand; 430 let PrintMethod = "printImmScale<8>"; 431} 432 433// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 434// instead of ImmLeaf (Constant) 435def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 436 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 437 UImmS2XForm> { 438 let ParserMatchClass = UImm5s2Operand; 439 let PrintMethod = "printImmScale<2>"; 440} 441def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 442 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 443 UImmS4XForm> { 444 let ParserMatchClass = UImm5s4Operand; 445 let PrintMethod = "printImmScale<4>"; 446} 447def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 448 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 449 UImmS8XForm> { 450 let ParserMatchClass = UImm5s8Operand; 451 let PrintMethod = "printImmScale<8>"; 452} 453 454// uimm6sN predicate - True if the immediate is a multiple of N in the range 455// [0 * N, 64 * N]. 456def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 457def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 458def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 459def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 460def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 461 462def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 463 let ParserMatchClass = UImm6s1Operand; 464} 465def uimm6s2 : Operand<i64>, ImmLeaf<i64, 466[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 467 let PrintMethod = "printImmScale<2>"; 468 let ParserMatchClass = UImm6s2Operand; 469} 470def uimm6s4 : Operand<i64>, ImmLeaf<i64, 471[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 472 let PrintMethod = "printImmScale<4>"; 473 let ParserMatchClass = UImm6s4Operand; 474} 475def uimm6s8 : Operand<i64>, ImmLeaf<i64, 476[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 477 let PrintMethod = "printImmScale<8>"; 478 let ParserMatchClass = UImm6s8Operand; 479} 480def uimm6s16 : Operand<i64>, ImmLeaf<i64, 481[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 482 let PrintMethod = "printImmScale<16>"; 483 let ParserMatchClass = UImm6s16Operand; 484} 485 486def SImmS2XForm : SDNodeXForm<imm, [{ 487 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 488}]>; 489def SImmS3XForm : SDNodeXForm<imm, [{ 490 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 491}]>; 492def SImmS4XForm : SDNodeXForm<imm, [{ 493 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 494}]>; 495def SImmS16XForm : SDNodeXForm<imm, [{ 496 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 497}]>; 498def SImmS32XForm : SDNodeXForm<imm, [{ 499 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 500}]>; 501 502// simm6sN predicate - True if the immediate is a multiple of N in the range 503// [-32 * N, 31 * N]. 504def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 505def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 506 let ParserMatchClass = SImm6s1Operand; 507 let DecoderMethod = "DecodeSImm<6>"; 508} 509 510// simm4sN predicate - True if the immediate is a multiple of N in the range 511// [ -8* N, 7 * N]. 512def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 513def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 514def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 515def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 516def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 517def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 518 519def simm4s1 : Operand<i64>, ImmLeaf<i64, 520[{ return Imm >=-8 && Imm <= 7; }]> { 521 let ParserMatchClass = SImm4s1Operand; 522 let DecoderMethod = "DecodeSImm<4>"; 523} 524 525def simm4s2 : Operand<i64>, ImmLeaf<i64, 526[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 527 let PrintMethod = "printImmScale<2>"; 528 let ParserMatchClass = SImm4s2Operand; 529 let DecoderMethod = "DecodeSImm<4>"; 530} 531 532def simm4s3 : Operand<i64>, ImmLeaf<i64, 533[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 534 let PrintMethod = "printImmScale<3>"; 535 let ParserMatchClass = SImm4s3Operand; 536 let DecoderMethod = "DecodeSImm<4>"; 537} 538 539def simm4s4 : Operand<i64>, ImmLeaf<i64, 540[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 541 let PrintMethod = "printImmScale<4>"; 542 let ParserMatchClass = SImm4s4Operand; 543 let DecoderMethod = "DecodeSImm<4>"; 544} 545def simm4s16 : Operand<i64>, ImmLeaf<i64, 546[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 547 let PrintMethod = "printImmScale<16>"; 548 let ParserMatchClass = SImm4s16Operand; 549 let DecoderMethod = "DecodeSImm<4>"; 550} 551def simm4s32 : Operand<i64>, ImmLeaf<i64, 552[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 553 let PrintMethod = "printImmScale<32>"; 554 let ParserMatchClass = SImm4s32Operand; 555 let DecoderMethod = "DecodeSImm<4>"; 556} 557 558def Imm1_8Operand : AsmImmRange<1, 8>; 559def Imm1_16Operand : AsmImmRange<1, 16>; 560def Imm1_32Operand : AsmImmRange<1, 32>; 561def Imm1_64Operand : AsmImmRange<1, 64>; 562 563class BranchTarget<int N> : AsmOperandClass { 564 let Name = "BranchTarget" # N; 565 let DiagnosticType = "InvalidLabel"; 566 let PredicateMethod = "isBranchTarget<" # N # ">"; 567} 568 569class PCRelLabel<int N> : BranchTarget<N> { 570 let Name = "PCRelLabel" # N; 571} 572 573def BranchTarget14Operand : BranchTarget<14>; 574def BranchTarget26Operand : BranchTarget<26>; 575def PCRelLabel19Operand : PCRelLabel<19>; 576 577def MovWSymbolG3AsmOperand : AsmOperandClass { 578 let Name = "MovWSymbolG3"; 579 let RenderMethod = "addImmOperands"; 580} 581 582def movw_symbol_g3 : Operand<i32> { 583 let ParserMatchClass = MovWSymbolG3AsmOperand; 584} 585 586def MovWSymbolG2AsmOperand : AsmOperandClass { 587 let Name = "MovWSymbolG2"; 588 let RenderMethod = "addImmOperands"; 589} 590 591def movw_symbol_g2 : Operand<i32> { 592 let ParserMatchClass = MovWSymbolG2AsmOperand; 593} 594 595def MovWSymbolG1AsmOperand : AsmOperandClass { 596 let Name = "MovWSymbolG1"; 597 let RenderMethod = "addImmOperands"; 598} 599 600def movw_symbol_g1 : Operand<i32> { 601 let ParserMatchClass = MovWSymbolG1AsmOperand; 602} 603 604def MovWSymbolG0AsmOperand : AsmOperandClass { 605 let Name = "MovWSymbolG0"; 606 let RenderMethod = "addImmOperands"; 607} 608 609def movw_symbol_g0 : Operand<i32> { 610 let ParserMatchClass = MovWSymbolG0AsmOperand; 611} 612 613class fixedpoint_i32<ValueType FloatVT> 614 : Operand<FloatVT>, 615 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 616 let EncoderMethod = "getFixedPointScaleOpValue"; 617 let DecoderMethod = "DecodeFixedPointScaleImm32"; 618 let ParserMatchClass = Imm1_32Operand; 619} 620 621class fixedpoint_i64<ValueType FloatVT> 622 : Operand<FloatVT>, 623 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 624 let EncoderMethod = "getFixedPointScaleOpValue"; 625 let DecoderMethod = "DecodeFixedPointScaleImm64"; 626 let ParserMatchClass = Imm1_64Operand; 627} 628 629def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 630def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 631def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 632 633def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 634def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 635def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 636 637def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 638 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 639}]> { 640 let EncoderMethod = "getVecShiftR8OpValue"; 641 let DecoderMethod = "DecodeVecShiftR8Imm"; 642 let ParserMatchClass = Imm1_8Operand; 643} 644def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 645 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 646}]> { 647 let EncoderMethod = "getVecShiftR16OpValue"; 648 let DecoderMethod = "DecodeVecShiftR16Imm"; 649 let ParserMatchClass = Imm1_16Operand; 650} 651def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 652 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 653}]> { 654 let EncoderMethod = "getVecShiftR16OpValue"; 655 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 656 let ParserMatchClass = Imm1_8Operand; 657} 658def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 659 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 660}]> { 661 let EncoderMethod = "getVecShiftR32OpValue"; 662 let DecoderMethod = "DecodeVecShiftR32Imm"; 663 let ParserMatchClass = Imm1_32Operand; 664} 665def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 666 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 667}]> { 668 let EncoderMethod = "getVecShiftR32OpValue"; 669 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 670 let ParserMatchClass = Imm1_16Operand; 671} 672def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 673 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 674}]> { 675 let EncoderMethod = "getVecShiftR64OpValue"; 676 let DecoderMethod = "DecodeVecShiftR64Imm"; 677 let ParserMatchClass = Imm1_64Operand; 678} 679def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 680 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 681}]> { 682 let EncoderMethod = "getVecShiftR64OpValue"; 683 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 684 let ParserMatchClass = Imm1_32Operand; 685} 686 687// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 688// (ImmLeaf) 689def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 690 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 691}]> { 692 let EncoderMethod = "getVecShiftR8OpValue"; 693 let DecoderMethod = "DecodeVecShiftR8Imm"; 694 let ParserMatchClass = Imm1_8Operand; 695} 696def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 697 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 698}]> { 699 let EncoderMethod = "getVecShiftR16OpValue"; 700 let DecoderMethod = "DecodeVecShiftR16Imm"; 701 let ParserMatchClass = Imm1_16Operand; 702} 703def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 704 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 705}]> { 706 let EncoderMethod = "getVecShiftR32OpValue"; 707 let DecoderMethod = "DecodeVecShiftR32Imm"; 708 let ParserMatchClass = Imm1_32Operand; 709} 710def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 711 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 712}]> { 713 let EncoderMethod = "getVecShiftR64OpValue"; 714 let DecoderMethod = "DecodeVecShiftR64Imm"; 715 let ParserMatchClass = Imm1_64Operand; 716} 717 718def Imm0_1Operand : AsmImmRange<0, 1>; 719def Imm0_7Operand : AsmImmRange<0, 7>; 720def Imm0_15Operand : AsmImmRange<0, 15>; 721def Imm0_31Operand : AsmImmRange<0, 31>; 722def Imm0_63Operand : AsmImmRange<0, 63>; 723 724def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 725 return (((uint32_t)Imm) < 8); 726}]> { 727 let EncoderMethod = "getVecShiftL8OpValue"; 728 let DecoderMethod = "DecodeVecShiftL8Imm"; 729 let ParserMatchClass = Imm0_7Operand; 730} 731def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 732 return (((uint32_t)Imm) < 16); 733}]> { 734 let EncoderMethod = "getVecShiftL16OpValue"; 735 let DecoderMethod = "DecodeVecShiftL16Imm"; 736 let ParserMatchClass = Imm0_15Operand; 737} 738def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 739 return (((uint32_t)Imm) < 32); 740}]> { 741 let EncoderMethod = "getVecShiftL32OpValue"; 742 let DecoderMethod = "DecodeVecShiftL32Imm"; 743 let ParserMatchClass = Imm0_31Operand; 744} 745def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 746 return (((uint32_t)Imm) < 64); 747}]> { 748 let EncoderMethod = "getVecShiftL64OpValue"; 749 let DecoderMethod = "DecodeVecShiftL64Imm"; 750 let ParserMatchClass = Imm0_63Operand; 751} 752 753// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 754// (ImmLeaf) 755def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 756 return (((uint32_t)Imm) < 8); 757}]> { 758 let EncoderMethod = "getVecShiftL8OpValue"; 759 let DecoderMethod = "DecodeVecShiftL8Imm"; 760 let ParserMatchClass = Imm0_7Operand; 761} 762def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 763 return (((uint32_t)Imm) < 16); 764}]> { 765 let EncoderMethod = "getVecShiftL16OpValue"; 766 let DecoderMethod = "DecodeVecShiftL16Imm"; 767 let ParserMatchClass = Imm0_15Operand; 768} 769def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 770 return (((uint32_t)Imm) < 32); 771}]> { 772 let EncoderMethod = "getVecShiftL32OpValue"; 773 let DecoderMethod = "DecodeVecShiftL32Imm"; 774 let ParserMatchClass = Imm0_31Operand; 775} 776def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 777 return (((uint32_t)Imm) < 64); 778}]> { 779 let EncoderMethod = "getVecShiftL64OpValue"; 780 let DecoderMethod = "DecodeVecShiftL64Imm"; 781 let ParserMatchClass = Imm0_63Operand; 782} 783 784// Crazy immediate formats used by 32-bit and 64-bit logical immediate 785// instructions for splatting repeating bit patterns across the immediate. 786def logical_imm32_XFORM : SDNodeXForm<imm, [{ 787 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 788 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 789}]>; 790def logical_imm64_XFORM : SDNodeXForm<imm, [{ 791 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 792 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 793}]>; 794 795def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 796 GISDNodeXFormEquiv<logical_imm32_XFORM>; 797def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 798 GISDNodeXFormEquiv<logical_imm64_XFORM>; 799 800let DiagnosticType = "LogicalSecondSource" in { 801 def LogicalImm32Operand : AsmOperandClass { 802 let Name = "LogicalImm32"; 803 let PredicateMethod = "isLogicalImm<int32_t>"; 804 let RenderMethod = "addLogicalImmOperands<int32_t>"; 805 } 806 def LogicalImm64Operand : AsmOperandClass { 807 let Name = "LogicalImm64"; 808 let PredicateMethod = "isLogicalImm<int64_t>"; 809 let RenderMethod = "addLogicalImmOperands<int64_t>"; 810 } 811 def LogicalImm32NotOperand : AsmOperandClass { 812 let Name = "LogicalImm32Not"; 813 let PredicateMethod = "isLogicalImm<int32_t>"; 814 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 815 } 816 def LogicalImm64NotOperand : AsmOperandClass { 817 let Name = "LogicalImm64Not"; 818 let PredicateMethod = "isLogicalImm<int64_t>"; 819 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 820 } 821} 822def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 823 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 824}], logical_imm32_XFORM> { 825 let PrintMethod = "printLogicalImm<int32_t>"; 826 let ParserMatchClass = LogicalImm32Operand; 827} 828def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 829 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 830}], logical_imm64_XFORM> { 831 let PrintMethod = "printLogicalImm<int64_t>"; 832 let ParserMatchClass = LogicalImm64Operand; 833} 834def logical_imm32_not : Operand<i32> { 835 let ParserMatchClass = LogicalImm32NotOperand; 836} 837def logical_imm64_not : Operand<i64> { 838 let ParserMatchClass = LogicalImm64NotOperand; 839} 840 841// iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535]. 842let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 843def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{ 844 return ((uint32_t)Imm) < 65536; 845}]>; 846 847def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{ 848 return ((uint64_t)Imm) < 65536; 849}]>; 850} 851 852// imm0_255 predicate - True if the immediate is in the range [0,255]. 853def Imm0_255Operand : AsmImmRange<0,255>; 854 855def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 856 return ((uint32_t)Imm) < 256; 857}]> { 858 let ParserMatchClass = Imm0_255Operand; 859 let PrintMethod = "printImm"; 860} 861 862// imm0_127 predicate - True if the immediate is in the range [0,127] 863def Imm0_127Operand : AsmImmRange<0, 127>; 864def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 865 return ((uint32_t)Imm) < 128; 866}]> { 867 let ParserMatchClass = Imm0_127Operand; 868 let PrintMethod = "printImm"; 869} 870 871def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 872 return ((uint64_t)Imm) < 128; 873}]> { 874 let ParserMatchClass = Imm0_127Operand; 875 let PrintMethod = "printImm"; 876} 877 878// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 879// for all shift-amounts. 880 881// imm0_63 predicate - True if the immediate is in the range [0,63] 882def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 883 return ((uint64_t)Imm) < 64; 884}]> { 885 let ParserMatchClass = Imm0_63Operand; 886} 887 888// imm0_31 predicate - True if the immediate is in the range [0,31] 889def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 890 return ((uint64_t)Imm) < 32; 891}]> { 892 let ParserMatchClass = Imm0_31Operand; 893} 894 895// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 896// instead of Constant (ImmLeaf) 897def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 898 return ((uint64_t)Imm) < 32; 899}]> { 900 let ParserMatchClass = Imm0_31Operand; 901} 902 903// True if the 32-bit immediate is in the range [0,31] 904def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 905 return ((uint64_t)Imm) < 32; 906}]> { 907 let ParserMatchClass = Imm0_31Operand; 908} 909 910// imm0_1 predicate - True if the immediate is in the range [0,1] 911def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 912 return ((uint64_t)Imm) < 2; 913}]> { 914 let ParserMatchClass = Imm0_1Operand; 915} 916 917// timm0_1 - as above, but use TargetConstant (TImmLeaf) 918def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 919 return ((uint64_t)Imm) < 2; 920}]> { 921 let ParserMatchClass = Imm0_1Operand; 922} 923 924// imm0_15 predicate - True if the immediate is in the range [0,15] 925def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 926 return ((uint64_t)Imm) < 16; 927}]> { 928 let ParserMatchClass = Imm0_15Operand; 929} 930 931// imm0_7 predicate - True if the immediate is in the range [0,7] 932def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 933 return ((uint64_t)Imm) < 8; 934}]> { 935 let ParserMatchClass = Imm0_7Operand; 936} 937 938// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 939def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 940 return ((uint32_t)Imm) < 8; 941}]> { 942 let ParserMatchClass = Imm0_7Operand; 943} 944 945// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 946def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 947 return ((uint32_t)Imm) < 16; 948}]> { 949 let ParserMatchClass = Imm0_15Operand; 950} 951 952// An arithmetic shifter operand: 953// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 954// {5-0} - imm6 955class arith_shift<ValueType Ty, int width> : Operand<Ty> { 956 let PrintMethod = "printShifter"; 957 let ParserMatchClass = !cast<AsmOperandClass>( 958 "ArithmeticShifterOperand" # width); 959} 960 961def arith_shift32 : arith_shift<i32, 32>; 962def arith_shift64 : arith_shift<i64, 64>; 963 964class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 965 : Operand<Ty>, 966 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 967 let PrintMethod = "printShiftedRegister"; 968 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 969} 970 971def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 972def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 973 974def gi_arith_shifted_reg32 : 975 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 976 GIComplexPatternEquiv<arith_shifted_reg32>; 977 978def gi_arith_shifted_reg64 : 979 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 980 GIComplexPatternEquiv<arith_shifted_reg64>; 981 982// An arithmetic shifter operand: 983// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 984// {5-0} - imm6 985class logical_shift<int width> : Operand<i32> { 986 let PrintMethod = "printShifter"; 987 let ParserMatchClass = !cast<AsmOperandClass>( 988 "LogicalShifterOperand" # width); 989} 990 991def logical_shift32 : logical_shift<32>; 992def logical_shift64 : logical_shift<64>; 993 994class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 995 : Operand<Ty>, 996 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 997 let PrintMethod = "printShiftedRegister"; 998 let MIOperandInfo = (ops regclass, shiftop); 999} 1000 1001def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1002def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1003 1004def gi_logical_shifted_reg32 : 1005 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1006 GIComplexPatternEquiv<logical_shifted_reg32>; 1007 1008def gi_logical_shifted_reg64 : 1009 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1010 GIComplexPatternEquiv<logical_shifted_reg64>; 1011 1012// A logical vector shifter operand: 1013// {7-6} - shift type: 00 = lsl 1014// {5-0} - imm6: #0, #8, #16, or #24 1015def logical_vec_shift : Operand<i32> { 1016 let PrintMethod = "printShifter"; 1017 let EncoderMethod = "getVecShifterOpValue"; 1018 let ParserMatchClass = LogicalVecShifterOperand; 1019} 1020 1021// A logical vector half-word shifter operand: 1022// {7-6} - shift type: 00 = lsl 1023// {5-0} - imm6: #0 or #8 1024def logical_vec_hw_shift : Operand<i32> { 1025 let PrintMethod = "printShifter"; 1026 let EncoderMethod = "getVecShifterOpValue"; 1027 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1028} 1029 1030// A vector move shifter operand: 1031// {0} - imm1: #8 or #16 1032def move_vec_shift : Operand<i32> { 1033 let PrintMethod = "printShifter"; 1034 let EncoderMethod = "getMoveVecShifterOpValue"; 1035 let ParserMatchClass = MoveVecShifterOperand; 1036} 1037 1038let DiagnosticType = "AddSubSecondSource" in { 1039 def AddSubImmOperand : AsmOperandClass { 1040 let Name = "AddSubImm"; 1041 let ParserMethod = "tryParseImmWithOptionalShift"; 1042 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1043 } 1044 def AddSubImmNegOperand : AsmOperandClass { 1045 let Name = "AddSubImmNeg"; 1046 let ParserMethod = "tryParseImmWithOptionalShift"; 1047 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1048 } 1049} 1050// An ADD/SUB immediate shifter operand: 1051// second operand: 1052// {7-6} - shift type: 00 = lsl 1053// {5-0} - imm6: #0 or #12 1054class addsub_shifted_imm<ValueType Ty> 1055 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1056 let PrintMethod = "printAddSubImm"; 1057 let EncoderMethod = "getAddSubImmOpValue"; 1058 let ParserMatchClass = AddSubImmOperand; 1059 let MIOperandInfo = (ops i32imm, i32imm); 1060} 1061 1062class addsub_shifted_imm_neg<ValueType Ty> 1063 : Operand<Ty> { 1064 let EncoderMethod = "getAddSubImmOpValue"; 1065 let ParserMatchClass = AddSubImmNegOperand; 1066 let MIOperandInfo = (ops i32imm, i32imm); 1067} 1068 1069def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1070def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1071def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1072def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1073 1074def gi_addsub_shifted_imm32 : 1075 GIComplexOperandMatcher<s32, "selectArithImmed">, 1076 GIComplexPatternEquiv<addsub_shifted_imm32>; 1077 1078def gi_addsub_shifted_imm64 : 1079 GIComplexOperandMatcher<s64, "selectArithImmed">, 1080 GIComplexPatternEquiv<addsub_shifted_imm64>; 1081 1082class neg_addsub_shifted_imm<ValueType Ty> 1083 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1084 let PrintMethod = "printAddSubImm"; 1085 let EncoderMethod = "getAddSubImmOpValue"; 1086 let ParserMatchClass = AddSubImmOperand; 1087 let MIOperandInfo = (ops i32imm, i32imm); 1088} 1089 1090def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1091def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1092 1093def gi_neg_addsub_shifted_imm32 : 1094 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1095 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1096 1097def gi_neg_addsub_shifted_imm64 : 1098 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1099 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1100 1101// An extend operand: 1102// {5-3} - extend type 1103// {2-0} - imm3 1104def arith_extend : Operand<i32> { 1105 let PrintMethod = "printArithExtend"; 1106 let ParserMatchClass = ExtendOperand; 1107} 1108def arith_extend64 : Operand<i32> { 1109 let PrintMethod = "printArithExtend"; 1110 let ParserMatchClass = ExtendOperand64; 1111} 1112 1113// 'extend' that's a lsl of a 64-bit register. 1114def arith_extendlsl64 : Operand<i32> { 1115 let PrintMethod = "printArithExtend"; 1116 let ParserMatchClass = ExtendOperandLSL64; 1117} 1118 1119class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1120 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1121 let PrintMethod = "printExtendedRegister"; 1122 let MIOperandInfo = (ops GPR32, arith_extend); 1123} 1124 1125class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1126 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1127 let PrintMethod = "printExtendedRegister"; 1128 let MIOperandInfo = (ops GPR32, arith_extend64); 1129} 1130 1131def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1132def gi_arith_extended_reg32_i32 : 1133 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1134 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1135 1136def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1137def gi_arith_extended_reg32_i64 : 1138 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1139 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1140 1141def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1142def gi_arith_extended_reg32to64_i64 : 1143 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1144 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1145 1146// Floating-point immediate. 1147def fpimm16 : Operand<f16>, 1148 FPImmLeaf<f16, [{ 1149 return AArch64_AM::getFP16Imm(Imm) != -1; 1150 }], SDNodeXForm<fpimm, [{ 1151 APFloat InVal = N->getValueAPF(); 1152 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1153 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1154 }]>> { 1155 let ParserMatchClass = FPImmOperand; 1156 let PrintMethod = "printFPImmOperand"; 1157} 1158def fpimm32 : Operand<f32>, 1159 FPImmLeaf<f32, [{ 1160 return AArch64_AM::getFP32Imm(Imm) != -1; 1161 }], SDNodeXForm<fpimm, [{ 1162 APFloat InVal = N->getValueAPF(); 1163 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1164 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1165 }]>> { 1166 let ParserMatchClass = FPImmOperand; 1167 let PrintMethod = "printFPImmOperand"; 1168} 1169def fpimm64 : Operand<f64>, 1170 FPImmLeaf<f64, [{ 1171 return AArch64_AM::getFP64Imm(Imm) != -1; 1172 }], SDNodeXForm<fpimm, [{ 1173 APFloat InVal = N->getValueAPF(); 1174 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1175 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1176 }]>> { 1177 let ParserMatchClass = FPImmOperand; 1178 let PrintMethod = "printFPImmOperand"; 1179} 1180 1181def fpimm8 : Operand<i32> { 1182 let ParserMatchClass = FPImmOperand; 1183 let PrintMethod = "printFPImmOperand"; 1184} 1185 1186def fpimm0 : FPImmLeaf<fAny, [{ 1187 return Imm.isExactlyValue(+0.0); 1188}]>; 1189 1190// Vector lane operands 1191class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1192 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1193 let DiagnosticType = "Invalid" # Name; 1194 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1195 let RenderMethod = "addVectorIndexOperands"; 1196} 1197 1198class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1199 : Operand<ty> { 1200 let ParserMatchClass = mc; 1201 let PrintMethod = "printVectorIndex"; 1202} 1203 1204multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1205 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1206 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1207} 1208 1209def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1210def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1211def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1212def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1213def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1214 1215defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1216 [{ return ((uint64_t)Imm) == 1; }]>; 1217defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1218 [{ return ((uint64_t)Imm) < 16; }]>; 1219defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1220 [{ return ((uint64_t)Imm) < 8; }]>; 1221defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1222 [{ return ((uint64_t)Imm) < 4; }]>; 1223defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1224 [{ return ((uint64_t)Imm) < 2; }]>; 1225 1226defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1227 [{ return ((uint64_t)Imm) == 1; }]>; 1228defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1229 [{ return ((uint64_t)Imm) < 16; }]>; 1230defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1231 [{ return ((uint64_t)Imm) < 8; }]>; 1232defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1233 [{ return ((uint64_t)Imm) < 4; }]>; 1234defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1235 [{ return ((uint64_t)Imm) < 2; }]>; 1236 1237def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1238def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1239def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1240def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1241def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1242 1243defm sve_elm_idx_extdup_b 1244 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1245 [{ return ((uint64_t)Imm) < 64; }]>; 1246defm sve_elm_idx_extdup_h 1247 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1248 [{ return ((uint64_t)Imm) < 32; }]>; 1249defm sve_elm_idx_extdup_s 1250 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1251 [{ return ((uint64_t)Imm) < 16; }]>; 1252defm sve_elm_idx_extdup_d 1253 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1254 [{ return ((uint64_t)Imm) < 8; }]>; 1255defm sve_elm_idx_extdup_q 1256 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1257 [{ return ((uint64_t)Imm) < 4; }]>; 1258 1259// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1260// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1261// are encoded as the eight bit value 'abcdefgh'. 1262def simdimmtype10 : Operand<i32>, 1263 FPImmLeaf<f64, [{ 1264 return AArch64_AM::isAdvSIMDModImmType10( 1265 Imm.bitcastToAPInt().getZExtValue()); 1266 }], SDNodeXForm<fpimm, [{ 1267 APFloat InVal = N->getValueAPF(); 1268 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1269 .bitcastToAPInt() 1270 .getZExtValue()); 1271 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1272 }]>> { 1273 let ParserMatchClass = SIMDImmType10Operand; 1274 let PrintMethod = "printSIMDType10Operand"; 1275} 1276 1277 1278//--- 1279// System management 1280//--- 1281 1282// Base encoding for system instruction operands. 1283let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1284class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1285 list<dag> pattern = []> 1286 : I<oops, iops, asm, operands, "", pattern> { 1287 let Inst{31-22} = 0b1101010100; 1288 let Inst{21} = L; 1289} 1290 1291// System instructions which do not have an Rt register. 1292class SimpleSystemI<bit L, dag iops, string asm, string operands, 1293 list<dag> pattern = []> 1294 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1295 let Inst{4-0} = 0b11111; 1296} 1297 1298// System instructions which have an Rt register. 1299class RtSystemI<bit L, dag oops, dag iops, string asm, string operands> 1300 : BaseSystemI<L, oops, iops, asm, operands>, 1301 Sched<[WriteSys]> { 1302 bits<5> Rt; 1303 let Inst{4-0} = Rt; 1304} 1305 1306// System instructions for transactional memory extension 1307class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1308 string asm, string operands, list<dag> pattern> 1309 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1310 Sched<[WriteSys]> { 1311 let Inst{20-12} = 0b000110011; 1312 let Inst{11-8} = CRm; 1313 let Inst{7-5} = op2; 1314 let DecoderMethod = ""; 1315 1316 let mayLoad = 1; 1317 let mayStore = 1; 1318} 1319 1320// System instructions for transactional memory - single input operand 1321class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1322 : TMBaseSystemI<0b1, CRm, 0b011, 1323 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1324 bits<5> Rt; 1325 let Inst{4-0} = Rt; 1326} 1327 1328// System instructions for transactional memory - no operand 1329class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1330 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1331 let Inst{4-0} = 0b11111; 1332} 1333 1334// System instructions for exit from transactions 1335class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1336 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1337 Sched<[WriteSys]> { 1338 bits<16> imm; 1339 let Inst{31-24} = 0b11010100; 1340 let Inst{23-21} = op1; 1341 let Inst{20-5} = imm; 1342 let Inst{4-0} = 0b00000; 1343} 1344 1345// Hint instructions that take both a CRm and a 3-bit immediate. 1346// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1347// model patterns with sufficiently fine granularity 1348let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1349 class HintI<string mnemonic> 1350 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1351 [(int_aarch64_hint imm0_127:$imm)]>, 1352 Sched<[WriteHint]> { 1353 bits <7> imm; 1354 let Inst{20-12} = 0b000110010; 1355 let Inst{11-5} = imm; 1356 } 1357 1358// System instructions taking a single literal operand which encodes into 1359// CRm. op2 differentiates the opcodes. 1360def BarrierAsmOperand : AsmOperandClass { 1361 let Name = "Barrier"; 1362 let ParserMethod = "tryParseBarrierOperand"; 1363} 1364def barrier_op : Operand<i32> { 1365 let PrintMethod = "printBarrierOption"; 1366 let ParserMatchClass = BarrierAsmOperand; 1367} 1368class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1369 list<dag> pattern = []> 1370 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1371 Sched<[WriteBarrier]> { 1372 bits<4> CRm; 1373 let Inst{20-12} = 0b000110011; 1374 let Inst{11-8} = CRm; 1375 let Inst{7-5} = opc; 1376} 1377 1378class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1379 : SimpleSystemI<0, (ins), asm, "", pattern>, 1380 Sched<[]> { 1381 bits<4> CRm; 1382 let CRm = 0b0011; 1383 let Inst{31-12} = 0b11010101000000110010; 1384 let Inst{11-8} = CRm; 1385 let Inst{7-5} = op2; 1386 let Inst{4-0} = 0b11111; 1387} 1388 1389// MRS/MSR system instructions. These have different operand classes because 1390// a different subset of registers can be accessed through each instruction. 1391def MRSSystemRegisterOperand : AsmOperandClass { 1392 let Name = "MRSSystemRegister"; 1393 let ParserMethod = "tryParseSysReg"; 1394 let DiagnosticType = "MRS"; 1395} 1396// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1397def mrs_sysreg_op : Operand<i32> { 1398 let ParserMatchClass = MRSSystemRegisterOperand; 1399 let DecoderMethod = "DecodeMRSSystemRegister"; 1400 let PrintMethod = "printMRSSystemRegister"; 1401} 1402 1403def MSRSystemRegisterOperand : AsmOperandClass { 1404 let Name = "MSRSystemRegister"; 1405 let ParserMethod = "tryParseSysReg"; 1406 let DiagnosticType = "MSR"; 1407} 1408def msr_sysreg_op : Operand<i32> { 1409 let ParserMatchClass = MSRSystemRegisterOperand; 1410 let DecoderMethod = "DecodeMSRSystemRegister"; 1411 let PrintMethod = "printMSRSystemRegister"; 1412} 1413 1414def PSBHintOperand : AsmOperandClass { 1415 let Name = "PSBHint"; 1416 let ParserMethod = "tryParsePSBHint"; 1417} 1418def psbhint_op : Operand<i32> { 1419 let ParserMatchClass = PSBHintOperand; 1420 let PrintMethod = "printPSBHintOp"; 1421 let MCOperandPredicate = [{ 1422 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1423 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1424 if (!MCOp.isImm()) 1425 return false; 1426 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1427 }]; 1428} 1429 1430def BTIHintOperand : AsmOperandClass { 1431 let Name = "BTIHint"; 1432 let ParserMethod = "tryParseBTIHint"; 1433} 1434def btihint_op : Operand<i32> { 1435 let ParserMatchClass = BTIHintOperand; 1436 let PrintMethod = "printBTIHintOp"; 1437 let MCOperandPredicate = [{ 1438 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1439 if (!MCOp.isImm()) 1440 return false; 1441 return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr; 1442 }]; 1443} 1444 1445class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1446 "mrs", "\t$Rt, $systemreg"> { 1447 bits<16> systemreg; 1448 let Inst{20-5} = systemreg; 1449} 1450 1451// FIXME: Some of these def NZCV, others don't. Best way to model that? 1452// Explicitly modeling each of the system register as a register class 1453// would do it, but feels like overkill at this point. 1454class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1455 "msr", "\t$systemreg, $Rt"> { 1456 bits<16> systemreg; 1457 let Inst{20-5} = systemreg; 1458} 1459 1460def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1461 let Name = "SystemPStateFieldWithImm0_15"; 1462 let ParserMethod = "tryParseSysReg"; 1463} 1464def pstatefield4_op : Operand<i32> { 1465 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1466 let PrintMethod = "printSystemPStateField"; 1467} 1468 1469// Instructions to modify PSTATE, no input reg 1470let Defs = [NZCV] in 1471class PstateWriteSimple<dag iops, string asm, string operands> 1472 : SimpleSystemI<0, iops, asm, operands> { 1473 1474 let Inst{20-19} = 0b00; 1475 let Inst{15-12} = 0b0100; 1476} 1477 1478class MSRpstateImm0_15 1479 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1480 "\t$pstatefield, $imm">, 1481 Sched<[WriteSys]> { 1482 1483 bits<6> pstatefield; 1484 bits<4> imm; 1485 let Inst{18-16} = pstatefield{5-3}; 1486 let Inst{11-8} = imm; 1487 let Inst{7-5} = pstatefield{2-0}; 1488 1489 let DecoderMethod = "DecodeSystemPStateInstruction"; 1490 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1491 // Fail the decoder should attempt to decode the instruction as MSRI. 1492 let hasCompleteDecoder = 0; 1493} 1494 1495def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1496 let Name = "SystemPStateFieldWithImm0_1"; 1497 let ParserMethod = "tryParseSysReg"; 1498} 1499def pstatefield1_op : Operand<i32> { 1500 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1501 let PrintMethod = "printSystemPStateField"; 1502} 1503 1504class MSRpstateImm0_1 1505 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1506 "\t$pstatefield, $imm">, 1507 Sched<[WriteSys]> { 1508 1509 bits<6> pstatefield; 1510 bit imm; 1511 let Inst{18-16} = pstatefield{5-3}; 1512 let Inst{11-9} = 0b000; 1513 let Inst{8} = imm; 1514 let Inst{7-5} = pstatefield{2-0}; 1515 1516 let DecoderMethod = "DecodeSystemPStateInstruction"; 1517 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1518 // Fail the decoder should attempt to decode the instruction as MSRI. 1519 let hasCompleteDecoder = 0; 1520} 1521 1522// SYS and SYSL generic system instructions. 1523def SysCRAsmOperand : AsmOperandClass { 1524 let Name = "SysCR"; 1525 let ParserMethod = "tryParseSysCROperand"; 1526} 1527 1528def sys_cr_op : Operand<i32> { 1529 let PrintMethod = "printSysCROperand"; 1530 let ParserMatchClass = SysCRAsmOperand; 1531} 1532 1533class SystemXtI<bit L, string asm> 1534 : RtSystemI<L, (outs), 1535 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1536 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1537 bits<3> op1; 1538 bits<4> Cn; 1539 bits<4> Cm; 1540 bits<3> op2; 1541 let Inst{20-19} = 0b01; 1542 let Inst{18-16} = op1; 1543 let Inst{15-12} = Cn; 1544 let Inst{11-8} = Cm; 1545 let Inst{7-5} = op2; 1546} 1547 1548class SystemLXtI<bit L, string asm> 1549 : RtSystemI<L, (outs), 1550 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1551 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1552 bits<3> op1; 1553 bits<4> Cn; 1554 bits<4> Cm; 1555 bits<3> op2; 1556 let Inst{20-19} = 0b01; 1557 let Inst{18-16} = op1; 1558 let Inst{15-12} = Cn; 1559 let Inst{11-8} = Cm; 1560 let Inst{7-5} = op2; 1561} 1562 1563 1564// Branch (register) instructions: 1565// 1566// case opc of 1567// 0001 blr 1568// 0000 br 1569// 0101 dret 1570// 0100 eret 1571// 0010 ret 1572// otherwise UNDEFINED 1573class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1574 string operands, list<dag> pattern> 1575 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1576 let Inst{31-25} = 0b1101011; 1577 let Inst{24-21} = opc; 1578 let Inst{20-16} = 0b11111; 1579 let Inst{15-10} = 0b000000; 1580 let Inst{4-0} = 0b00000; 1581} 1582 1583class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1584 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1585 bits<5> Rn; 1586 let Inst{9-5} = Rn; 1587} 1588 1589let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1590class SpecialReturn<bits<4> opc, string asm> 1591 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1592 let Inst{9-5} = 0b11111; 1593} 1594 1595let mayLoad = 1 in 1596class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1597 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1598 Sched<[]> { 1599 bits<5> Rn; 1600 bits<5> Rt; 1601 let Inst{31-30} = sz; 1602 let Inst{29-10} = 0b11100010111111110000; 1603 let Inst{9-5} = Rn; 1604 let Inst{4-0} = Rt; 1605} 1606 1607class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1608 list<dag> pattern> 1609 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1610 let isAuthenticated = 1; 1611 let Inst{31-25} = 0b1101011; 1612 let Inst{20-11} = 0b1111100001; 1613 let Inst{10} = M; 1614 let Inst{4-0} = 0b11111; 1615} 1616 1617class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1618 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1619 bits<5> Rn; 1620 bits<5> Rm; 1621 let Inst{24-22} = 0b100; 1622 let Inst{21} = op; 1623 let Inst{9-5} = Rn; 1624 let Inst{4-0} = Rm; 1625} 1626 1627class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1628 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1629 bits<5> Rn; 1630 let Inst{24} = 0; 1631 let Inst{23-21} = opc; 1632 let Inst{9-5} = Rn; 1633} 1634 1635let Uses = [LR,SP] in 1636class AuthReturn<bits<3> op, bits<1> M, string asm> 1637 : AuthBase<M, (outs), (ins), asm, "", []> { 1638 let Inst{24} = 0; 1639 let Inst{23-21} = op; 1640 let Inst{9-0} = 0b1111111111; 1641} 1642 1643let mayLoad = 1 in 1644class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1645 string operands, string cstr, Operand opr> 1646 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1647 bits<10> offset; 1648 bits<5> Rn; 1649 bits<5> Rt; 1650 let isAuthenticated = 1; 1651 let Inst{31-24} = 0b11111000; 1652 let Inst{23} = M; 1653 let Inst{22} = offset{9}; 1654 let Inst{21} = 1; 1655 let Inst{20-12} = offset{8-0}; 1656 let Inst{11} = W; 1657 let Inst{10} = 1; 1658 let Inst{9-5} = Rn; 1659 let Inst{4-0} = Rt; 1660 1661 let DecoderMethod = "DecodeAuthLoadInstruction"; 1662} 1663 1664multiclass AuthLoad<bit M, string asm, Operand opr> { 1665 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1666 (ins GPR64sp:$Rn, opr:$offset), 1667 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1668 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1669 (ins GPR64sp:$Rn, opr:$offset), 1670 asm, "\t$Rt, [$Rn, $offset]!", 1671 "$Rn = $wback,@earlyclobber $wback", opr>; 1672 1673 def : InstAlias<asm # "\t$Rt, [$Rn]", 1674 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1675 1676 def : InstAlias<asm # "\t$Rt, [$wback]!", 1677 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1678} 1679 1680//--- 1681// Conditional branch instruction. 1682//--- 1683 1684// Condition code. 1685// 4-bit immediate. Pretty-printed as <cc> 1686def ccode : Operand<i32> { 1687 let PrintMethod = "printCondCode"; 1688 let ParserMatchClass = CondCode; 1689} 1690def inv_ccode : Operand<i32> { 1691 // AL and NV are invalid in the aliases which use inv_ccode 1692 let PrintMethod = "printInverseCondCode"; 1693 let ParserMatchClass = CondCode; 1694 let MCOperandPredicate = [{ 1695 return MCOp.isImm() && 1696 MCOp.getImm() != AArch64CC::AL && 1697 MCOp.getImm() != AArch64CC::NV; 1698 }]; 1699} 1700 1701// Conditional branch target. 19-bit immediate. The low two bits of the target 1702// offset are implied zero and so are not part of the immediate. 1703def am_brcond : Operand<OtherVT> { 1704 let EncoderMethod = "getCondBranchTargetOpValue"; 1705 let DecoderMethod = "DecodePCRelLabel19"; 1706 let PrintMethod = "printAlignedLabel"; 1707 let ParserMatchClass = PCRelLabel19Operand; 1708 let OperandType = "OPERAND_PCREL"; 1709} 1710 1711class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1712 "b", ".$cond\t$target", "", 1713 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1714 Sched<[WriteBr]> { 1715 let isBranch = 1; 1716 let isTerminator = 1; 1717 let Uses = [NZCV]; 1718 1719 bits<4> cond; 1720 bits<19> target; 1721 let Inst{31-24} = 0b01010100; 1722 let Inst{23-5} = target; 1723 let Inst{4} = 0; 1724 let Inst{3-0} = cond; 1725} 1726 1727//--- 1728// Compare-and-branch instructions. 1729//--- 1730class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1731 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1732 asm, "\t$Rt, $target", "", 1733 [(node regtype:$Rt, bb:$target)]>, 1734 Sched<[WriteBr]> { 1735 let isBranch = 1; 1736 let isTerminator = 1; 1737 1738 bits<5> Rt; 1739 bits<19> target; 1740 let Inst{30-25} = 0b011010; 1741 let Inst{24} = op; 1742 let Inst{23-5} = target; 1743 let Inst{4-0} = Rt; 1744} 1745 1746multiclass CmpBranch<bit op, string asm, SDNode node> { 1747 def W : BaseCmpBranch<GPR32, op, asm, node> { 1748 let Inst{31} = 0; 1749 } 1750 def X : BaseCmpBranch<GPR64, op, asm, node> { 1751 let Inst{31} = 1; 1752 } 1753} 1754 1755//--- 1756// Test-bit-and-branch instructions. 1757//--- 1758// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1759// the target offset are implied zero and so are not part of the immediate. 1760def am_tbrcond : Operand<OtherVT> { 1761 let EncoderMethod = "getTestBranchTargetOpValue"; 1762 let PrintMethod = "printAlignedLabel"; 1763 let ParserMatchClass = BranchTarget14Operand; 1764 let OperandType = "OPERAND_PCREL"; 1765} 1766 1767// AsmOperand classes to emit (or not) special diagnostics 1768def TBZImm0_31Operand : AsmOperandClass { 1769 let Name = "TBZImm0_31"; 1770 let PredicateMethod = "isImmInRange<0,31>"; 1771 let RenderMethod = "addImmOperands"; 1772} 1773def TBZImm32_63Operand : AsmOperandClass { 1774 let Name = "Imm32_63"; 1775 let PredicateMethod = "isImmInRange<32,63>"; 1776 let DiagnosticType = "InvalidImm0_63"; 1777 let RenderMethod = "addImmOperands"; 1778} 1779 1780class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1781 return (((uint32_t)Imm) < 32); 1782}]> { 1783 let ParserMatchClass = matcher; 1784} 1785 1786def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1787def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1788 1789def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1790 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1791}]> { 1792 let ParserMatchClass = TBZImm32_63Operand; 1793} 1794 1795class BaseTestBranch<RegisterClass regtype, Operand immtype, 1796 bit op, string asm, SDNode node> 1797 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1798 asm, "\t$Rt, $bit_off, $target", "", 1799 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1800 Sched<[WriteBr]> { 1801 let isBranch = 1; 1802 let isTerminator = 1; 1803 1804 bits<5> Rt; 1805 bits<6> bit_off; 1806 bits<14> target; 1807 1808 let Inst{30-25} = 0b011011; 1809 let Inst{24} = op; 1810 let Inst{23-19} = bit_off{4-0}; 1811 let Inst{18-5} = target; 1812 let Inst{4-0} = Rt; 1813 1814 let DecoderMethod = "DecodeTestAndBranch"; 1815} 1816 1817multiclass TestBranch<bit op, string asm, SDNode node> { 1818 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1819 let Inst{31} = 0; 1820 } 1821 1822 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1823 let Inst{31} = 1; 1824 } 1825 1826 // Alias X-reg with 0-31 imm to W-Reg. 1827 def : InstAlias<asm # "\t$Rd, $imm, $target", 1828 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1829 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1830 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1831 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1832 tbz_imm0_31_diag:$imm, bb:$target)>; 1833} 1834 1835//--- 1836// Unconditional branch (immediate) instructions. 1837//--- 1838def am_b_target : Operand<OtherVT> { 1839 let EncoderMethod = "getBranchTargetOpValue"; 1840 let PrintMethod = "printAlignedLabel"; 1841 let ParserMatchClass = BranchTarget26Operand; 1842 let OperandType = "OPERAND_PCREL"; 1843} 1844def am_bl_target : Operand<i64> { 1845 let EncoderMethod = "getBranchTargetOpValue"; 1846 let PrintMethod = "printAlignedLabel"; 1847 let ParserMatchClass = BranchTarget26Operand; 1848 let OperandType = "OPERAND_PCREL"; 1849} 1850 1851class BImm<bit op, dag iops, string asm, list<dag> pattern> 1852 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1853 bits<26> addr; 1854 let Inst{31} = op; 1855 let Inst{30-26} = 0b00101; 1856 let Inst{25-0} = addr; 1857 1858 let DecoderMethod = "DecodeUnconditionalBranch"; 1859} 1860 1861class BranchImm<bit op, string asm, list<dag> pattern> 1862 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1863class CallImm<bit op, string asm, list<dag> pattern> 1864 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1865 1866//--- 1867// Basic one-operand data processing instructions. 1868//--- 1869 1870let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1871class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1872 SDPatternOperator node> 1873 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1874 [(set regtype:$Rd, (node regtype:$Rn))]>, 1875 Sched<[WriteI, ReadI]> { 1876 bits<5> Rd; 1877 bits<5> Rn; 1878 1879 let Inst{30-13} = 0b101101011000000000; 1880 let Inst{12-10} = opc; 1881 let Inst{9-5} = Rn; 1882 let Inst{4-0} = Rd; 1883} 1884 1885let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1886multiclass OneOperandData<bits<3> opc, string asm, 1887 SDPatternOperator node = null_frag> { 1888 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1889 let Inst{31} = 0; 1890 } 1891 1892 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1893 let Inst{31} = 1; 1894 } 1895} 1896 1897class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1898 : BaseOneOperandData<opc, GPR32, asm, node> { 1899 let Inst{31} = 0; 1900} 1901 1902class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1903 : BaseOneOperandData<opc, GPR64, asm, node> { 1904 let Inst{31} = 1; 1905} 1906 1907class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1908 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "", 1909 []>, 1910 Sched<[WriteI, ReadI]> { 1911 bits<5> Rd; 1912 bits<5> Rn; 1913 let Inst{31-15} = 0b11011010110000010; 1914 let Inst{14-12} = opcode_prefix; 1915 let Inst{11-10} = opcode; 1916 let Inst{9-5} = Rn; 1917 let Inst{4-0} = Rd; 1918} 1919 1920class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1921 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> { 1922 bits<5> Rd; 1923 let Inst{31-15} = 0b11011010110000010; 1924 let Inst{14-12} = opcode_prefix; 1925 let Inst{11-10} = opcode; 1926 let Inst{9-5} = 0b11111; 1927 let Inst{4-0} = Rd; 1928} 1929 1930class SignAuthTwoOperand<bits<4> opc, string asm, 1931 SDPatternOperator OpNode> 1932 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1933 asm, "\t$Rd, $Rn, $Rm", "", 1934 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1935 Sched<[WriteI, ReadI, ReadI]> { 1936 bits<5> Rd; 1937 bits<5> Rn; 1938 bits<5> Rm; 1939 let Inst{31-21} = 0b10011010110; 1940 let Inst{20-16} = Rm; 1941 let Inst{15-14} = 0b00; 1942 let Inst{13-10} = opc; 1943 let Inst{9-5} = Rn; 1944 let Inst{4-0} = Rd; 1945} 1946 1947class ClearAuth<bits<1> data, string asm> 1948 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 1949 bits<5> Rd; 1950 let Inst{31-11} = 0b110110101100000101000; 1951 let Inst{10} = data; 1952 let Inst{9-5} = 0b11111; 1953 let Inst{4-0} = Rd; 1954} 1955 1956// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 1957class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 1958 : I<(outs), iops, asm, ops, "", []>, 1959 Sched<[WriteI, ReadI, ReadI]> { 1960 let Uses = [NZCV]; 1961 let Defs = [NZCV]; 1962 bits<5> Rn; 1963 let Inst{31} = sf; 1964 let Inst{30-15} = 0b0111010000000000; 1965 let Inst{14} = sz; 1966 let Inst{13-10} = 0b0010; 1967 let Inst{9-5} = Rn; 1968 let Inst{4-0} = 0b01101; 1969} 1970 1971class FlagRotate<dag iops, string asm, string ops> 1972 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 1973 bits<6> imm; 1974 bits<4> mask; 1975 let Inst{20-15} = imm; 1976 let Inst{13-10} = 0b0001; 1977 let Inst{4} = 0b0; 1978 let Inst{3-0} = mask; 1979} 1980 1981//--- 1982// Basic two-operand data processing instructions. 1983//--- 1984class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1985 list<dag> pattern> 1986 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1987 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1988 Sched<[WriteI, ReadI, ReadI]> { 1989 let Uses = [NZCV]; 1990 bits<5> Rd; 1991 bits<5> Rn; 1992 bits<5> Rm; 1993 let Inst{30} = isSub; 1994 let Inst{28-21} = 0b11010000; 1995 let Inst{20-16} = Rm; 1996 let Inst{15-10} = 0; 1997 let Inst{9-5} = Rn; 1998 let Inst{4-0} = Rd; 1999} 2000 2001class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2002 SDNode OpNode> 2003 : BaseBaseAddSubCarry<isSub, regtype, asm, 2004 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2005 2006class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2007 SDNode OpNode> 2008 : BaseBaseAddSubCarry<isSub, regtype, asm, 2009 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2010 (implicit NZCV)]> { 2011 let Defs = [NZCV]; 2012} 2013 2014multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2015 SDNode OpNode, SDNode OpNode_setflags> { 2016 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2017 let Inst{31} = 0; 2018 let Inst{29} = 0; 2019 } 2020 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2021 let Inst{31} = 1; 2022 let Inst{29} = 0; 2023 } 2024 2025 // Sets flags. 2026 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2027 OpNode_setflags> { 2028 let Inst{31} = 0; 2029 let Inst{29} = 1; 2030 } 2031 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2032 OpNode_setflags> { 2033 let Inst{31} = 1; 2034 let Inst{29} = 1; 2035 } 2036} 2037 2038class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2039 SDPatternOperator OpNode, 2040 RegisterClass in1regtype = regtype, 2041 RegisterClass in2regtype = regtype> 2042 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2043 asm, "\t$Rd, $Rn, $Rm", "", 2044 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2045 bits<5> Rd; 2046 bits<5> Rn; 2047 bits<5> Rm; 2048 let Inst{30-21} = 0b0011010110; 2049 let Inst{20-16} = Rm; 2050 let Inst{15-14} = 0b00; 2051 let Inst{13-10} = opc; 2052 let Inst{9-5} = Rn; 2053 let Inst{4-0} = Rd; 2054} 2055 2056class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2057 SDPatternOperator OpNode> 2058 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2059 let Inst{10} = isSigned; 2060} 2061 2062multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2063 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2064 Sched<[WriteID32, ReadID, ReadID]> { 2065 let Inst{31} = 0; 2066 } 2067 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2068 Sched<[WriteID64, ReadID, ReadID]> { 2069 let Inst{31} = 1; 2070 } 2071} 2072 2073class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2074 SDPatternOperator OpNode = null_frag> 2075 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2076 Sched<[WriteIS, ReadI]> { 2077 let Inst{11-10} = shift_type; 2078} 2079 2080multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2081 def Wr : BaseShift<shift_type, GPR32, asm> { 2082 let Inst{31} = 0; 2083 } 2084 2085 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2086 let Inst{31} = 1; 2087 } 2088 2089 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2090 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2091 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2092 2093 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2094 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2095 2096 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2097 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2098 2099 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2100 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2101 2102 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2103 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2104 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2105 2106 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2107 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2108 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2109} 2110 2111class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2112 : InstAlias<asm#"\t$dst, $src1, $src2", 2113 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2114 2115class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2116 RegisterClass addtype, string asm, 2117 list<dag> pattern> 2118 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2119 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2120 bits<5> Rd; 2121 bits<5> Rn; 2122 bits<5> Rm; 2123 bits<5> Ra; 2124 let Inst{30-24} = 0b0011011; 2125 let Inst{23-21} = opc; 2126 let Inst{20-16} = Rm; 2127 let Inst{15} = isSub; 2128 let Inst{14-10} = Ra; 2129 let Inst{9-5} = Rn; 2130 let Inst{4-0} = Rd; 2131} 2132 2133multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 2134 // MADD/MSUB generation is decided by MachineCombiner.cpp 2135 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 2136 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 2137 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2138 let Inst{31} = 0; 2139 } 2140 2141 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 2142 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 2143 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2144 let Inst{31} = 1; 2145 } 2146} 2147 2148class WideMulAccum<bit isSub, bits<3> opc, string asm, 2149 SDNode AccNode, SDNode ExtNode> 2150 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2151 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2152 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2153 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2154 let Inst{31} = 1; 2155} 2156 2157class MulHi<bits<3> opc, string asm, SDNode OpNode> 2158 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2159 asm, "\t$Rd, $Rn, $Rm", "", 2160 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2161 Sched<[WriteIM64, ReadIM, ReadIM]> { 2162 bits<5> Rd; 2163 bits<5> Rn; 2164 bits<5> Rm; 2165 let Inst{31-24} = 0b10011011; 2166 let Inst{23-21} = opc; 2167 let Inst{20-16} = Rm; 2168 let Inst{15} = 0; 2169 let Inst{9-5} = Rn; 2170 let Inst{4-0} = Rd; 2171 2172 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2173 // (i.e. all bits 1) but is ignored by the processor. 2174 let PostEncoderMethod = "fixMulHigh"; 2175} 2176 2177class MulAccumWAlias<string asm, Instruction inst> 2178 : InstAlias<asm#"\t$dst, $src1, $src2", 2179 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2180class MulAccumXAlias<string asm, Instruction inst> 2181 : InstAlias<asm#"\t$dst, $src1, $src2", 2182 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2183class WideMulAccumAlias<string asm, Instruction inst> 2184 : InstAlias<asm#"\t$dst, $src1, $src2", 2185 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2186 2187class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2188 SDPatternOperator OpNode, string asm> 2189 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2190 asm, "\t$Rd, $Rn, $Rm", "", 2191 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2192 Sched<[WriteISReg, ReadI, ReadISReg]> { 2193 bits<5> Rd; 2194 bits<5> Rn; 2195 bits<5> Rm; 2196 2197 let Inst{31} = sf; 2198 let Inst{30-21} = 0b0011010110; 2199 let Inst{20-16} = Rm; 2200 let Inst{15-13} = 0b010; 2201 let Inst{12} = C; 2202 let Inst{11-10} = sz; 2203 let Inst{9-5} = Rn; 2204 let Inst{4-0} = Rd; 2205 let Predicates = [HasCRC]; 2206} 2207 2208//--- 2209// Address generation. 2210//--- 2211 2212class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2213 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2214 pattern>, 2215 Sched<[WriteI]> { 2216 bits<5> Xd; 2217 bits<21> label; 2218 let Inst{31} = page; 2219 let Inst{30-29} = label{1-0}; 2220 let Inst{28-24} = 0b10000; 2221 let Inst{23-5} = label{20-2}; 2222 let Inst{4-0} = Xd; 2223 2224 let DecoderMethod = "DecodeAdrInstruction"; 2225} 2226 2227//--- 2228// Move immediate. 2229//--- 2230 2231def movimm32_imm : Operand<i32> { 2232 let ParserMatchClass = AsmImmRange<0, 65535>; 2233 let EncoderMethod = "getMoveWideImmOpValue"; 2234 let PrintMethod = "printImm"; 2235} 2236def movimm32_shift : Operand<i32> { 2237 let PrintMethod = "printShifter"; 2238 let ParserMatchClass = MovImm32ShifterOperand; 2239} 2240def movimm64_shift : Operand<i32> { 2241 let PrintMethod = "printShifter"; 2242 let ParserMatchClass = MovImm64ShifterOperand; 2243} 2244 2245let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2246class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2247 string asm> 2248 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2249 asm, "\t$Rd, $imm$shift", "", []>, 2250 Sched<[WriteImm]> { 2251 bits<5> Rd; 2252 bits<16> imm; 2253 bits<6> shift; 2254 let Inst{30-29} = opc; 2255 let Inst{28-23} = 0b100101; 2256 let Inst{22-21} = shift{5-4}; 2257 let Inst{20-5} = imm; 2258 let Inst{4-0} = Rd; 2259 2260 let DecoderMethod = "DecodeMoveImmInstruction"; 2261} 2262 2263multiclass MoveImmediate<bits<2> opc, string asm> { 2264 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2265 let Inst{31} = 0; 2266 } 2267 2268 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2269 let Inst{31} = 1; 2270 } 2271} 2272 2273let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2274class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2275 string asm> 2276 : I<(outs regtype:$Rd), 2277 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2278 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2279 Sched<[WriteI, ReadI]> { 2280 bits<5> Rd; 2281 bits<16> imm; 2282 bits<6> shift; 2283 let Inst{30-29} = opc; 2284 let Inst{28-23} = 0b100101; 2285 let Inst{22-21} = shift{5-4}; 2286 let Inst{20-5} = imm; 2287 let Inst{4-0} = Rd; 2288 2289 let DecoderMethod = "DecodeMoveImmInstruction"; 2290} 2291 2292multiclass InsertImmediate<bits<2> opc, string asm> { 2293 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2294 let Inst{31} = 0; 2295 } 2296 2297 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2298 let Inst{31} = 1; 2299 } 2300} 2301 2302//--- 2303// Add/Subtract 2304//--- 2305 2306class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2307 string asm_inst, string asm_ops, 2308 dag inputs, dag pattern> 2309 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2310 Sched<[WriteI, ReadI]> { 2311 bits<5> Rd; 2312 bits<5> Rn; 2313 let Inst{30} = isSub; 2314 let Inst{29} = setFlags; 2315 let Inst{28-24} = 0b10001; 2316 let Inst{9-5} = Rn; 2317 let Inst{4-0} = Rd; 2318} 2319 2320class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2321 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2322 string asm_inst, SDPatternOperator OpNode> 2323 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2324 (ins srcRegtype:$Rn, immtype:$imm), 2325 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2326 bits<14> imm; 2327 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2328 let Inst{21-10} = imm{11-0}; 2329 let DecoderMethod = "DecodeAddSubImmShift"; 2330} 2331 2332class BaseAddSubRegPseudo<RegisterClass regtype, 2333 SDPatternOperator OpNode> 2334 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2335 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2336 Sched<[WriteI, ReadI, ReadI]>; 2337 2338class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2339 arith_shifted_reg shifted_regtype, string asm, 2340 SDPatternOperator OpNode> 2341 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2342 asm, "\t$Rd, $Rn, $Rm", "", 2343 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2344 Sched<[WriteISReg, ReadI, ReadISReg]> { 2345 // The operands are in order to match the 'addr' MI operands, so we 2346 // don't need an encoder method and by-name matching. Just use the default 2347 // in-order handling. Since we're using by-order, make sure the names 2348 // do not match. 2349 bits<5> dst; 2350 bits<5> src1; 2351 bits<5> src2; 2352 bits<8> shift; 2353 let Inst{30} = isSub; 2354 let Inst{29} = setFlags; 2355 let Inst{28-24} = 0b01011; 2356 let Inst{23-22} = shift{7-6}; 2357 let Inst{21} = 0; 2358 let Inst{20-16} = src2; 2359 let Inst{15-10} = shift{5-0}; 2360 let Inst{9-5} = src1; 2361 let Inst{4-0} = dst; 2362 2363 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2364} 2365 2366class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2367 RegisterClass src1Regtype, Operand src2Regtype, 2368 string asm, SDPatternOperator OpNode> 2369 : I<(outs dstRegtype:$R1), 2370 (ins src1Regtype:$R2, src2Regtype:$R3), 2371 asm, "\t$R1, $R2, $R3", "", 2372 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2373 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2374 bits<5> Rd; 2375 bits<5> Rn; 2376 bits<5> Rm; 2377 bits<6> ext; 2378 let Inst{30} = isSub; 2379 let Inst{29} = setFlags; 2380 let Inst{28-24} = 0b01011; 2381 let Inst{23-21} = 0b001; 2382 let Inst{20-16} = Rm; 2383 let Inst{15-13} = ext{5-3}; 2384 let Inst{12-10} = ext{2-0}; 2385 let Inst{9-5} = Rn; 2386 let Inst{4-0} = Rd; 2387 2388 let DecoderMethod = "DecodeAddSubERegInstruction"; 2389} 2390 2391let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2392class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2393 RegisterClass src1Regtype, RegisterClass src2Regtype, 2394 Operand ext_op, string asm> 2395 : I<(outs dstRegtype:$Rd), 2396 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2397 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2398 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2399 bits<5> Rd; 2400 bits<5> Rn; 2401 bits<5> Rm; 2402 bits<6> ext; 2403 let Inst{30} = isSub; 2404 let Inst{29} = setFlags; 2405 let Inst{28-24} = 0b01011; 2406 let Inst{23-21} = 0b001; 2407 let Inst{20-16} = Rm; 2408 let Inst{15} = ext{5}; 2409 let Inst{12-10} = ext{2-0}; 2410 let Inst{9-5} = Rn; 2411 let Inst{4-0} = Rd; 2412 2413 let DecoderMethod = "DecodeAddSubERegInstruction"; 2414} 2415 2416// Aliases for register+register add/subtract. 2417class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2418 RegisterClass src1Regtype, RegisterClass src2Regtype, 2419 int shiftExt> 2420 : InstAlias<asm#"\t$dst, $src1, $src2", 2421 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2422 shiftExt)>; 2423 2424multiclass AddSub<bit isSub, string mnemonic, string alias, 2425 SDPatternOperator OpNode = null_frag> { 2426 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2427 // Add/Subtract immediate 2428 // Increase the weight of the immediate variant to try to match it before 2429 // the extended register variant. 2430 // We used to match the register variant before the immediate when the 2431 // register argument could be implicitly zero-extended. 2432 let AddedComplexity = 6 in 2433 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2434 mnemonic, OpNode> { 2435 let Inst{31} = 0; 2436 } 2437 let AddedComplexity = 6 in 2438 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2439 mnemonic, OpNode> { 2440 let Inst{31} = 1; 2441 } 2442 2443 // Add/Subtract register - Only used for CodeGen 2444 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2445 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2446 2447 // Add/Subtract shifted register 2448 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2449 OpNode> { 2450 let Inst{31} = 0; 2451 } 2452 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2453 OpNode> { 2454 let Inst{31} = 1; 2455 } 2456 } 2457 2458 // Add/Subtract extended register 2459 let AddedComplexity = 1, hasSideEffects = 0 in { 2460 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2461 arith_extended_reg32_i32, mnemonic, OpNode> { 2462 let Inst{31} = 0; 2463 } 2464 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2465 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2466 let Inst{31} = 1; 2467 } 2468 } 2469 2470 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2471 arith_extendlsl64, mnemonic> { 2472 // UXTX and SXTX only. 2473 let Inst{14-13} = 0b11; 2474 let Inst{31} = 1; 2475 } 2476 2477 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2478 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2479 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2480 addsub_shifted_imm32_neg:$imm), 0>; 2481 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2482 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2483 addsub_shifted_imm64_neg:$imm), 0>; 2484 2485 // Register/register aliases with no shift when SP is not used. 2486 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2487 GPR32, GPR32, GPR32, 0>; 2488 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2489 GPR64, GPR64, GPR64, 0>; 2490 2491 // Register/register aliases with no shift when either the destination or 2492 // first source register is SP. 2493 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2494 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2495 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2496 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2497 def : AddSubRegAlias<mnemonic, 2498 !cast<Instruction>(NAME#"Xrx64"), 2499 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2500 def : AddSubRegAlias<mnemonic, 2501 !cast<Instruction>(NAME#"Xrx64"), 2502 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2503} 2504 2505multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2506 string alias, string cmpAlias> { 2507 let isCompare = 1, Defs = [NZCV] in { 2508 // Add/Subtract immediate 2509 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2510 mnemonic, OpNode> { 2511 let Inst{31} = 0; 2512 } 2513 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2514 mnemonic, OpNode> { 2515 let Inst{31} = 1; 2516 } 2517 2518 // Add/Subtract register 2519 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2520 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2521 2522 // Add/Subtract shifted register 2523 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2524 OpNode> { 2525 let Inst{31} = 0; 2526 } 2527 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2528 OpNode> { 2529 let Inst{31} = 1; 2530 } 2531 2532 // Add/Subtract extended register 2533 let AddedComplexity = 1 in { 2534 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2535 arith_extended_reg32_i32, mnemonic, OpNode> { 2536 let Inst{31} = 0; 2537 } 2538 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2539 arith_extended_reg32_i64, mnemonic, OpNode> { 2540 let Inst{31} = 1; 2541 } 2542 } 2543 2544 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2545 arith_extendlsl64, mnemonic> { 2546 // UXTX and SXTX only. 2547 let Inst{14-13} = 0b11; 2548 let Inst{31} = 1; 2549 } 2550 } // Defs = [NZCV] 2551 2552 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2553 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2554 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2555 addsub_shifted_imm32_neg:$imm), 0>; 2556 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2557 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2558 addsub_shifted_imm64_neg:$imm), 0>; 2559 2560 // Compare aliases 2561 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2562 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2563 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2564 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2565 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2566 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2567 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2568 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2569 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2570 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2571 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2572 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2573 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2574 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2575 2576 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2577 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2578 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2579 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2580 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2581 2582 // Compare shorthands 2583 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2584 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2585 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2586 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2587 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2588 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2589 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2590 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2591 2592 // Register/register aliases with no shift when SP is not used. 2593 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2594 GPR32, GPR32, GPR32, 0>; 2595 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2596 GPR64, GPR64, GPR64, 0>; 2597 2598 // Register/register aliases with no shift when the first source register 2599 // is SP. 2600 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2601 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2602 def : AddSubRegAlias<mnemonic, 2603 !cast<Instruction>(NAME#"Xrx64"), 2604 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2605} 2606 2607class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2608 : BaseAddSubImm< 2609 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2610 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2611 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2612 bits<6> imm6; 2613 bits<4> imm4; 2614 let Inst{31} = 1; 2615 let Inst{23-22} = 0b10; 2616 let Inst{21-16} = imm6; 2617 let Inst{15-14} = 0b00; 2618 let Inst{13-10} = imm4; 2619 let Unpredictable{15-14} = 0b11; 2620} 2621 2622class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2623 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2624 let Inst{31} = 1; 2625 let Inst{29} = setsFlags; 2626} 2627 2628//--- 2629// Extract 2630//--- 2631def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2632 SDTCisPtrTy<3>]>; 2633def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2634 2635class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2636 list<dag> patterns> 2637 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2638 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2639 Sched<[WriteExtr, ReadExtrHi]> { 2640 bits<5> Rd; 2641 bits<5> Rn; 2642 bits<5> Rm; 2643 bits<6> imm; 2644 2645 let Inst{30-23} = 0b00100111; 2646 let Inst{21} = 0; 2647 let Inst{20-16} = Rm; 2648 let Inst{15-10} = imm; 2649 let Inst{9-5} = Rn; 2650 let Inst{4-0} = Rd; 2651} 2652 2653multiclass ExtractImm<string asm> { 2654 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2655 [(set GPR32:$Rd, 2656 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2657 let Inst{31} = 0; 2658 let Inst{22} = 0; 2659 // imm<5> must be zero. 2660 let imm{5} = 0; 2661 } 2662 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2663 [(set GPR64:$Rd, 2664 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2665 2666 let Inst{31} = 1; 2667 let Inst{22} = 1; 2668 } 2669} 2670 2671//--- 2672// Bitfield 2673//--- 2674 2675let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2676class BaseBitfieldImm<bits<2> opc, 2677 RegisterClass regtype, Operand imm_type, string asm> 2678 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2679 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2680 Sched<[WriteIS, ReadI]> { 2681 bits<5> Rd; 2682 bits<5> Rn; 2683 bits<6> immr; 2684 bits<6> imms; 2685 2686 let Inst{30-29} = opc; 2687 let Inst{28-23} = 0b100110; 2688 let Inst{21-16} = immr; 2689 let Inst{15-10} = imms; 2690 let Inst{9-5} = Rn; 2691 let Inst{4-0} = Rd; 2692} 2693 2694multiclass BitfieldImm<bits<2> opc, string asm> { 2695 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2696 let Inst{31} = 0; 2697 let Inst{22} = 0; 2698 // imms<5> and immr<5> must be zero, else ReservedValue(). 2699 let Inst{21} = 0; 2700 let Inst{15} = 0; 2701 } 2702 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2703 let Inst{31} = 1; 2704 let Inst{22} = 1; 2705 } 2706} 2707 2708let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2709class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2710 RegisterClass regtype, Operand imm_type, string asm> 2711 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2712 imm_type:$imms), 2713 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2714 Sched<[WriteIS, ReadI]> { 2715 bits<5> Rd; 2716 bits<5> Rn; 2717 bits<6> immr; 2718 bits<6> imms; 2719 2720 let Inst{30-29} = opc; 2721 let Inst{28-23} = 0b100110; 2722 let Inst{21-16} = immr; 2723 let Inst{15-10} = imms; 2724 let Inst{9-5} = Rn; 2725 let Inst{4-0} = Rd; 2726} 2727 2728multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2729 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2730 let Inst{31} = 0; 2731 let Inst{22} = 0; 2732 // imms<5> and immr<5> must be zero, else ReservedValue(). 2733 let Inst{21} = 0; 2734 let Inst{15} = 0; 2735 } 2736 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2737 let Inst{31} = 1; 2738 let Inst{22} = 1; 2739 } 2740} 2741 2742//--- 2743// Logical 2744//--- 2745 2746// Logical (immediate) 2747class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2748 RegisterClass sregtype, Operand imm_type, string asm, 2749 list<dag> pattern> 2750 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2751 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2752 Sched<[WriteI, ReadI]> { 2753 bits<5> Rd; 2754 bits<5> Rn; 2755 bits<13> imm; 2756 let Inst{30-29} = opc; 2757 let Inst{28-23} = 0b100100; 2758 let Inst{22} = imm{12}; 2759 let Inst{21-16} = imm{11-6}; 2760 let Inst{15-10} = imm{5-0}; 2761 let Inst{9-5} = Rn; 2762 let Inst{4-0} = Rd; 2763 2764 let DecoderMethod = "DecodeLogicalImmInstruction"; 2765} 2766 2767// Logical (shifted register) 2768class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2769 logical_shifted_reg shifted_regtype, string asm, 2770 list<dag> pattern> 2771 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2772 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2773 Sched<[WriteISReg, ReadI, ReadISReg]> { 2774 // The operands are in order to match the 'addr' MI operands, so we 2775 // don't need an encoder method and by-name matching. Just use the default 2776 // in-order handling. Since we're using by-order, make sure the names 2777 // do not match. 2778 bits<5> dst; 2779 bits<5> src1; 2780 bits<5> src2; 2781 bits<8> shift; 2782 let Inst{30-29} = opc; 2783 let Inst{28-24} = 0b01010; 2784 let Inst{23-22} = shift{7-6}; 2785 let Inst{21} = N; 2786 let Inst{20-16} = src2; 2787 let Inst{15-10} = shift{5-0}; 2788 let Inst{9-5} = src1; 2789 let Inst{4-0} = dst; 2790 2791 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2792} 2793 2794// Aliases for register+register logical instructions. 2795class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2796 : InstAlias<asm#"\t$dst, $src1, $src2", 2797 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2798 2799multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2800 string Alias> { 2801 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2802 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2803 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2804 logical_imm32:$imm))]> { 2805 let Inst{31} = 0; 2806 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2807 } 2808 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2809 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2810 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2811 logical_imm64:$imm))]> { 2812 let Inst{31} = 1; 2813 } 2814 2815 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2816 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2817 logical_imm32_not:$imm), 0>; 2818 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2819 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2820 logical_imm64_not:$imm), 0>; 2821} 2822 2823multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2824 string Alias> { 2825 let isCompare = 1, Defs = [NZCV] in { 2826 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2827 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2828 let Inst{31} = 0; 2829 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2830 } 2831 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2832 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2833 let Inst{31} = 1; 2834 } 2835 } // end Defs = [NZCV] 2836 2837 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2838 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2839 logical_imm32_not:$imm), 0>; 2840 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2841 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2842 logical_imm64_not:$imm), 0>; 2843} 2844 2845class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2846 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2847 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2848 Sched<[WriteI, ReadI, ReadI]>; 2849 2850// Split from LogicalImm as not all instructions have both. 2851multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2852 SDPatternOperator OpNode> { 2853 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2854 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2855 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2856 } 2857 2858 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2859 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2860 logical_shifted_reg32:$Rm))]> { 2861 let Inst{31} = 0; 2862 } 2863 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2864 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2865 logical_shifted_reg64:$Rm))]> { 2866 let Inst{31} = 1; 2867 } 2868 2869 def : LogicalRegAlias<mnemonic, 2870 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2871 def : LogicalRegAlias<mnemonic, 2872 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2873} 2874 2875// Split from LogicalReg to allow setting NZCV Defs 2876multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2877 SDPatternOperator OpNode = null_frag> { 2878 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2879 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2880 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2881 2882 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2883 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2884 let Inst{31} = 0; 2885 } 2886 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2887 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2888 let Inst{31} = 1; 2889 } 2890 } // Defs = [NZCV] 2891 2892 def : LogicalRegAlias<mnemonic, 2893 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2894 def : LogicalRegAlias<mnemonic, 2895 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2896} 2897 2898//--- 2899// Conditionally set flags 2900//--- 2901 2902let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2903class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2904 string mnemonic, SDNode OpNode> 2905 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2906 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2907 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2908 (i32 imm:$cond), NZCV))]>, 2909 Sched<[WriteI, ReadI]> { 2910 let Uses = [NZCV]; 2911 let Defs = [NZCV]; 2912 2913 bits<5> Rn; 2914 bits<5> imm; 2915 bits<4> nzcv; 2916 bits<4> cond; 2917 2918 let Inst{30} = op; 2919 let Inst{29-21} = 0b111010010; 2920 let Inst{20-16} = imm; 2921 let Inst{15-12} = cond; 2922 let Inst{11-10} = 0b10; 2923 let Inst{9-5} = Rn; 2924 let Inst{4} = 0b0; 2925 let Inst{3-0} = nzcv; 2926} 2927 2928let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2929class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2930 SDNode OpNode> 2931 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2932 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2933 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2934 (i32 imm:$cond), NZCV))]>, 2935 Sched<[WriteI, ReadI, ReadI]> { 2936 let Uses = [NZCV]; 2937 let Defs = [NZCV]; 2938 2939 bits<5> Rn; 2940 bits<5> Rm; 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} = Rm; 2947 let Inst{15-12} = cond; 2948 let Inst{11-10} = 0b00; 2949 let Inst{9-5} = Rn; 2950 let Inst{4} = 0b0; 2951 let Inst{3-0} = nzcv; 2952} 2953 2954multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2955 // immediate operand variants 2956 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2957 let Inst{31} = 0; 2958 } 2959 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2960 let Inst{31} = 1; 2961 } 2962 // register operand variants 2963 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2964 let Inst{31} = 0; 2965 } 2966 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2967 let Inst{31} = 1; 2968 } 2969} 2970 2971//--- 2972// Conditional select 2973//--- 2974 2975class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2976 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2977 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2978 [(set regtype:$Rd, 2979 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2980 Sched<[WriteI, ReadI, ReadI]> { 2981 let Uses = [NZCV]; 2982 2983 bits<5> Rd; 2984 bits<5> Rn; 2985 bits<5> Rm; 2986 bits<4> cond; 2987 2988 let Inst{30} = op; 2989 let Inst{29-21} = 0b011010100; 2990 let Inst{20-16} = Rm; 2991 let Inst{15-12} = cond; 2992 let Inst{11-10} = op2; 2993 let Inst{9-5} = Rn; 2994 let Inst{4-0} = Rd; 2995} 2996 2997multiclass CondSelect<bit op, bits<2> op2, string asm> { 2998 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2999 let Inst{31} = 0; 3000 } 3001 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3002 let Inst{31} = 1; 3003 } 3004} 3005 3006class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3007 PatFrag frag> 3008 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3009 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3010 [(set regtype:$Rd, 3011 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3012 (i32 imm:$cond), NZCV))]>, 3013 Sched<[WriteI, ReadI, ReadI]> { 3014 let Uses = [NZCV]; 3015 3016 bits<5> Rd; 3017 bits<5> Rn; 3018 bits<5> Rm; 3019 bits<4> cond; 3020 3021 let Inst{30} = op; 3022 let Inst{29-21} = 0b011010100; 3023 let Inst{20-16} = Rm; 3024 let Inst{15-12} = cond; 3025 let Inst{11-10} = op2; 3026 let Inst{9-5} = Rn; 3027 let Inst{4-0} = Rd; 3028} 3029 3030def inv_cond_XFORM : SDNodeXForm<imm, [{ 3031 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3032 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3033 MVT::i32); 3034}]>; 3035 3036multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3037 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3038 let Inst{31} = 0; 3039 } 3040 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3041 let Inst{31} = 1; 3042 } 3043 3044 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3045 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3046 (inv_cond_XFORM imm:$cond))>; 3047 3048 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3049 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3050 (inv_cond_XFORM imm:$cond))>; 3051} 3052 3053//--- 3054// Special Mask Value 3055//--- 3056def maski8_or_more : Operand<i32>, 3057 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3058} 3059def maski16_or_more : Operand<i32>, 3060 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3061} 3062 3063 3064//--- 3065// Load/store 3066//--- 3067 3068// (unsigned immediate) 3069// Indexed for 8-bit registers. offset is in range [0,4095]. 3070def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 3071def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 3072def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 3073def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 3074def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 3075 3076def gi_am_indexed8 : 3077 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3078 GIComplexPatternEquiv<am_indexed8>; 3079def gi_am_indexed16 : 3080 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3081 GIComplexPatternEquiv<am_indexed16>; 3082def gi_am_indexed32 : 3083 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3084 GIComplexPatternEquiv<am_indexed32>; 3085def gi_am_indexed64 : 3086 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3087 GIComplexPatternEquiv<am_indexed64>; 3088def gi_am_indexed128 : 3089 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3090 GIComplexPatternEquiv<am_indexed128>; 3091 3092class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3093 let Name = "UImm12Offset" # Scale; 3094 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3095 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3096 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3097} 3098 3099def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3100def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3101def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3102def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3103def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3104 3105class uimm12_scaled<int Scale> : Operand<i64> { 3106 let ParserMatchClass 3107 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3108 let EncoderMethod 3109 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3110 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3111} 3112 3113def uimm12s1 : uimm12_scaled<1>; 3114def uimm12s2 : uimm12_scaled<2>; 3115def uimm12s4 : uimm12_scaled<4>; 3116def uimm12s8 : uimm12_scaled<8>; 3117def uimm12s16 : uimm12_scaled<16>; 3118 3119class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3120 string asm, list<dag> pattern> 3121 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3122 bits<5> Rt; 3123 3124 bits<5> Rn; 3125 bits<12> offset; 3126 3127 let Inst{31-30} = sz; 3128 let Inst{29-27} = 0b111; 3129 let Inst{26} = V; 3130 let Inst{25-24} = 0b01; 3131 let Inst{23-22} = opc; 3132 let Inst{21-10} = offset; 3133 let Inst{9-5} = Rn; 3134 let Inst{4-0} = Rt; 3135 3136 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3137} 3138 3139multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3140 Operand indextype, string asm, list<dag> pattern> { 3141 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3142 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3143 (ins GPR64sp:$Rn, indextype:$offset), 3144 asm, pattern>, 3145 Sched<[WriteLD]>; 3146 3147 def : InstAlias<asm # "\t$Rt, [$Rn]", 3148 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3149} 3150 3151multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3152 Operand indextype, string asm, list<dag> pattern> { 3153 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3154 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3155 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3156 asm, pattern>, 3157 Sched<[WriteST]>; 3158 3159 def : InstAlias<asm # "\t$Rt, [$Rn]", 3160 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3161} 3162 3163// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3164// substitute zero-registers automatically. 3165// 3166// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3167// into StoreUI. 3168multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3169 Operand indextype, string asm, list<dag> pattern> { 3170 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3171 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3172 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3173 asm, pattern>, 3174 Sched<[WriteST]>; 3175 3176 def : InstAlias<asm # "\t$Rt, [$Rn]", 3177 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3178} 3179 3180def PrefetchOperand : AsmOperandClass { 3181 let Name = "Prefetch"; 3182 let ParserMethod = "tryParsePrefetch"; 3183} 3184def prfop : Operand<i32> { 3185 let PrintMethod = "printPrefetchOp"; 3186 let ParserMatchClass = PrefetchOperand; 3187} 3188 3189let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3190class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3191 : BaseLoadStoreUI<sz, V, opc, 3192 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3193 asm, pat>, 3194 Sched<[WriteLD]>; 3195 3196//--- 3197// Load literal 3198//--- 3199 3200// Load literal address: 19-bit immediate. The low two bits of the target 3201// offset are implied zero and so are not part of the immediate. 3202def am_ldrlit : Operand<iPTR> { 3203 let EncoderMethod = "getLoadLiteralOpValue"; 3204 let DecoderMethod = "DecodePCRelLabel19"; 3205 let PrintMethod = "printAlignedLabel"; 3206 let ParserMatchClass = PCRelLabel19Operand; 3207 let OperandType = "OPERAND_PCREL"; 3208} 3209 3210let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3211class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3212 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3213 asm, "\t$Rt, $label", "", pat>, 3214 Sched<[WriteLD]> { 3215 bits<5> Rt; 3216 bits<19> label; 3217 let Inst{31-30} = opc; 3218 let Inst{29-27} = 0b011; 3219 let Inst{26} = V; 3220 let Inst{25-24} = 0b00; 3221 let Inst{23-5} = label; 3222 let Inst{4-0} = Rt; 3223} 3224 3225let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3226class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3227 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3228 asm, "\t$Rt, $label", "", pat>, 3229 Sched<[WriteLD]> { 3230 bits<5> Rt; 3231 bits<19> label; 3232 let Inst{31-30} = opc; 3233 let Inst{29-27} = 0b011; 3234 let Inst{26} = V; 3235 let Inst{25-24} = 0b00; 3236 let Inst{23-5} = label; 3237 let Inst{4-0} = Rt; 3238} 3239 3240//--- 3241// Load/store register offset 3242//--- 3243 3244def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3245def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3246def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3247def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3248def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3249 3250def gi_ro_Xindexed8 : 3251 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3252 GIComplexPatternEquiv<ro_Xindexed8>; 3253def gi_ro_Xindexed16 : 3254 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3255 GIComplexPatternEquiv<ro_Xindexed16>; 3256def gi_ro_Xindexed32 : 3257 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3258 GIComplexPatternEquiv<ro_Xindexed32>; 3259def gi_ro_Xindexed64 : 3260 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3261 GIComplexPatternEquiv<ro_Xindexed64>; 3262def gi_ro_Xindexed128 : 3263 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3264 GIComplexPatternEquiv<ro_Xindexed128>; 3265 3266def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3267def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3268def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3269def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3270def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3271 3272def gi_ro_Windexed8 : 3273 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3274 GIComplexPatternEquiv<ro_Windexed8>; 3275def gi_ro_Windexed16 : 3276 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3277 GIComplexPatternEquiv<ro_Windexed16>; 3278def gi_ro_Windexed32 : 3279 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3280 GIComplexPatternEquiv<ro_Windexed32>; 3281def gi_ro_Windexed64 : 3282 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3283 GIComplexPatternEquiv<ro_Windexed64>; 3284def gi_ro_Windexed128 : 3285 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3286 GIComplexPatternEquiv<ro_Windexed128>; 3287 3288class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3289 let Name = "Mem" # Reg # "Extend" # Width; 3290 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3291 let RenderMethod = "addMemExtendOperands"; 3292 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3293} 3294 3295def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3296 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3297 // the trivial shift. 3298 let RenderMethod = "addMemExtend8Operands"; 3299} 3300def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3301def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3302def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3303def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3304 3305def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3306 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3307 // the trivial shift. 3308 let RenderMethod = "addMemExtend8Operands"; 3309} 3310def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3311def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3312def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3313def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3314 3315class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3316 : Operand<i32> { 3317 let ParserMatchClass = ParserClass; 3318 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3319 let DecoderMethod = "DecodeMemExtend"; 3320 let EncoderMethod = "getMemExtendOpValue"; 3321 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3322} 3323 3324def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3325def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3326def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3327def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3328def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3329 3330def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3331def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3332def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3333def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3334def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3335 3336class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3337 Operand wextend, Operand xextend> { 3338 // CodeGen-level pattern covering the entire addressing mode. 3339 ComplexPattern Wpat = windex; 3340 ComplexPattern Xpat = xindex; 3341 3342 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3343 Operand Wext = wextend; 3344 Operand Xext = xextend; 3345} 3346 3347def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3348def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3349def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3350def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3351def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3352 ro_Xextend128>; 3353 3354class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3355 string asm, dag ins, dag outs, list<dag> pat> 3356 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3357 bits<5> Rt; 3358 bits<5> Rn; 3359 bits<5> Rm; 3360 bits<2> extend; 3361 let Inst{31-30} = sz; 3362 let Inst{29-27} = 0b111; 3363 let Inst{26} = V; 3364 let Inst{25-24} = 0b00; 3365 let Inst{23-22} = opc; 3366 let Inst{21} = 1; 3367 let Inst{20-16} = Rm; 3368 let Inst{15} = extend{1}; // sign extend Rm? 3369 let Inst{14} = 1; 3370 let Inst{12} = extend{0}; // do shift? 3371 let Inst{11-10} = 0b10; 3372 let Inst{9-5} = Rn; 3373 let Inst{4-0} = Rt; 3374} 3375 3376class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST> 3377 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3378 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3379 3380multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3381 string asm, ValueType Ty, SDPatternOperator loadop> { 3382 let AddedComplexity = 10 in 3383 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3384 (outs regtype:$Rt), 3385 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3386 [(set (Ty regtype:$Rt), 3387 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3388 ro_Wextend8:$extend)))]>, 3389 Sched<[WriteLDIdx, ReadAdrBase]> { 3390 let Inst{13} = 0b0; 3391 } 3392 3393 let AddedComplexity = 10 in 3394 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3395 (outs regtype:$Rt), 3396 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3397 [(set (Ty regtype:$Rt), 3398 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3399 ro_Xextend8:$extend)))]>, 3400 Sched<[WriteLDIdx, ReadAdrBase]> { 3401 let Inst{13} = 0b1; 3402 } 3403 3404 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3405} 3406 3407multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3408 string asm, ValueType Ty, SDPatternOperator storeop> { 3409 let AddedComplexity = 10 in 3410 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3411 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3412 [(storeop (Ty regtype:$Rt), 3413 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3414 ro_Wextend8:$extend))]>, 3415 Sched<[WriteSTIdx, ReadAdrBase]> { 3416 let Inst{13} = 0b0; 3417 } 3418 3419 let AddedComplexity = 10 in 3420 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3421 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3422 [(storeop (Ty regtype:$Rt), 3423 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3424 ro_Xextend8:$extend))]>, 3425 Sched<[WriteSTIdx, ReadAdrBase]> { 3426 let Inst{13} = 0b1; 3427 } 3428 3429 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3430} 3431 3432class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3433 string asm, dag ins, dag outs, list<dag> pat> 3434 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3435 bits<5> Rt; 3436 bits<5> Rn; 3437 bits<5> Rm; 3438 bits<2> extend; 3439 let Inst{31-30} = sz; 3440 let Inst{29-27} = 0b111; 3441 let Inst{26} = V; 3442 let Inst{25-24} = 0b00; 3443 let Inst{23-22} = opc; 3444 let Inst{21} = 1; 3445 let Inst{20-16} = Rm; 3446 let Inst{15} = extend{1}; // sign extend Rm? 3447 let Inst{14} = 1; 3448 let Inst{12} = extend{0}; // do shift? 3449 let Inst{11-10} = 0b10; 3450 let Inst{9-5} = Rn; 3451 let Inst{4-0} = Rt; 3452} 3453 3454multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3455 string asm, ValueType Ty, SDPatternOperator loadop> { 3456 let AddedComplexity = 10 in 3457 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3458 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3459 [(set (Ty regtype:$Rt), 3460 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3461 ro_Wextend16:$extend)))]>, 3462 Sched<[WriteLDIdx, ReadAdrBase]> { 3463 let Inst{13} = 0b0; 3464 } 3465 3466 let AddedComplexity = 10 in 3467 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3468 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3469 [(set (Ty regtype:$Rt), 3470 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3471 ro_Xextend16:$extend)))]>, 3472 Sched<[WriteLDIdx, ReadAdrBase]> { 3473 let Inst{13} = 0b1; 3474 } 3475 3476 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3477} 3478 3479multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3480 string asm, ValueType Ty, SDPatternOperator storeop> { 3481 let AddedComplexity = 10 in 3482 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3483 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3484 [(storeop (Ty regtype:$Rt), 3485 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3486 ro_Wextend16:$extend))]>, 3487 Sched<[WriteSTIdx, ReadAdrBase]> { 3488 let Inst{13} = 0b0; 3489 } 3490 3491 let AddedComplexity = 10 in 3492 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3493 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3494 [(storeop (Ty regtype:$Rt), 3495 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3496 ro_Xextend16:$extend))]>, 3497 Sched<[WriteSTIdx, ReadAdrBase]> { 3498 let Inst{13} = 0b1; 3499 } 3500 3501 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3502} 3503 3504class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3505 string asm, dag ins, dag outs, list<dag> pat> 3506 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3507 bits<5> Rt; 3508 bits<5> Rn; 3509 bits<5> Rm; 3510 bits<2> extend; 3511 let Inst{31-30} = sz; 3512 let Inst{29-27} = 0b111; 3513 let Inst{26} = V; 3514 let Inst{25-24} = 0b00; 3515 let Inst{23-22} = opc; 3516 let Inst{21} = 1; 3517 let Inst{20-16} = Rm; 3518 let Inst{15} = extend{1}; // sign extend Rm? 3519 let Inst{14} = 1; 3520 let Inst{12} = extend{0}; // do shift? 3521 let Inst{11-10} = 0b10; 3522 let Inst{9-5} = Rn; 3523 let Inst{4-0} = Rt; 3524} 3525 3526multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3527 string asm, ValueType Ty, SDPatternOperator loadop> { 3528 let AddedComplexity = 10 in 3529 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3530 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3531 [(set (Ty regtype:$Rt), 3532 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3533 ro_Wextend32:$extend)))]>, 3534 Sched<[WriteLDIdx, ReadAdrBase]> { 3535 let Inst{13} = 0b0; 3536 } 3537 3538 let AddedComplexity = 10 in 3539 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3540 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3541 [(set (Ty regtype:$Rt), 3542 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3543 ro_Xextend32:$extend)))]>, 3544 Sched<[WriteLDIdx, ReadAdrBase]> { 3545 let Inst{13} = 0b1; 3546 } 3547 3548 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3549} 3550 3551multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3552 string asm, ValueType Ty, SDPatternOperator storeop> { 3553 let AddedComplexity = 10 in 3554 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3555 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3556 [(storeop (Ty regtype:$Rt), 3557 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3558 ro_Wextend32:$extend))]>, 3559 Sched<[WriteSTIdx, ReadAdrBase]> { 3560 let Inst{13} = 0b0; 3561 } 3562 3563 let AddedComplexity = 10 in 3564 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3565 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3566 [(storeop (Ty regtype:$Rt), 3567 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3568 ro_Xextend32:$extend))]>, 3569 Sched<[WriteSTIdx, ReadAdrBase]> { 3570 let Inst{13} = 0b1; 3571 } 3572 3573 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3574} 3575 3576class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3577 string asm, dag ins, dag outs, list<dag> pat> 3578 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3579 bits<5> Rt; 3580 bits<5> Rn; 3581 bits<5> Rm; 3582 bits<2> extend; 3583 let Inst{31-30} = sz; 3584 let Inst{29-27} = 0b111; 3585 let Inst{26} = V; 3586 let Inst{25-24} = 0b00; 3587 let Inst{23-22} = opc; 3588 let Inst{21} = 1; 3589 let Inst{20-16} = Rm; 3590 let Inst{15} = extend{1}; // sign extend Rm? 3591 let Inst{14} = 1; 3592 let Inst{12} = extend{0}; // do shift? 3593 let Inst{11-10} = 0b10; 3594 let Inst{9-5} = Rn; 3595 let Inst{4-0} = Rt; 3596} 3597 3598multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3599 string asm, ValueType Ty, SDPatternOperator loadop> { 3600 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3601 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3602 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3603 [(set (Ty regtype:$Rt), 3604 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3605 ro_Wextend64:$extend)))]>, 3606 Sched<[WriteLDIdx, ReadAdrBase]> { 3607 let Inst{13} = 0b0; 3608 } 3609 3610 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3611 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3612 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3613 [(set (Ty regtype:$Rt), 3614 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3615 ro_Xextend64:$extend)))]>, 3616 Sched<[WriteLDIdx, ReadAdrBase]> { 3617 let Inst{13} = 0b1; 3618 } 3619 3620 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3621} 3622 3623multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3624 string asm, ValueType Ty, SDPatternOperator storeop> { 3625 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3626 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3627 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3628 [(storeop (Ty regtype:$Rt), 3629 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3630 ro_Wextend64:$extend))]>, 3631 Sched<[WriteSTIdx, ReadAdrBase]> { 3632 let Inst{13} = 0b0; 3633 } 3634 3635 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3636 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3637 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3638 [(storeop (Ty regtype:$Rt), 3639 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3640 ro_Xextend64:$extend))]>, 3641 Sched<[WriteSTIdx, ReadAdrBase]> { 3642 let Inst{13} = 0b1; 3643 } 3644 3645 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3646} 3647 3648class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3649 string asm, dag ins, dag outs, list<dag> pat> 3650 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3651 bits<5> Rt; 3652 bits<5> Rn; 3653 bits<5> Rm; 3654 bits<2> extend; 3655 let Inst{31-30} = sz; 3656 let Inst{29-27} = 0b111; 3657 let Inst{26} = V; 3658 let Inst{25-24} = 0b00; 3659 let Inst{23-22} = opc; 3660 let Inst{21} = 1; 3661 let Inst{20-16} = Rm; 3662 let Inst{15} = extend{1}; // sign extend Rm? 3663 let Inst{14} = 1; 3664 let Inst{12} = extend{0}; // do shift? 3665 let Inst{11-10} = 0b10; 3666 let Inst{9-5} = Rn; 3667 let Inst{4-0} = Rt; 3668} 3669 3670multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3671 string asm, ValueType Ty, SDPatternOperator loadop> { 3672 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3673 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3674 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3675 [(set (Ty regtype:$Rt), 3676 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3677 ro_Wextend128:$extend)))]>, 3678 Sched<[WriteLDIdx, ReadAdrBase]> { 3679 let Inst{13} = 0b0; 3680 } 3681 3682 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3683 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3684 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3685 [(set (Ty regtype:$Rt), 3686 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3687 ro_Xextend128:$extend)))]>, 3688 Sched<[WriteLDIdx, ReadAdrBase]> { 3689 let Inst{13} = 0b1; 3690 } 3691 3692 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3693} 3694 3695multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3696 string asm, ValueType Ty, SDPatternOperator storeop> { 3697 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3698 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3699 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3700 []>, 3701 Sched<[WriteSTIdx, ReadAdrBase]> { 3702 let Inst{13} = 0b0; 3703 } 3704 3705 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3706 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3707 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3708 []>, 3709 Sched<[WriteSTIdx, ReadAdrBase]> { 3710 let Inst{13} = 0b1; 3711 } 3712 3713 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3714} 3715 3716let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3717class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3718 string asm, list<dag> pat> 3719 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3720 Sched<[WriteLD]> { 3721 bits<5> Rt; 3722 bits<5> Rn; 3723 bits<5> Rm; 3724 bits<2> extend; 3725 let Inst{31-30} = sz; 3726 let Inst{29-27} = 0b111; 3727 let Inst{26} = V; 3728 let Inst{25-24} = 0b00; 3729 let Inst{23-22} = opc; 3730 let Inst{21} = 1; 3731 let Inst{20-16} = Rm; 3732 let Inst{15} = extend{1}; // sign extend Rm? 3733 let Inst{14} = 1; 3734 let Inst{12} = extend{0}; // do shift? 3735 let Inst{11-10} = 0b10; 3736 let Inst{9-5} = Rn; 3737 let Inst{4-0} = Rt; 3738} 3739 3740multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3741 def roW : BasePrefetchRO<sz, V, opc, (outs), 3742 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3743 asm, [(AArch64Prefetch imm:$Rt, 3744 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3745 ro_Wextend64:$extend))]> { 3746 let Inst{13} = 0b0; 3747 } 3748 3749 def roX : BasePrefetchRO<sz, V, opc, (outs), 3750 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3751 asm, [(AArch64Prefetch imm:$Rt, 3752 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3753 ro_Xextend64:$extend))]> { 3754 let Inst{13} = 0b1; 3755 } 3756 3757 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3758 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3759 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3760} 3761 3762//--- 3763// Load/store unscaled immediate 3764//--- 3765 3766def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3767def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3768def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3769def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3770def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3771 3772def gi_am_unscaled8 : 3773 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3774 GIComplexPatternEquiv<am_unscaled8>; 3775def gi_am_unscaled16 : 3776 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3777 GIComplexPatternEquiv<am_unscaled16>; 3778def gi_am_unscaled32 : 3779 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3780 GIComplexPatternEquiv<am_unscaled32>; 3781def gi_am_unscaled64 : 3782 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3783 GIComplexPatternEquiv<am_unscaled64>; 3784def gi_am_unscaled128 : 3785 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3786 GIComplexPatternEquiv<am_unscaled128>; 3787 3788 3789class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3790 string asm, list<dag> pattern> 3791 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3792 bits<5> Rt; 3793 bits<5> Rn; 3794 bits<9> offset; 3795 let Inst{31-30} = sz; 3796 let Inst{29-27} = 0b111; 3797 let Inst{26} = V; 3798 let Inst{25-24} = 0b00; 3799 let Inst{23-22} = opc; 3800 let Inst{21} = 0; 3801 let Inst{20-12} = offset; 3802 let Inst{11-10} = 0b00; 3803 let Inst{9-5} = Rn; 3804 let Inst{4-0} = Rt; 3805 3806 let DecoderMethod = "DecodeSignedLdStInstruction"; 3807} 3808 3809// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3810multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3811 RegisterOperand regtype > { 3812 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3813 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3814 Sched<[WriteST]> { 3815 let Inst{29} = 0; 3816 let Inst{24} = 1; 3817 } 3818 def : InstAlias<asm # "\t$Rt, [$Rn]", 3819 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3820} 3821 3822multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3823 RegisterOperand regtype > { 3824 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3825 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3826 asm, []>, 3827 Sched<[WriteST]> { 3828 let Inst{29} = 0; 3829 let Inst{24} = 1; 3830 } 3831 def : InstAlias<asm # "\t$Rt, [$Rn]", 3832 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3833} 3834 3835multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3836 string asm, list<dag> pattern> { 3837 let AddedComplexity = 1 in // try this before LoadUI 3838 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3839 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3840 Sched<[WriteLD]>; 3841 3842 def : InstAlias<asm # "\t$Rt, [$Rn]", 3843 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3844} 3845 3846multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3847 string asm, list<dag> pattern> { 3848 let AddedComplexity = 1 in // try this before StoreUI 3849 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3850 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3851 asm, pattern>, 3852 Sched<[WriteST]>; 3853 3854 def : InstAlias<asm # "\t$Rt, [$Rn]", 3855 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3856} 3857 3858multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3859 list<dag> pat> { 3860 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3861 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3862 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3863 asm, pat>, 3864 Sched<[WriteLD]>; 3865 3866 def : InstAlias<asm # "\t$Rt, [$Rn]", 3867 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3868} 3869 3870//--- 3871// Load/store unscaled immediate, unprivileged 3872//--- 3873 3874class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3875 dag oops, dag iops, string asm> 3876 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3877 bits<5> Rt; 3878 bits<5> Rn; 3879 bits<9> offset; 3880 let Inst{31-30} = sz; 3881 let Inst{29-27} = 0b111; 3882 let Inst{26} = V; 3883 let Inst{25-24} = 0b00; 3884 let Inst{23-22} = opc; 3885 let Inst{21} = 0; 3886 let Inst{20-12} = offset; 3887 let Inst{11-10} = 0b10; 3888 let Inst{9-5} = Rn; 3889 let Inst{4-0} = Rt; 3890 3891 let DecoderMethod = "DecodeSignedLdStInstruction"; 3892} 3893 3894multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3895 RegisterClass regtype, string asm> { 3896 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3897 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3898 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3899 Sched<[WriteLD]>; 3900 3901 def : InstAlias<asm # "\t$Rt, [$Rn]", 3902 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3903} 3904 3905multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3906 RegisterClass regtype, string asm> { 3907 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3908 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3909 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3910 asm>, 3911 Sched<[WriteST]>; 3912 3913 def : InstAlias<asm # "\t$Rt, [$Rn]", 3914 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3915} 3916 3917//--- 3918// Load/store pre-indexed 3919//--- 3920 3921class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3922 string asm, string cstr, list<dag> pat> 3923 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3924 bits<5> Rt; 3925 bits<5> Rn; 3926 bits<9> offset; 3927 let Inst{31-30} = sz; 3928 let Inst{29-27} = 0b111; 3929 let Inst{26} = V; 3930 let Inst{25-24} = 0; 3931 let Inst{23-22} = opc; 3932 let Inst{21} = 0; 3933 let Inst{20-12} = offset; 3934 let Inst{11-10} = 0b11; 3935 let Inst{9-5} = Rn; 3936 let Inst{4-0} = Rt; 3937 3938 let DecoderMethod = "DecodeSignedLdStInstruction"; 3939} 3940 3941let hasSideEffects = 0 in { 3942let mayStore = 0, mayLoad = 1 in 3943class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3944 string asm> 3945 : BaseLoadStorePreIdx<sz, V, opc, 3946 (outs GPR64sp:$wback, regtype:$Rt), 3947 (ins GPR64sp:$Rn, simm9:$offset), asm, 3948 "$Rn = $wback,@earlyclobber $wback", []>, 3949 Sched<[WriteAdr, WriteLD]>; 3950 3951let mayStore = 1, mayLoad = 0 in 3952class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3953 string asm, SDPatternOperator storeop, ValueType Ty> 3954 : BaseLoadStorePreIdx<sz, V, opc, 3955 (outs GPR64sp:$wback), 3956 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3957 asm, "$Rn = $wback,@earlyclobber $wback", 3958 [(set GPR64sp:$wback, 3959 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3960 Sched<[WriteAdr, WriteST]>; 3961} // hasSideEffects = 0 3962 3963//--- 3964// Load/store post-indexed 3965//--- 3966 3967class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3968 string asm, string cstr, list<dag> pat> 3969 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3970 bits<5> Rt; 3971 bits<5> Rn; 3972 bits<9> offset; 3973 let Inst{31-30} = sz; 3974 let Inst{29-27} = 0b111; 3975 let Inst{26} = V; 3976 let Inst{25-24} = 0b00; 3977 let Inst{23-22} = opc; 3978 let Inst{21} = 0b0; 3979 let Inst{20-12} = offset; 3980 let Inst{11-10} = 0b01; 3981 let Inst{9-5} = Rn; 3982 let Inst{4-0} = Rt; 3983 3984 let DecoderMethod = "DecodeSignedLdStInstruction"; 3985} 3986 3987let hasSideEffects = 0 in { 3988let mayStore = 0, mayLoad = 1 in 3989class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3990 string asm> 3991 : BaseLoadStorePostIdx<sz, V, opc, 3992 (outs GPR64sp:$wback, regtype:$Rt), 3993 (ins GPR64sp:$Rn, simm9:$offset), 3994 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3995 Sched<[WriteAdr, WriteLD]>; 3996 3997let mayStore = 1, mayLoad = 0 in 3998class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3999 string asm, SDPatternOperator storeop, ValueType Ty> 4000 : BaseLoadStorePostIdx<sz, V, opc, 4001 (outs GPR64sp:$wback), 4002 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4003 asm, "$Rn = $wback,@earlyclobber $wback", 4004 [(set GPR64sp:$wback, 4005 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4006 Sched<[WriteAdr, WriteST]>; 4007} // hasSideEffects = 0 4008 4009 4010//--- 4011// Load/store pair 4012//--- 4013 4014// (indexed, offset) 4015 4016class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4017 string asm> 4018 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4019 bits<5> Rt; 4020 bits<5> Rt2; 4021 bits<5> Rn; 4022 bits<7> offset; 4023 let Inst{31-30} = opc; 4024 let Inst{29-27} = 0b101; 4025 let Inst{26} = V; 4026 let Inst{25-23} = 0b010; 4027 let Inst{22} = L; 4028 let Inst{21-15} = offset; 4029 let Inst{14-10} = Rt2; 4030 let Inst{9-5} = Rn; 4031 let Inst{4-0} = Rt; 4032 4033 let DecoderMethod = "DecodePairLdStInstruction"; 4034} 4035 4036multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4037 Operand indextype, string asm> { 4038 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4039 def i : BaseLoadStorePairOffset<opc, V, 1, 4040 (outs regtype:$Rt, regtype:$Rt2), 4041 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4042 Sched<[WriteLD, WriteLDHi]>; 4043 4044 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4045 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4046 GPR64sp:$Rn, 0)>; 4047} 4048 4049 4050multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4051 Operand indextype, string asm> { 4052 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4053 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4054 (ins regtype:$Rt, regtype:$Rt2, 4055 GPR64sp:$Rn, indextype:$offset), 4056 asm>, 4057 Sched<[WriteSTP]>; 4058 4059 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4060 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4061 GPR64sp:$Rn, 0)>; 4062} 4063 4064// (pre-indexed) 4065class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4066 string asm> 4067 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4068 bits<5> Rt; 4069 bits<5> Rt2; 4070 bits<5> Rn; 4071 bits<7> offset; 4072 let Inst{31-30} = opc; 4073 let Inst{29-27} = 0b101; 4074 let Inst{26} = V; 4075 let Inst{25-23} = 0b011; 4076 let Inst{22} = L; 4077 let Inst{21-15} = offset; 4078 let Inst{14-10} = Rt2; 4079 let Inst{9-5} = Rn; 4080 let Inst{4-0} = Rt; 4081 4082 let DecoderMethod = "DecodePairLdStInstruction"; 4083} 4084 4085let hasSideEffects = 0 in { 4086let mayStore = 0, mayLoad = 1 in 4087class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4088 Operand indextype, string asm> 4089 : BaseLoadStorePairPreIdx<opc, V, 1, 4090 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4091 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4092 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4093 4094let mayStore = 1, mayLoad = 0 in 4095class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4096 Operand indextype, string asm> 4097 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4098 (ins regtype:$Rt, regtype:$Rt2, 4099 GPR64sp:$Rn, indextype:$offset), 4100 asm>, 4101 Sched<[WriteAdr, WriteSTP]>; 4102} // hasSideEffects = 0 4103 4104// (post-indexed) 4105 4106class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4107 string asm> 4108 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4109 bits<5> Rt; 4110 bits<5> Rt2; 4111 bits<5> Rn; 4112 bits<7> offset; 4113 let Inst{31-30} = opc; 4114 let Inst{29-27} = 0b101; 4115 let Inst{26} = V; 4116 let Inst{25-23} = 0b001; 4117 let Inst{22} = L; 4118 let Inst{21-15} = offset; 4119 let Inst{14-10} = Rt2; 4120 let Inst{9-5} = Rn; 4121 let Inst{4-0} = Rt; 4122 4123 let DecoderMethod = "DecodePairLdStInstruction"; 4124} 4125 4126let hasSideEffects = 0 in { 4127let mayStore = 0, mayLoad = 1 in 4128class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4129 Operand idxtype, string asm> 4130 : BaseLoadStorePairPostIdx<opc, V, 1, 4131 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4132 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4133 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4134 4135let mayStore = 1, mayLoad = 0 in 4136class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4137 Operand idxtype, string asm> 4138 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4139 (ins regtype:$Rt, regtype:$Rt2, 4140 GPR64sp:$Rn, idxtype:$offset), 4141 asm>, 4142 Sched<[WriteAdr, WriteSTP]>; 4143} // hasSideEffects = 0 4144 4145// (no-allocate) 4146 4147class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4148 string asm> 4149 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4150 bits<5> Rt; 4151 bits<5> Rt2; 4152 bits<5> Rn; 4153 bits<7> offset; 4154 let Inst{31-30} = opc; 4155 let Inst{29-27} = 0b101; 4156 let Inst{26} = V; 4157 let Inst{25-23} = 0b000; 4158 let Inst{22} = L; 4159 let Inst{21-15} = offset; 4160 let Inst{14-10} = Rt2; 4161 let Inst{9-5} = Rn; 4162 let Inst{4-0} = Rt; 4163 4164 let DecoderMethod = "DecodePairLdStInstruction"; 4165} 4166 4167multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4168 Operand indextype, string asm> { 4169 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4170 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4171 (outs regtype:$Rt, regtype:$Rt2), 4172 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4173 Sched<[WriteLD, WriteLDHi]>; 4174 4175 4176 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4177 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4178 GPR64sp:$Rn, 0)>; 4179} 4180 4181multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4182 Operand indextype, string asm> { 4183 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4184 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4185 (ins regtype:$Rt, regtype:$Rt2, 4186 GPR64sp:$Rn, indextype:$offset), 4187 asm>, 4188 Sched<[WriteSTP]>; 4189 4190 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4191 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4192 GPR64sp:$Rn, 0)>; 4193} 4194 4195//--- 4196// Load/store exclusive 4197//--- 4198 4199// True exclusive operations write to and/or read from the system's exclusive 4200// monitors, which as far as a compiler is concerned can be modelled as a 4201// random shared memory address. Hence LoadExclusive mayStore. 4202// 4203// Since these instructions have the undefined register bits set to 1 in 4204// their canonical form, we need a post encoder method to set those bits 4205// to 1 when encoding these instructions. We do this using the 4206// fixLoadStoreExclusive function. This function has template parameters: 4207// 4208// fixLoadStoreExclusive<int hasRs, int hasRt2> 4209// 4210// hasRs indicates that the instruction uses the Rs field, so we won't set 4211// it to 1 (and the same for Rt2). We don't need template parameters for 4212// the other register fields since Rt and Rn are always used. 4213// 4214let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4215class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4216 dag oops, dag iops, string asm, string operands> 4217 : I<oops, iops, asm, operands, "", []> { 4218 let Inst{31-30} = sz; 4219 let Inst{29-24} = 0b001000; 4220 let Inst{23} = o2; 4221 let Inst{22} = L; 4222 let Inst{21} = o1; 4223 let Inst{15} = o0; 4224 4225 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4226} 4227 4228// Neither Rs nor Rt2 operands. 4229class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4230 dag oops, dag iops, string asm, string operands> 4231 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4232 bits<5> Rt; 4233 bits<5> Rn; 4234 let Inst{20-16} = 0b11111; 4235 let Unpredictable{20-16} = 0b11111; 4236 let Inst{14-10} = 0b11111; 4237 let Unpredictable{14-10} = 0b11111; 4238 let Inst{9-5} = Rn; 4239 let Inst{4-0} = Rt; 4240 4241 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4242} 4243 4244// Simple load acquires don't set the exclusive monitor 4245let mayLoad = 1, mayStore = 0 in 4246class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4247 RegisterClass regtype, string asm> 4248 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4249 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4250 Sched<[WriteLD]>; 4251 4252class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4253 RegisterClass regtype, string asm> 4254 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4255 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4256 Sched<[WriteLD]>; 4257 4258class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4259 RegisterClass regtype, string asm> 4260 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4261 (outs regtype:$Rt, regtype:$Rt2), 4262 (ins GPR64sp0:$Rn), asm, 4263 "\t$Rt, $Rt2, [$Rn]">, 4264 Sched<[WriteLD, WriteLDHi]> { 4265 bits<5> Rt; 4266 bits<5> Rt2; 4267 bits<5> Rn; 4268 let Inst{14-10} = Rt2; 4269 let Inst{9-5} = Rn; 4270 let Inst{4-0} = Rt; 4271 4272 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4273} 4274 4275// Simple store release operations do not check the exclusive monitor. 4276let mayLoad = 0, mayStore = 1 in 4277class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4278 RegisterClass regtype, string asm> 4279 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4280 (ins regtype:$Rt, GPR64sp0:$Rn), 4281 asm, "\t$Rt, [$Rn]">, 4282 Sched<[WriteST]>; 4283 4284let mayLoad = 1, mayStore = 1 in 4285class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4286 RegisterClass regtype, string asm> 4287 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4288 (ins regtype:$Rt, GPR64sp0:$Rn), 4289 asm, "\t$Ws, $Rt, [$Rn]">, 4290 Sched<[WriteSTX]> { 4291 bits<5> Ws; 4292 bits<5> Rt; 4293 bits<5> Rn; 4294 let Inst{20-16} = Ws; 4295 let Inst{9-5} = Rn; 4296 let Inst{4-0} = Rt; 4297 4298 let Constraints = "@earlyclobber $Ws"; 4299 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4300} 4301 4302class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4303 RegisterClass regtype, string asm> 4304 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4305 (outs GPR32:$Ws), 4306 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4307 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4308 Sched<[WriteSTX]> { 4309 bits<5> Ws; 4310 bits<5> Rt; 4311 bits<5> Rt2; 4312 bits<5> Rn; 4313 let Inst{20-16} = Ws; 4314 let Inst{14-10} = Rt2; 4315 let Inst{9-5} = Rn; 4316 let Inst{4-0} = Rt; 4317 4318 let Constraints = "@earlyclobber $Ws"; 4319} 4320 4321// Armv8.5-A Memory Tagging Extension 4322class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4323 string asm_opnds, string cstr, dag oops, dag iops> 4324 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4325 Sched<[]> { 4326 bits<5> Rn; 4327 4328 let Inst{31-24} = 0b11011001; 4329 let Inst{23-22} = opc1; 4330 let Inst{21} = 1; 4331 // Inst{20-12} defined by subclass 4332 let Inst{11-10} = opc2; 4333 let Inst{9-5} = Rn; 4334 // Inst{4-0} defined by subclass 4335} 4336 4337class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4338 dag oops, dag iops> 4339 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4340 "", oops, iops> { 4341 bits<5> Rt; 4342 4343 let Inst{20-12} = 0b000000000; 4344 let Inst{4-0} = Rt; 4345 4346 let mayLoad = Load; 4347} 4348 4349class MemTagLoad<string asm_insn, string asm_opnds> 4350 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4351 (outs GPR64:$wback), 4352 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4353 bits<5> Rt; 4354 bits<9> offset; 4355 4356 let Inst{20-12} = offset; 4357 let Inst{4-0} = Rt; 4358 4359 let mayLoad = 1; 4360} 4361 4362class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4363 string asm_opnds, string cstr, dag oops, dag iops> 4364 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4365 bits<5> Rt; 4366 bits<9> offset; 4367 4368 let Inst{20-12} = offset; 4369 let Inst{4-0} = Rt; 4370 4371 let mayStore = 1; 4372} 4373 4374multiclass MemTagStore<bits<2> opc1, string insn> { 4375 def Offset : 4376 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4377 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4378 def PreIndex : 4379 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4380 "$Rn = $wback", 4381 (outs GPR64sp:$wback), 4382 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4383 def PostIndex : 4384 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4385 "$Rn = $wback", 4386 (outs GPR64sp:$wback), 4387 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4388 4389 def : InstAlias<insn # "\t$Rt, [$Rn]", 4390 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4391} 4392 4393//--- 4394// Exception generation 4395//--- 4396 4397let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4398class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4399 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4400 Sched<[WriteSys]> { 4401 bits<16> imm; 4402 let Inst{31-24} = 0b11010100; 4403 let Inst{23-21} = op1; 4404 let Inst{20-5} = imm; 4405 let Inst{4-2} = 0b000; 4406 let Inst{1-0} = ll; 4407} 4408 4409//--- 4410// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4411//-- 4412let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4413class UDFType<bits<16> opc, string asm> 4414 : I<(outs), (ins uimm16:$imm), 4415 asm, "\t$imm", "", []>, 4416 Sched<[]> { 4417 bits<16> imm; 4418 let Inst{31-16} = opc; 4419 let Inst{15-0} = imm; 4420} 4421} 4422let Predicates = [HasFPARMv8] in { 4423 4424//--- 4425// Floating point to integer conversion 4426//--- 4427 4428class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4429 RegisterClass srcType, RegisterClass dstType, 4430 string asm, list<dag> pattern> 4431 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4432 asm, "\t$Rd, $Rn", "", pattern>, 4433 Sched<[WriteFCvt]> { 4434 bits<5> Rd; 4435 bits<5> Rn; 4436 let Inst{30-29} = 0b00; 4437 let Inst{28-24} = 0b11110; 4438 let Inst{23-22} = type; 4439 let Inst{21} = 1; 4440 let Inst{20-19} = rmode; 4441 let Inst{18-16} = opcode; 4442 let Inst{15-10} = 0; 4443 let Inst{9-5} = Rn; 4444 let Inst{4-0} = Rd; 4445} 4446 4447let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4448class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4449 RegisterClass srcType, RegisterClass dstType, 4450 Operand immType, string asm, list<dag> pattern> 4451 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4452 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4453 Sched<[WriteFCvt]> { 4454 bits<5> Rd; 4455 bits<5> Rn; 4456 bits<6> scale; 4457 let Inst{30-29} = 0b00; 4458 let Inst{28-24} = 0b11110; 4459 let Inst{23-22} = type; 4460 let Inst{21} = 0; 4461 let Inst{20-19} = rmode; 4462 let Inst{18-16} = opcode; 4463 let Inst{15-10} = scale; 4464 let Inst{9-5} = Rn; 4465 let Inst{4-0} = Rd; 4466} 4467 4468multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4469 SDPatternOperator OpN> { 4470 // Unscaled half-precision to 32-bit 4471 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4472 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4473 let Inst{31} = 0; // 32-bit GPR flag 4474 let Predicates = [HasFullFP16]; 4475 } 4476 4477 // Unscaled half-precision to 64-bit 4478 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4479 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4480 let Inst{31} = 1; // 64-bit GPR flag 4481 let Predicates = [HasFullFP16]; 4482 } 4483 4484 // Unscaled single-precision to 32-bit 4485 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4486 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4487 let Inst{31} = 0; // 32-bit GPR flag 4488 } 4489 4490 // Unscaled single-precision to 64-bit 4491 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4492 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4493 let Inst{31} = 1; // 64-bit GPR flag 4494 } 4495 4496 // Unscaled double-precision to 32-bit 4497 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4498 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4499 let Inst{31} = 0; // 32-bit GPR flag 4500 } 4501 4502 // Unscaled double-precision to 64-bit 4503 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4504 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4505 let Inst{31} = 1; // 64-bit GPR flag 4506 } 4507} 4508 4509multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4510 SDPatternOperator OpN> { 4511 // Scaled half-precision to 32-bit 4512 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4513 fixedpoint_f16_i32, asm, 4514 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4515 fixedpoint_f16_i32:$scale)))]> { 4516 let Inst{31} = 0; // 32-bit GPR flag 4517 let scale{5} = 1; 4518 let Predicates = [HasFullFP16]; 4519 } 4520 4521 // Scaled half-precision to 64-bit 4522 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4523 fixedpoint_f16_i64, asm, 4524 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4525 fixedpoint_f16_i64:$scale)))]> { 4526 let Inst{31} = 1; // 64-bit GPR flag 4527 let Predicates = [HasFullFP16]; 4528 } 4529 4530 // Scaled single-precision to 32-bit 4531 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4532 fixedpoint_f32_i32, asm, 4533 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4534 fixedpoint_f32_i32:$scale)))]> { 4535 let Inst{31} = 0; // 32-bit GPR flag 4536 let scale{5} = 1; 4537 } 4538 4539 // Scaled single-precision to 64-bit 4540 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4541 fixedpoint_f32_i64, asm, 4542 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4543 fixedpoint_f32_i64:$scale)))]> { 4544 let Inst{31} = 1; // 64-bit GPR flag 4545 } 4546 4547 // Scaled double-precision to 32-bit 4548 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4549 fixedpoint_f64_i32, asm, 4550 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4551 fixedpoint_f64_i32:$scale)))]> { 4552 let Inst{31} = 0; // 32-bit GPR flag 4553 let scale{5} = 1; 4554 } 4555 4556 // Scaled double-precision to 64-bit 4557 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4558 fixedpoint_f64_i64, asm, 4559 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4560 fixedpoint_f64_i64:$scale)))]> { 4561 let Inst{31} = 1; // 64-bit GPR flag 4562 } 4563} 4564 4565//--- 4566// Integer to floating point conversion 4567//--- 4568 4569let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4570class BaseIntegerToFP<bit isUnsigned, 4571 RegisterClass srcType, RegisterClass dstType, 4572 Operand immType, string asm, list<dag> pattern> 4573 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4574 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4575 Sched<[WriteFCvt]> { 4576 bits<5> Rd; 4577 bits<5> Rn; 4578 bits<6> scale; 4579 let Inst{30-24} = 0b0011110; 4580 let Inst{21-17} = 0b00001; 4581 let Inst{16} = isUnsigned; 4582 let Inst{15-10} = scale; 4583 let Inst{9-5} = Rn; 4584 let Inst{4-0} = Rd; 4585} 4586 4587class BaseIntegerToFPUnscaled<bit isUnsigned, 4588 RegisterClass srcType, RegisterClass dstType, 4589 ValueType dvt, string asm, SDNode node> 4590 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4591 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4592 Sched<[WriteFCvt]> { 4593 bits<5> Rd; 4594 bits<5> Rn; 4595 bits<6> scale; 4596 let Inst{30-24} = 0b0011110; 4597 let Inst{21-17} = 0b10001; 4598 let Inst{16} = isUnsigned; 4599 let Inst{15-10} = 0b000000; 4600 let Inst{9-5} = Rn; 4601 let Inst{4-0} = Rd; 4602} 4603 4604multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 4605 // Unscaled 4606 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4607 let Inst{31} = 0; // 32-bit GPR flag 4608 let Inst{23-22} = 0b11; // 16-bit FPR flag 4609 let Predicates = [HasFullFP16]; 4610 } 4611 4612 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4613 let Inst{31} = 0; // 32-bit GPR flag 4614 let Inst{23-22} = 0b00; // 32-bit FPR flag 4615 } 4616 4617 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4618 let Inst{31} = 0; // 32-bit GPR flag 4619 let Inst{23-22} = 0b01; // 64-bit FPR flag 4620 } 4621 4622 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4623 let Inst{31} = 1; // 64-bit GPR flag 4624 let Inst{23-22} = 0b11; // 16-bit FPR flag 4625 let Predicates = [HasFullFP16]; 4626 } 4627 4628 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4629 let Inst{31} = 1; // 64-bit GPR flag 4630 let Inst{23-22} = 0b00; // 32-bit FPR flag 4631 } 4632 4633 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4634 let Inst{31} = 1; // 64-bit GPR flag 4635 let Inst{23-22} = 0b01; // 64-bit FPR flag 4636 } 4637 4638 // Scaled 4639 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4640 [(set (f16 FPR16:$Rd), 4641 (fdiv (node GPR32:$Rn), 4642 fixedpoint_f16_i32:$scale))]> { 4643 let Inst{31} = 0; // 32-bit GPR flag 4644 let Inst{23-22} = 0b11; // 16-bit FPR flag 4645 let scale{5} = 1; 4646 let Predicates = [HasFullFP16]; 4647 } 4648 4649 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4650 [(set FPR32:$Rd, 4651 (fdiv (node GPR32:$Rn), 4652 fixedpoint_f32_i32:$scale))]> { 4653 let Inst{31} = 0; // 32-bit GPR flag 4654 let Inst{23-22} = 0b00; // 32-bit FPR flag 4655 let scale{5} = 1; 4656 } 4657 4658 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4659 [(set FPR64:$Rd, 4660 (fdiv (node GPR32:$Rn), 4661 fixedpoint_f64_i32:$scale))]> { 4662 let Inst{31} = 0; // 32-bit GPR flag 4663 let Inst{23-22} = 0b01; // 64-bit FPR flag 4664 let scale{5} = 1; 4665 } 4666 4667 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4668 [(set (f16 FPR16:$Rd), 4669 (fdiv (node GPR64:$Rn), 4670 fixedpoint_f16_i64:$scale))]> { 4671 let Inst{31} = 1; // 64-bit GPR flag 4672 let Inst{23-22} = 0b11; // 16-bit FPR flag 4673 let Predicates = [HasFullFP16]; 4674 } 4675 4676 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4677 [(set FPR32:$Rd, 4678 (fdiv (node GPR64:$Rn), 4679 fixedpoint_f32_i64:$scale))]> { 4680 let Inst{31} = 1; // 64-bit GPR flag 4681 let Inst{23-22} = 0b00; // 32-bit FPR flag 4682 } 4683 4684 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4685 [(set FPR64:$Rd, 4686 (fdiv (node GPR64:$Rn), 4687 fixedpoint_f64_i64:$scale))]> { 4688 let Inst{31} = 1; // 64-bit GPR flag 4689 let Inst{23-22} = 0b01; // 64-bit FPR flag 4690 } 4691} 4692 4693//--- 4694// Unscaled integer <-> floating point conversion (i.e. FMOV) 4695//--- 4696 4697let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4698class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4699 RegisterClass srcType, RegisterClass dstType, 4700 string asm> 4701 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4702 // We use COPY_TO_REGCLASS for these bitconvert operations. 4703 // copyPhysReg() expands the resultant COPY instructions after 4704 // regalloc is done. This gives greater freedom for the allocator 4705 // and related passes (coalescing, copy propagation, et. al.) to 4706 // be more effective. 4707 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4708 Sched<[WriteFCopy]> { 4709 bits<5> Rd; 4710 bits<5> Rn; 4711 let Inst{30-24} = 0b0011110; 4712 let Inst{21} = 1; 4713 let Inst{20-19} = rmode; 4714 let Inst{18-16} = opcode; 4715 let Inst{15-10} = 0b000000; 4716 let Inst{9-5} = Rn; 4717 let Inst{4-0} = Rd; 4718} 4719 4720let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4721class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4722 RegisterClass srcType, RegisterOperand dstType, string asm, 4723 string kind> 4724 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4725 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4726 Sched<[WriteFCopy]> { 4727 bits<5> Rd; 4728 bits<5> Rn; 4729 let Inst{30-23} = 0b00111101; 4730 let Inst{21} = 1; 4731 let Inst{20-19} = rmode; 4732 let Inst{18-16} = opcode; 4733 let Inst{15-10} = 0b000000; 4734 let Inst{9-5} = Rn; 4735 let Inst{4-0} = Rd; 4736 4737 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4738} 4739 4740let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4741class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4742 RegisterOperand srcType, RegisterClass dstType, string asm, 4743 string kind> 4744 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4745 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4746 Sched<[WriteFCopy]> { 4747 bits<5> Rd; 4748 bits<5> Rn; 4749 let Inst{30-23} = 0b00111101; 4750 let Inst{21} = 1; 4751 let Inst{20-19} = rmode; 4752 let Inst{18-16} = opcode; 4753 let Inst{15-10} = 0b000000; 4754 let Inst{9-5} = Rn; 4755 let Inst{4-0} = Rd; 4756 4757 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4758} 4759 4760 4761multiclass UnscaledConversion<string asm> { 4762 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4763 let Inst{31} = 0; // 32-bit GPR flag 4764 let Inst{23-22} = 0b11; // 16-bit FPR flag 4765 let Predicates = [HasFullFP16]; 4766 } 4767 4768 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4769 let Inst{31} = 1; // 64-bit GPR flag 4770 let Inst{23-22} = 0b11; // 16-bit FPR flag 4771 let Predicates = [HasFullFP16]; 4772 } 4773 4774 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4775 let Inst{31} = 0; // 32-bit GPR flag 4776 let Inst{23-22} = 0b00; // 32-bit FPR flag 4777 } 4778 4779 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4780 let Inst{31} = 1; // 64-bit GPR flag 4781 let Inst{23-22} = 0b01; // 64-bit FPR flag 4782 } 4783 4784 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4785 let Inst{31} = 0; // 32-bit GPR flag 4786 let Inst{23-22} = 0b11; // 16-bit FPR flag 4787 let Predicates = [HasFullFP16]; 4788 } 4789 4790 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4791 let Inst{31} = 1; // 64-bit GPR flag 4792 let Inst{23-22} = 0b11; // 16-bit FPR flag 4793 let Predicates = [HasFullFP16]; 4794 } 4795 4796 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4797 let Inst{31} = 0; // 32-bit GPR flag 4798 let Inst{23-22} = 0b00; // 32-bit FPR flag 4799 } 4800 4801 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4802 let Inst{31} = 1; // 64-bit GPR flag 4803 let Inst{23-22} = 0b01; // 64-bit FPR flag 4804 } 4805 4806 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4807 asm, ".d"> { 4808 let Inst{31} = 1; 4809 let Inst{22} = 0; 4810 } 4811 4812 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4813 asm, ".d"> { 4814 let Inst{31} = 1; 4815 let Inst{22} = 0; 4816 } 4817} 4818 4819//--- 4820// Floating point conversion 4821//--- 4822 4823class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4824 RegisterClass srcType, string asm, list<dag> pattern> 4825 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4826 Sched<[WriteFCvt]> { 4827 bits<5> Rd; 4828 bits<5> Rn; 4829 let Inst{31-24} = 0b00011110; 4830 let Inst{23-22} = type; 4831 let Inst{21-17} = 0b10001; 4832 let Inst{16-15} = opcode; 4833 let Inst{14-10} = 0b10000; 4834 let Inst{9-5} = Rn; 4835 let Inst{4-0} = Rd; 4836} 4837 4838multiclass FPConversion<string asm> { 4839 // Double-precision to Half-precision 4840 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4841 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4842 4843 // Double-precision to Single-precision 4844 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4845 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4846 4847 // Half-precision to Double-precision 4848 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4849 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4850 4851 // Half-precision to Single-precision 4852 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4853 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4854 4855 // Single-precision to Double-precision 4856 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4857 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4858 4859 // Single-precision to Half-precision 4860 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4861 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 4862} 4863 4864//--- 4865// Single operand floating point data processing 4866//--- 4867 4868let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4869class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4870 ValueType vt, string asm, SDPatternOperator node> 4871 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4872 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4873 Sched<[WriteF]> { 4874 bits<5> Rd; 4875 bits<5> Rn; 4876 let Inst{31-24} = 0b00011110; 4877 let Inst{21} = 0b1; 4878 let Inst{20-15} = opcode; 4879 let Inst{14-10} = 0b10000; 4880 let Inst{9-5} = Rn; 4881 let Inst{4-0} = Rd; 4882} 4883 4884multiclass SingleOperandFPData<bits<4> opcode, string asm, 4885 SDPatternOperator node = null_frag> { 4886 4887 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4888 let Inst{23-22} = 0b11; // 16-bit size flag 4889 let Predicates = [HasFullFP16]; 4890 } 4891 4892 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4893 let Inst{23-22} = 0b00; // 32-bit size flag 4894 } 4895 4896 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4897 let Inst{23-22} = 0b01; // 64-bit size flag 4898 } 4899} 4900 4901multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4902 SDPatternOperator node = null_frag>{ 4903 4904 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4905 let Inst{23-22} = 0b00; // 32-bit registers 4906 } 4907 4908 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4909 let Inst{23-22} = 0b01; // 64-bit registers 4910 } 4911} 4912 4913// FRInt[32|64][Z|N] instructions 4914multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4915 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4916 4917//--- 4918// Two operand floating point data processing 4919//--- 4920 4921let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4922class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4923 string asm, list<dag> pat> 4924 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4925 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4926 Sched<[WriteF]> { 4927 bits<5> Rd; 4928 bits<5> Rn; 4929 bits<5> Rm; 4930 let Inst{31-24} = 0b00011110; 4931 let Inst{21} = 1; 4932 let Inst{20-16} = Rm; 4933 let Inst{15-12} = opcode; 4934 let Inst{11-10} = 0b10; 4935 let Inst{9-5} = Rn; 4936 let Inst{4-0} = Rd; 4937} 4938 4939multiclass TwoOperandFPData<bits<4> opcode, string asm, 4940 SDPatternOperator node = null_frag> { 4941 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4942 [(set (f16 FPR16:$Rd), 4943 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4944 let Inst{23-22} = 0b11; // 16-bit size flag 4945 let Predicates = [HasFullFP16]; 4946 } 4947 4948 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4949 [(set (f32 FPR32:$Rd), 4950 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4951 let Inst{23-22} = 0b00; // 32-bit size flag 4952 } 4953 4954 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4955 [(set (f64 FPR64:$Rd), 4956 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4957 let Inst{23-22} = 0b01; // 64-bit size flag 4958 } 4959} 4960 4961multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4962 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4963 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 4964 let Inst{23-22} = 0b11; // 16-bit size flag 4965 let Predicates = [HasFullFP16]; 4966 } 4967 4968 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4969 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4970 let Inst{23-22} = 0b00; // 32-bit size flag 4971 } 4972 4973 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4974 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 4975 let Inst{23-22} = 0b01; // 64-bit size flag 4976 } 4977} 4978 4979 4980//--- 4981// Three operand floating point data processing 4982//--- 4983 4984class BaseThreeOperandFPData<bit isNegated, bit isSub, 4985 RegisterClass regtype, string asm, list<dag> pat> 4986 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 4987 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 4988 Sched<[WriteFMul]> { 4989 bits<5> Rd; 4990 bits<5> Rn; 4991 bits<5> Rm; 4992 bits<5> Ra; 4993 let Inst{31-24} = 0b00011111; 4994 let Inst{21} = isNegated; 4995 let Inst{20-16} = Rm; 4996 let Inst{15} = isSub; 4997 let Inst{14-10} = Ra; 4998 let Inst{9-5} = Rn; 4999 let Inst{4-0} = Rd; 5000} 5001 5002multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5003 SDPatternOperator node> { 5004 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5005 [(set (f16 FPR16:$Rd), 5006 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5007 let Inst{23-22} = 0b11; // 16-bit size flag 5008 let Predicates = [HasFullFP16]; 5009 } 5010 5011 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5012 [(set FPR32:$Rd, 5013 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5014 let Inst{23-22} = 0b00; // 32-bit size flag 5015 } 5016 5017 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5018 [(set FPR64:$Rd, 5019 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5020 let Inst{23-22} = 0b01; // 64-bit size flag 5021 } 5022} 5023 5024//--- 5025// Floating point data comparisons 5026//--- 5027 5028let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5029class BaseOneOperandFPComparison<bit signalAllNans, 5030 RegisterClass regtype, string asm, 5031 list<dag> pat> 5032 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5033 Sched<[WriteFCmp]> { 5034 bits<5> Rn; 5035 let Inst{31-24} = 0b00011110; 5036 let Inst{21} = 1; 5037 5038 let Inst{15-10} = 0b001000; 5039 let Inst{9-5} = Rn; 5040 let Inst{4} = signalAllNans; 5041 let Inst{3-0} = 0b1000; 5042 5043 // Rm should be 0b00000 canonically, but we need to accept any value. 5044 let PostEncoderMethod = "fixOneOperandFPComparison"; 5045} 5046 5047let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5048class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5049 string asm, list<dag> pat> 5050 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5051 Sched<[WriteFCmp]> { 5052 bits<5> Rm; 5053 bits<5> Rn; 5054 let Inst{31-24} = 0b00011110; 5055 let Inst{21} = 1; 5056 let Inst{20-16} = Rm; 5057 let Inst{15-10} = 0b001000; 5058 let Inst{9-5} = Rn; 5059 let Inst{4} = signalAllNans; 5060 let Inst{3-0} = 0b0000; 5061} 5062 5063multiclass FPComparison<bit signalAllNans, string asm, 5064 SDPatternOperator OpNode = null_frag> { 5065 let Defs = [NZCV] in { 5066 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5067 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5068 let Inst{23-22} = 0b11; 5069 let Predicates = [HasFullFP16]; 5070 } 5071 5072 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5073 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5074 let Inst{23-22} = 0b11; 5075 let Predicates = [HasFullFP16]; 5076 } 5077 5078 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5079 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5080 let Inst{23-22} = 0b00; 5081 } 5082 5083 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5084 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5085 let Inst{23-22} = 0b00; 5086 } 5087 5088 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5089 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5090 let Inst{23-22} = 0b01; 5091 } 5092 5093 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5094 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5095 let Inst{23-22} = 0b01; 5096 } 5097 } // Defs = [NZCV] 5098} 5099 5100//--- 5101// Floating point conditional comparisons 5102//--- 5103 5104let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5105class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5106 string mnemonic, list<dag> pat> 5107 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5108 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5109 Sched<[WriteFCmp]> { 5110 let Uses = [NZCV]; 5111 let Defs = [NZCV]; 5112 5113 bits<5> Rn; 5114 bits<5> Rm; 5115 bits<4> nzcv; 5116 bits<4> cond; 5117 5118 let Inst{31-24} = 0b00011110; 5119 let Inst{21} = 1; 5120 let Inst{20-16} = Rm; 5121 let Inst{15-12} = cond; 5122 let Inst{11-10} = 0b01; 5123 let Inst{9-5} = Rn; 5124 let Inst{4} = signalAllNans; 5125 let Inst{3-0} = nzcv; 5126} 5127 5128multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5129 SDPatternOperator OpNode = null_frag> { 5130 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5131 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5132 (i32 imm:$cond), NZCV))]> { 5133 let Inst{23-22} = 0b11; 5134 let Predicates = [HasFullFP16]; 5135 } 5136 5137 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5138 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5139 (i32 imm:$cond), NZCV))]> { 5140 let Inst{23-22} = 0b00; 5141 } 5142 5143 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5144 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5145 (i32 imm:$cond), NZCV))]> { 5146 let Inst{23-22} = 0b01; 5147 } 5148} 5149 5150//--- 5151// Floating point conditional select 5152//--- 5153 5154class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5155 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5156 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5157 [(set regtype:$Rd, 5158 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5159 (i32 imm:$cond), NZCV))]>, 5160 Sched<[WriteF]> { 5161 bits<5> Rd; 5162 bits<5> Rn; 5163 bits<5> Rm; 5164 bits<4> cond; 5165 5166 let Inst{31-24} = 0b00011110; 5167 let Inst{21} = 1; 5168 let Inst{20-16} = Rm; 5169 let Inst{15-12} = cond; 5170 let Inst{11-10} = 0b11; 5171 let Inst{9-5} = Rn; 5172 let Inst{4-0} = Rd; 5173} 5174 5175multiclass FPCondSelect<string asm> { 5176 let Uses = [NZCV] in { 5177 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5178 let Inst{23-22} = 0b11; 5179 let Predicates = [HasFullFP16]; 5180 } 5181 5182 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5183 let Inst{23-22} = 0b00; 5184 } 5185 5186 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5187 let Inst{23-22} = 0b01; 5188 } 5189 } // Uses = [NZCV] 5190} 5191 5192//--- 5193// Floating move immediate 5194//--- 5195 5196class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5197 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5198 [(set regtype:$Rd, fpimmtype:$imm)]>, 5199 Sched<[WriteFImm]> { 5200 bits<5> Rd; 5201 bits<8> imm; 5202 let Inst{31-24} = 0b00011110; 5203 let Inst{21} = 1; 5204 let Inst{20-13} = imm; 5205 let Inst{12-5} = 0b10000000; 5206 let Inst{4-0} = Rd; 5207} 5208 5209multiclass FPMoveImmediate<string asm> { 5210 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5211 let Inst{23-22} = 0b11; 5212 let Predicates = [HasFullFP16]; 5213 } 5214 5215 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5216 let Inst{23-22} = 0b00; 5217 } 5218 5219 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5220 let Inst{23-22} = 0b01; 5221 } 5222} 5223} // end of 'let Predicates = [HasFPARMv8]' 5224 5225//---------------------------------------------------------------------------- 5226// AdvSIMD 5227//---------------------------------------------------------------------------- 5228 5229let Predicates = [HasNEON] in { 5230 5231//---------------------------------------------------------------------------- 5232// AdvSIMD three register vector instructions 5233//---------------------------------------------------------------------------- 5234 5235let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5236class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5237 RegisterOperand regtype, string asm, string kind, 5238 list<dag> pattern> 5239 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5240 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5241 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5242 Sched<[WriteV]> { 5243 bits<5> Rd; 5244 bits<5> Rn; 5245 bits<5> Rm; 5246 let Inst{31} = 0; 5247 let Inst{30} = Q; 5248 let Inst{29} = U; 5249 let Inst{28-24} = 0b01110; 5250 let Inst{23-21} = size; 5251 let Inst{20-16} = Rm; 5252 let Inst{15-11} = opcode; 5253 let Inst{10} = 1; 5254 let Inst{9-5} = Rn; 5255 let Inst{4-0} = Rd; 5256} 5257 5258let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5259class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5260 RegisterOperand regtype, string asm, string kind, 5261 list<dag> pattern> 5262 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5263 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5264 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5265 Sched<[WriteV]> { 5266 bits<5> Rd; 5267 bits<5> Rn; 5268 bits<5> Rm; 5269 let Inst{31} = 0; 5270 let Inst{30} = Q; 5271 let Inst{29} = U; 5272 let Inst{28-24} = 0b01110; 5273 let Inst{23-21} = size; 5274 let Inst{20-16} = Rm; 5275 let Inst{15-11} = opcode; 5276 let Inst{10} = 1; 5277 let Inst{9-5} = Rn; 5278 let Inst{4-0} = Rd; 5279} 5280 5281let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5282class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5283 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5284 Sched<[WriteV]>; 5285 5286multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5287 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5288 [(set (v8i8 V64:$dst), 5289 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5290 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5291 [(set (v16i8 V128:$dst), 5292 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5293 (v16i8 V128:$Rm)))]>; 5294 5295 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5296 (v4i16 V64:$RHS))), 5297 (!cast<Instruction>(NAME#"v8i8") 5298 V64:$LHS, V64:$MHS, V64:$RHS)>; 5299 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5300 (v2i32 V64:$RHS))), 5301 (!cast<Instruction>(NAME#"v8i8") 5302 V64:$LHS, V64:$MHS, V64:$RHS)>; 5303 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5304 (v1i64 V64:$RHS))), 5305 (!cast<Instruction>(NAME#"v8i8") 5306 V64:$LHS, V64:$MHS, V64:$RHS)>; 5307 5308 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5309 (v8i16 V128:$RHS))), 5310 (!cast<Instruction>(NAME#"v16i8") 5311 V128:$LHS, V128:$MHS, V128:$RHS)>; 5312 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5313 (v4i32 V128:$RHS))), 5314 (!cast<Instruction>(NAME#"v16i8") 5315 V128:$LHS, V128:$MHS, V128:$RHS)>; 5316 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5317 (v2i64 V128:$RHS))), 5318 (!cast<Instruction>(NAME#"v16i8") 5319 V128:$LHS, V128:$MHS, V128:$RHS)>; 5320} 5321 5322// All operand sizes distinguished in the encoding. 5323multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5324 SDPatternOperator OpNode> { 5325 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5326 asm, ".8b", 5327 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5328 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5329 asm, ".16b", 5330 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5331 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5332 asm, ".4h", 5333 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5334 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5335 asm, ".8h", 5336 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5337 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5338 asm, ".2s", 5339 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5340 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5341 asm, ".4s", 5342 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5343 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5344 asm, ".2d", 5345 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5346} 5347 5348multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5349 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5350 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5351 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5352 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5353 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5354 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5355 5356 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5357 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5358 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5359 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5360 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5361 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5362 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5363 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5364} 5365 5366// As above, but D sized elements unsupported. 5367multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5368 SDPatternOperator OpNode> { 5369 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5370 asm, ".8b", 5371 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5372 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5373 asm, ".16b", 5374 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5375 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5376 asm, ".4h", 5377 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5378 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5379 asm, ".8h", 5380 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5381 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5382 asm, ".2s", 5383 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5384 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5385 asm, ".4s", 5386 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5387} 5388 5389multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5390 SDPatternOperator OpNode> { 5391 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5392 asm, ".8b", 5393 [(set (v8i8 V64:$dst), 5394 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5395 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5396 asm, ".16b", 5397 [(set (v16i8 V128:$dst), 5398 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5399 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5400 asm, ".4h", 5401 [(set (v4i16 V64:$dst), 5402 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5403 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5404 asm, ".8h", 5405 [(set (v8i16 V128:$dst), 5406 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5407 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5408 asm, ".2s", 5409 [(set (v2i32 V64:$dst), 5410 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5411 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5412 asm, ".4s", 5413 [(set (v4i32 V128:$dst), 5414 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5415} 5416 5417// As above, but only B sized elements supported. 5418multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5419 SDPatternOperator OpNode> { 5420 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5421 asm, ".8b", 5422 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5423 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5424 asm, ".16b", 5425 [(set (v16i8 V128:$Rd), 5426 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5427} 5428 5429// As above, but only floating point elements supported. 5430multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5431 string asm, SDPatternOperator OpNode> { 5432 let Predicates = [HasNEON, HasFullFP16] in { 5433 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5434 asm, ".4h", 5435 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5436 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5437 asm, ".8h", 5438 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5439 } // Predicates = [HasNEON, HasFullFP16] 5440 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5441 asm, ".2s", 5442 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5443 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5444 asm, ".4s", 5445 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5446 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5447 asm, ".2d", 5448 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5449} 5450 5451multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5452 string asm, 5453 SDPatternOperator OpNode> { 5454 let Predicates = [HasNEON, HasFullFP16] in { 5455 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5456 asm, ".4h", 5457 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5458 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5459 asm, ".8h", 5460 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5461 } // Predicates = [HasNEON, HasFullFP16] 5462 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5463 asm, ".2s", 5464 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5465 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5466 asm, ".4s", 5467 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5468 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5469 asm, ".2d", 5470 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5471} 5472 5473multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5474 string asm, SDPatternOperator OpNode> { 5475 let Predicates = [HasNEON, HasFullFP16] in { 5476 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5477 asm, ".4h", 5478 [(set (v4f16 V64:$dst), 5479 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5480 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5481 asm, ".8h", 5482 [(set (v8f16 V128:$dst), 5483 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5484 } // Predicates = [HasNEON, HasFullFP16] 5485 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5486 asm, ".2s", 5487 [(set (v2f32 V64:$dst), 5488 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5489 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5490 asm, ".4s", 5491 [(set (v4f32 V128:$dst), 5492 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5493 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5494 asm, ".2d", 5495 [(set (v2f64 V128:$dst), 5496 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5497} 5498 5499// As above, but D and B sized elements unsupported. 5500multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5501 SDPatternOperator OpNode> { 5502 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5503 asm, ".4h", 5504 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5505 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5506 asm, ".8h", 5507 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5508 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5509 asm, ".2s", 5510 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5511 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5512 asm, ".4s", 5513 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5514} 5515 5516// Logical three vector ops share opcode bits, and only use B sized elements. 5517multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5518 SDPatternOperator OpNode = null_frag> { 5519 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5520 asm, ".8b", 5521 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5522 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5523 asm, ".16b", 5524 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5525 5526 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5527 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5528 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5529 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5530 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5531 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5532 5533 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5534 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5535 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5536 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5537 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5538 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5539} 5540 5541multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5542 string asm, SDPatternOperator OpNode = null_frag> { 5543 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5544 asm, ".8b", 5545 [(set (v8i8 V64:$dst), 5546 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5547 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5548 asm, ".16b", 5549 [(set (v16i8 V128:$dst), 5550 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5551 (v16i8 V128:$Rm)))]>; 5552 5553 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5554 (v4i16 V64:$RHS))), 5555 (!cast<Instruction>(NAME#"v8i8") 5556 V64:$LHS, V64:$MHS, V64:$RHS)>; 5557 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5558 (v2i32 V64:$RHS))), 5559 (!cast<Instruction>(NAME#"v8i8") 5560 V64:$LHS, V64:$MHS, V64:$RHS)>; 5561 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5562 (v1i64 V64:$RHS))), 5563 (!cast<Instruction>(NAME#"v8i8") 5564 V64:$LHS, V64:$MHS, V64:$RHS)>; 5565 5566 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5567 (v8i16 V128:$RHS))), 5568 (!cast<Instruction>(NAME#"v16i8") 5569 V128:$LHS, V128:$MHS, V128:$RHS)>; 5570 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5571 (v4i32 V128:$RHS))), 5572 (!cast<Instruction>(NAME#"v16i8") 5573 V128:$LHS, V128:$MHS, V128:$RHS)>; 5574 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5575 (v2i64 V128:$RHS))), 5576 (!cast<Instruction>(NAME#"v16i8") 5577 V128:$LHS, V128:$MHS, V128:$RHS)>; 5578} 5579 5580// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5581// bytes from S-sized elements. 5582class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5583 string kind2, RegisterOperand RegType, 5584 ValueType AccumType, ValueType InputType, 5585 SDPatternOperator OpNode> : 5586 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5587 [(set (AccumType RegType:$dst), 5588 (OpNode (AccumType RegType:$Rd), 5589 (InputType RegType:$Rn), 5590 (InputType RegType:$Rm)))]> { 5591 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5592} 5593 5594multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5595 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5596 v2i32, v8i8, OpNode>; 5597 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5598 v4i32, v16i8, OpNode>; 5599} 5600 5601// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5602// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5603// 8H to 4S, when Q=1). 5604class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5605 string kind2, RegisterOperand RegType, 5606 ValueType AccumType, ValueType InputType, 5607 SDPatternOperator OpNode> : 5608 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5609 [(set (AccumType RegType:$dst), 5610 (OpNode (AccumType RegType:$Rd), 5611 (InputType RegType:$Rn), 5612 (InputType RegType:$Rm)))]> { 5613 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5614 let Inst{13} = b13; 5615} 5616 5617multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5618 SDPatternOperator OpNode> { 5619 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5620 v2f32, v4f16, OpNode>; 5621 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5622 v4f32, v8f16, OpNode>; 5623} 5624 5625 5626//---------------------------------------------------------------------------- 5627// AdvSIMD two register vector instructions. 5628//---------------------------------------------------------------------------- 5629 5630let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5631class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5632 bits<2> size2, RegisterOperand regtype, string asm, 5633 string dstkind, string srckind, list<dag> pattern> 5634 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5635 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5636 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5637 Sched<[WriteV]> { 5638 bits<5> Rd; 5639 bits<5> Rn; 5640 let Inst{31} = 0; 5641 let Inst{30} = Q; 5642 let Inst{29} = U; 5643 let Inst{28-24} = 0b01110; 5644 let Inst{23-22} = size; 5645 let Inst{21} = 0b1; 5646 let Inst{20-19} = size2; 5647 let Inst{18-17} = 0b00; 5648 let Inst{16-12} = opcode; 5649 let Inst{11-10} = 0b10; 5650 let Inst{9-5} = Rn; 5651 let Inst{4-0} = Rd; 5652} 5653 5654let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5655class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5656 bits<2> size2, RegisterOperand regtype, 5657 string asm, string dstkind, string srckind, 5658 list<dag> pattern> 5659 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5660 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5661 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5662 Sched<[WriteV]> { 5663 bits<5> Rd; 5664 bits<5> Rn; 5665 let Inst{31} = 0; 5666 let Inst{30} = Q; 5667 let Inst{29} = U; 5668 let Inst{28-24} = 0b01110; 5669 let Inst{23-22} = size; 5670 let Inst{21} = 0b1; 5671 let Inst{20-19} = size2; 5672 let Inst{18-17} = 0b00; 5673 let Inst{16-12} = opcode; 5674 let Inst{11-10} = 0b10; 5675 let Inst{9-5} = Rn; 5676 let Inst{4-0} = Rd; 5677} 5678 5679// Supports B, H, and S element sizes. 5680multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5681 SDPatternOperator OpNode> { 5682 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5683 asm, ".8b", ".8b", 5684 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5685 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5686 asm, ".16b", ".16b", 5687 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5688 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5689 asm, ".4h", ".4h", 5690 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5691 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5692 asm, ".8h", ".8h", 5693 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5694 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5695 asm, ".2s", ".2s", 5696 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5697 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5698 asm, ".4s", ".4s", 5699 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5700} 5701 5702class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5703 RegisterOperand regtype, string asm, string dstkind, 5704 string srckind, string amount> 5705 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5706 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5707 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5708 Sched<[WriteV]> { 5709 bits<5> Rd; 5710 bits<5> Rn; 5711 let Inst{31} = 0; 5712 let Inst{30} = Q; 5713 let Inst{29-24} = 0b101110; 5714 let Inst{23-22} = size; 5715 let Inst{21-10} = 0b100001001110; 5716 let Inst{9-5} = Rn; 5717 let Inst{4-0} = Rd; 5718} 5719 5720multiclass SIMDVectorLShiftLongBySizeBHS { 5721 let hasSideEffects = 0 in { 5722 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5723 "shll", ".8h", ".8b", "8">; 5724 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5725 "shll2", ".8h", ".16b", "8">; 5726 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5727 "shll", ".4s", ".4h", "16">; 5728 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5729 "shll2", ".4s", ".8h", "16">; 5730 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5731 "shll", ".2d", ".2s", "32">; 5732 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5733 "shll2", ".2d", ".4s", "32">; 5734 } 5735} 5736 5737// Supports all element sizes. 5738multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5739 SDPatternOperator OpNode> { 5740 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5741 asm, ".4h", ".8b", 5742 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5743 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5744 asm, ".8h", ".16b", 5745 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5746 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5747 asm, ".2s", ".4h", 5748 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5749 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5750 asm, ".4s", ".8h", 5751 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5752 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5753 asm, ".1d", ".2s", 5754 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5755 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5756 asm, ".2d", ".4s", 5757 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5758} 5759 5760multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5761 SDPatternOperator OpNode> { 5762 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5763 asm, ".4h", ".8b", 5764 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5765 (v8i8 V64:$Rn)))]>; 5766 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5767 asm, ".8h", ".16b", 5768 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5769 (v16i8 V128:$Rn)))]>; 5770 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5771 asm, ".2s", ".4h", 5772 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5773 (v4i16 V64:$Rn)))]>; 5774 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5775 asm, ".4s", ".8h", 5776 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5777 (v8i16 V128:$Rn)))]>; 5778 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5779 asm, ".1d", ".2s", 5780 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5781 (v2i32 V64:$Rn)))]>; 5782 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5783 asm, ".2d", ".4s", 5784 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5785 (v4i32 V128:$Rn)))]>; 5786} 5787 5788// Supports all element sizes, except 1xD. 5789multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5790 SDPatternOperator OpNode> { 5791 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5792 asm, ".8b", ".8b", 5793 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5794 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5795 asm, ".16b", ".16b", 5796 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5797 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5798 asm, ".4h", ".4h", 5799 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5800 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5801 asm, ".8h", ".8h", 5802 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5803 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5804 asm, ".2s", ".2s", 5805 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5806 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5807 asm, ".4s", ".4s", 5808 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5809 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5810 asm, ".2d", ".2d", 5811 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5812} 5813 5814multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5815 SDPatternOperator OpNode = null_frag> { 5816 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5817 asm, ".8b", ".8b", 5818 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5819 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5820 asm, ".16b", ".16b", 5821 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5822 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5823 asm, ".4h", ".4h", 5824 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5825 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5826 asm, ".8h", ".8h", 5827 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5828 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5829 asm, ".2s", ".2s", 5830 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5831 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5832 asm, ".4s", ".4s", 5833 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5834 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5835 asm, ".2d", ".2d", 5836 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5837} 5838 5839 5840// Supports only B element sizes. 5841multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5842 SDPatternOperator OpNode> { 5843 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5844 asm, ".8b", ".8b", 5845 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5846 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5847 asm, ".16b", ".16b", 5848 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5849 5850} 5851 5852// Supports only B and H element sizes. 5853multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5854 SDPatternOperator OpNode> { 5855 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5856 asm, ".8b", ".8b", 5857 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5858 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5859 asm, ".16b", ".16b", 5860 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5861 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5862 asm, ".4h", ".4h", 5863 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5864 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5865 asm, ".8h", ".8h", 5866 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5867} 5868 5869// Supports H, S and D element sizes, uses high bit of the size field 5870// as an extra opcode bit. 5871multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5872 SDPatternOperator OpNode> { 5873 let Predicates = [HasNEON, HasFullFP16] in { 5874 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5875 asm, ".4h", ".4h", 5876 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5877 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5878 asm, ".8h", ".8h", 5879 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5880 } // Predicates = [HasNEON, HasFullFP16] 5881 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5882 asm, ".2s", ".2s", 5883 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5884 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5885 asm, ".4s", ".4s", 5886 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5887 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5888 asm, ".2d", ".2d", 5889 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5890} 5891 5892// Supports only S and D element sizes 5893multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5894 SDPatternOperator OpNode = null_frag> { 5895 5896 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5897 asm, ".2s", ".2s", 5898 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5899 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5900 asm, ".4s", ".4s", 5901 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5902 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5903 asm, ".2d", ".2d", 5904 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5905} 5906 5907multiclass FRIntNNTVector<bit U, bit op, string asm, 5908 SDPatternOperator OpNode = null_frag> : 5909 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5910 5911// Supports only S element size. 5912multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5913 SDPatternOperator OpNode> { 5914 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5915 asm, ".2s", ".2s", 5916 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5917 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5918 asm, ".4s", ".4s", 5919 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5920} 5921 5922 5923multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5924 SDPatternOperator OpNode> { 5925 let Predicates = [HasNEON, HasFullFP16] in { 5926 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5927 asm, ".4h", ".4h", 5928 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5929 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5930 asm, ".8h", ".8h", 5931 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5932 } // Predicates = [HasNEON, HasFullFP16] 5933 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5934 asm, ".2s", ".2s", 5935 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5936 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5937 asm, ".4s", ".4s", 5938 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5939 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5940 asm, ".2d", ".2d", 5941 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5942} 5943 5944multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 5945 SDPatternOperator OpNode> { 5946 let Predicates = [HasNEON, HasFullFP16] in { 5947 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5948 asm, ".4h", ".4h", 5949 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5950 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5951 asm, ".8h", ".8h", 5952 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5953 } // Predicates = [HasNEON, HasFullFP16] 5954 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5955 asm, ".2s", ".2s", 5956 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5957 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5958 asm, ".4s", ".4s", 5959 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5960 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5961 asm, ".2d", ".2d", 5962 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5963} 5964 5965 5966class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5967 RegisterOperand inreg, RegisterOperand outreg, 5968 string asm, string outkind, string inkind, 5969 list<dag> pattern> 5970 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 5971 "{\t$Rd" # outkind # ", $Rn" # inkind # 5972 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 5973 Sched<[WriteV]> { 5974 bits<5> Rd; 5975 bits<5> Rn; 5976 let Inst{31} = 0; 5977 let Inst{30} = Q; 5978 let Inst{29} = U; 5979 let Inst{28-24} = 0b01110; 5980 let Inst{23-22} = size; 5981 let Inst{21-17} = 0b10000; 5982 let Inst{16-12} = opcode; 5983 let Inst{11-10} = 0b10; 5984 let Inst{9-5} = Rn; 5985 let Inst{4-0} = Rd; 5986} 5987 5988class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5989 RegisterOperand inreg, RegisterOperand outreg, 5990 string asm, string outkind, string inkind, 5991 list<dag> pattern> 5992 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 5993 "{\t$Rd" # outkind # ", $Rn" # inkind # 5994 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5995 Sched<[WriteV]> { 5996 bits<5> Rd; 5997 bits<5> Rn; 5998 let Inst{31} = 0; 5999 let Inst{30} = Q; 6000 let Inst{29} = U; 6001 let Inst{28-24} = 0b01110; 6002 let Inst{23-22} = size; 6003 let Inst{21-17} = 0b10000; 6004 let Inst{16-12} = opcode; 6005 let Inst{11-10} = 0b10; 6006 let Inst{9-5} = Rn; 6007 let Inst{4-0} = Rd; 6008} 6009 6010multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6011 SDPatternOperator OpNode> { 6012 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6013 asm, ".8b", ".8h", 6014 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6015 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6016 asm#"2", ".16b", ".8h", []>; 6017 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6018 asm, ".4h", ".4s", 6019 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6020 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6021 asm#"2", ".8h", ".4s", []>; 6022 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6023 asm, ".2s", ".2d", 6024 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6025 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6026 asm#"2", ".4s", ".2d", []>; 6027 6028 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6029 (!cast<Instruction>(NAME # "v16i8") 6030 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6031 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6032 (!cast<Instruction>(NAME # "v8i16") 6033 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6034 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6035 (!cast<Instruction>(NAME # "v4i32") 6036 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6037} 6038 6039class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6040 bits<5> opcode, RegisterOperand regtype, string asm, 6041 string kind, string zero, ValueType dty, 6042 ValueType sty, SDNode OpNode> 6043 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6044 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6045 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6046 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6047 Sched<[WriteV]> { 6048 bits<5> Rd; 6049 bits<5> Rn; 6050 let Inst{31} = 0; 6051 let Inst{30} = Q; 6052 let Inst{29} = U; 6053 let Inst{28-24} = 0b01110; 6054 let Inst{23-22} = size; 6055 let Inst{21} = 0b1; 6056 let Inst{20-19} = size2; 6057 let Inst{18-17} = 0b00; 6058 let Inst{16-12} = opcode; 6059 let Inst{11-10} = 0b10; 6060 let Inst{9-5} = Rn; 6061 let Inst{4-0} = Rd; 6062} 6063 6064// Comparisons support all element sizes, except 1xD. 6065multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6066 SDNode OpNode> { 6067 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6068 asm, ".8b", "0", 6069 v8i8, v8i8, OpNode>; 6070 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6071 asm, ".16b", "0", 6072 v16i8, v16i8, OpNode>; 6073 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6074 asm, ".4h", "0", 6075 v4i16, v4i16, OpNode>; 6076 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6077 asm, ".8h", "0", 6078 v8i16, v8i16, OpNode>; 6079 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6080 asm, ".2s", "0", 6081 v2i32, v2i32, OpNode>; 6082 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6083 asm, ".4s", "0", 6084 v4i32, v4i32, OpNode>; 6085 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6086 asm, ".2d", "0", 6087 v2i64, v2i64, OpNode>; 6088} 6089 6090// FP Comparisons support only S and D element sizes (and H for v8.2a). 6091multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6092 string asm, SDNode OpNode> { 6093 6094 let Predicates = [HasNEON, HasFullFP16] in { 6095 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6096 asm, ".4h", "0.0", 6097 v4i16, v4f16, OpNode>; 6098 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6099 asm, ".8h", "0.0", 6100 v8i16, v8f16, OpNode>; 6101 } // Predicates = [HasNEON, HasFullFP16] 6102 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6103 asm, ".2s", "0.0", 6104 v2i32, v2f32, OpNode>; 6105 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6106 asm, ".4s", "0.0", 6107 v4i32, v4f32, OpNode>; 6108 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6109 asm, ".2d", "0.0", 6110 v2i64, v2f64, OpNode>; 6111 6112 let Predicates = [HasNEON, HasFullFP16] in { 6113 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6114 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6115 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6116 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6117 } 6118 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6119 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6120 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6121 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6122 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6123 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6124 let Predicates = [HasNEON, HasFullFP16] in { 6125 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6126 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6127 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6128 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6129 } 6130 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6131 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6132 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6133 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6134 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6135 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6136} 6137 6138let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6139class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6140 RegisterOperand outtype, RegisterOperand intype, 6141 string asm, string VdTy, string VnTy, 6142 list<dag> pattern> 6143 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6144 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6145 Sched<[WriteV]> { 6146 bits<5> Rd; 6147 bits<5> Rn; 6148 let Inst{31} = 0; 6149 let Inst{30} = Q; 6150 let Inst{29} = U; 6151 let Inst{28-24} = 0b01110; 6152 let Inst{23-22} = size; 6153 let Inst{21-17} = 0b10000; 6154 let Inst{16-12} = opcode; 6155 let Inst{11-10} = 0b10; 6156 let Inst{9-5} = Rn; 6157 let Inst{4-0} = Rd; 6158} 6159 6160class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6161 RegisterOperand outtype, RegisterOperand intype, 6162 string asm, string VdTy, string VnTy, 6163 list<dag> pattern> 6164 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6165 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6166 Sched<[WriteV]> { 6167 bits<5> Rd; 6168 bits<5> Rn; 6169 let Inst{31} = 0; 6170 let Inst{30} = Q; 6171 let Inst{29} = U; 6172 let Inst{28-24} = 0b01110; 6173 let Inst{23-22} = size; 6174 let Inst{21-17} = 0b10000; 6175 let Inst{16-12} = opcode; 6176 let Inst{11-10} = 0b10; 6177 let Inst{9-5} = Rn; 6178 let Inst{4-0} = Rd; 6179} 6180 6181multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6182 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6183 asm, ".4s", ".4h", []>; 6184 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6185 asm#"2", ".4s", ".8h", []>; 6186 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6187 asm, ".2d", ".2s", []>; 6188 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6189 asm#"2", ".2d", ".4s", []>; 6190} 6191 6192multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6193 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6194 asm, ".4h", ".4s", []>; 6195 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6196 asm#"2", ".8h", ".4s", []>; 6197 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6198 asm, ".2s", ".2d", []>; 6199 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6200 asm#"2", ".4s", ".2d", []>; 6201} 6202 6203multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6204 Intrinsic OpNode> { 6205 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6206 asm, ".2s", ".2d", 6207 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6208 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6209 asm#"2", ".4s", ".2d", []>; 6210 6211 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6212 (!cast<Instruction>(NAME # "v4f32") 6213 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6214} 6215 6216//---------------------------------------------------------------------------- 6217// AdvSIMD three register different-size vector instructions. 6218//---------------------------------------------------------------------------- 6219 6220let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6221class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6222 RegisterOperand outtype, RegisterOperand intype1, 6223 RegisterOperand intype2, string asm, 6224 string outkind, string inkind1, string inkind2, 6225 list<dag> pattern> 6226 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6227 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6228 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6229 Sched<[WriteV]> { 6230 bits<5> Rd; 6231 bits<5> Rn; 6232 bits<5> Rm; 6233 let Inst{31} = 0; 6234 let Inst{30} = size{0}; 6235 let Inst{29} = U; 6236 let Inst{28-24} = 0b01110; 6237 let Inst{23-22} = size{2-1}; 6238 let Inst{21} = 1; 6239 let Inst{20-16} = Rm; 6240 let Inst{15-12} = opcode; 6241 let Inst{11-10} = 0b00; 6242 let Inst{9-5} = Rn; 6243 let Inst{4-0} = Rd; 6244} 6245 6246let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6247class BaseSIMDDifferentThreeVectorTied<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:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6253 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6254 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", 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 6272// FIXME: TableGen doesn't know how to deal with expanded types that also 6273// change the element count (in this case, placing the results in 6274// the high elements of the result register rather than the low 6275// elements). Until that's fixed, we can't code-gen those. 6276multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6277 Intrinsic IntOp> { 6278 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6279 V64, V128, V128, 6280 asm, ".8b", ".8h", ".8h", 6281 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6282 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6283 V128, V128, V128, 6284 asm#"2", ".16b", ".8h", ".8h", 6285 []>; 6286 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6287 V64, V128, V128, 6288 asm, ".4h", ".4s", ".4s", 6289 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6290 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6291 V128, V128, V128, 6292 asm#"2", ".8h", ".4s", ".4s", 6293 []>; 6294 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6295 V64, V128, V128, 6296 asm, ".2s", ".2d", ".2d", 6297 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6298 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6299 V128, V128, V128, 6300 asm#"2", ".4s", ".2d", ".2d", 6301 []>; 6302 6303 6304 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6305 // a version attached to an instruction. 6306 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6307 (v8i16 V128:$Rm))), 6308 (!cast<Instruction>(NAME # "v8i16_v16i8") 6309 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6310 V128:$Rn, V128:$Rm)>; 6311 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6312 (v4i32 V128:$Rm))), 6313 (!cast<Instruction>(NAME # "v4i32_v8i16") 6314 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6315 V128:$Rn, V128:$Rm)>; 6316 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6317 (v2i64 V128:$Rm))), 6318 (!cast<Instruction>(NAME # "v2i64_v4i32") 6319 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6320 V128:$Rn, V128:$Rm)>; 6321} 6322 6323multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6324 Intrinsic IntOp> { 6325 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6326 V128, V64, V64, 6327 asm, ".8h", ".8b", ".8b", 6328 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6329 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6330 V128, V128, V128, 6331 asm#"2", ".8h", ".16b", ".16b", []>; 6332 let Predicates = [HasAES] in { 6333 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6334 V128, V64, V64, 6335 asm, ".1q", ".1d", ".1d", []>; 6336 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6337 V128, V128, V128, 6338 asm#"2", ".1q", ".2d", ".2d", []>; 6339 } 6340 6341 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6342 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6343 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6344} 6345 6346multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6347 SDPatternOperator OpNode> { 6348 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6349 V128, V64, V64, 6350 asm, ".4s", ".4h", ".4h", 6351 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6352 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6353 V128, V128, V128, 6354 asm#"2", ".4s", ".8h", ".8h", 6355 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6356 (extract_high_v8i16 V128:$Rm)))]>; 6357 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6358 V128, V64, V64, 6359 asm, ".2d", ".2s", ".2s", 6360 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6361 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6362 V128, V128, V128, 6363 asm#"2", ".2d", ".4s", ".4s", 6364 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6365 (extract_high_v4i32 V128:$Rm)))]>; 6366} 6367 6368multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6369 SDPatternOperator OpNode = null_frag> { 6370 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6371 V128, V64, V64, 6372 asm, ".8h", ".8b", ".8b", 6373 [(set (v8i16 V128:$Rd), 6374 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6375 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6376 V128, V128, V128, 6377 asm#"2", ".8h", ".16b", ".16b", 6378 [(set (v8i16 V128:$Rd), 6379 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6380 (extract_high_v16i8 V128:$Rm)))))]>; 6381 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6382 V128, V64, V64, 6383 asm, ".4s", ".4h", ".4h", 6384 [(set (v4i32 V128:$Rd), 6385 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6386 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6387 V128, V128, V128, 6388 asm#"2", ".4s", ".8h", ".8h", 6389 [(set (v4i32 V128:$Rd), 6390 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6391 (extract_high_v8i16 V128:$Rm)))))]>; 6392 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6393 V128, V64, V64, 6394 asm, ".2d", ".2s", ".2s", 6395 [(set (v2i64 V128:$Rd), 6396 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6397 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6398 V128, V128, V128, 6399 asm#"2", ".2d", ".4s", ".4s", 6400 [(set (v2i64 V128:$Rd), 6401 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6402 (extract_high_v4i32 V128:$Rm)))))]>; 6403} 6404 6405multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6406 string asm, 6407 SDPatternOperator OpNode> { 6408 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6409 V128, V64, V64, 6410 asm, ".8h", ".8b", ".8b", 6411 [(set (v8i16 V128:$dst), 6412 (add (v8i16 V128:$Rd), 6413 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6414 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6415 V128, V128, V128, 6416 asm#"2", ".8h", ".16b", ".16b", 6417 [(set (v8i16 V128:$dst), 6418 (add (v8i16 V128:$Rd), 6419 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6420 (extract_high_v16i8 V128:$Rm))))))]>; 6421 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6422 V128, V64, V64, 6423 asm, ".4s", ".4h", ".4h", 6424 [(set (v4i32 V128:$dst), 6425 (add (v4i32 V128:$Rd), 6426 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6427 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6428 V128, V128, V128, 6429 asm#"2", ".4s", ".8h", ".8h", 6430 [(set (v4i32 V128:$dst), 6431 (add (v4i32 V128:$Rd), 6432 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6433 (extract_high_v8i16 V128:$Rm))))))]>; 6434 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6435 V128, V64, V64, 6436 asm, ".2d", ".2s", ".2s", 6437 [(set (v2i64 V128:$dst), 6438 (add (v2i64 V128:$Rd), 6439 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6440 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6441 V128, V128, V128, 6442 asm#"2", ".2d", ".4s", ".4s", 6443 [(set (v2i64 V128:$dst), 6444 (add (v2i64 V128:$Rd), 6445 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6446 (extract_high_v4i32 V128:$Rm))))))]>; 6447} 6448 6449multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6450 SDPatternOperator OpNode = null_frag> { 6451 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6452 V128, V64, V64, 6453 asm, ".8h", ".8b", ".8b", 6454 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6455 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6456 V128, V128, V128, 6457 asm#"2", ".8h", ".16b", ".16b", 6458 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6459 (extract_high_v16i8 V128:$Rm)))]>; 6460 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6461 V128, V64, V64, 6462 asm, ".4s", ".4h", ".4h", 6463 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6464 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6465 V128, V128, V128, 6466 asm#"2", ".4s", ".8h", ".8h", 6467 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6468 (extract_high_v8i16 V128:$Rm)))]>; 6469 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6470 V128, V64, V64, 6471 asm, ".2d", ".2s", ".2s", 6472 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6473 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6474 V128, V128, V128, 6475 asm#"2", ".2d", ".4s", ".4s", 6476 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6477 (extract_high_v4i32 V128:$Rm)))]>; 6478} 6479 6480multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6481 string asm, 6482 SDPatternOperator OpNode> { 6483 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6484 V128, V64, V64, 6485 asm, ".8h", ".8b", ".8b", 6486 [(set (v8i16 V128:$dst), 6487 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6488 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6489 V128, V128, V128, 6490 asm#"2", ".8h", ".16b", ".16b", 6491 [(set (v8i16 V128:$dst), 6492 (OpNode (v8i16 V128:$Rd), 6493 (extract_high_v16i8 V128:$Rn), 6494 (extract_high_v16i8 V128:$Rm)))]>; 6495 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6496 V128, V64, V64, 6497 asm, ".4s", ".4h", ".4h", 6498 [(set (v4i32 V128:$dst), 6499 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6500 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6501 V128, V128, V128, 6502 asm#"2", ".4s", ".8h", ".8h", 6503 [(set (v4i32 V128:$dst), 6504 (OpNode (v4i32 V128:$Rd), 6505 (extract_high_v8i16 V128:$Rn), 6506 (extract_high_v8i16 V128:$Rm)))]>; 6507 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6508 V128, V64, V64, 6509 asm, ".2d", ".2s", ".2s", 6510 [(set (v2i64 V128:$dst), 6511 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6512 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6513 V128, V128, V128, 6514 asm#"2", ".2d", ".4s", ".4s", 6515 [(set (v2i64 V128:$dst), 6516 (OpNode (v2i64 V128:$Rd), 6517 (extract_high_v4i32 V128:$Rn), 6518 (extract_high_v4i32 V128:$Rm)))]>; 6519} 6520 6521multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6522 SDPatternOperator Accum> { 6523 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6524 V128, V64, V64, 6525 asm, ".4s", ".4h", ".4h", 6526 [(set (v4i32 V128:$dst), 6527 (Accum (v4i32 V128:$Rd), 6528 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6529 (v4i16 V64:$Rm)))))]>; 6530 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6531 V128, V128, V128, 6532 asm#"2", ".4s", ".8h", ".8h", 6533 [(set (v4i32 V128:$dst), 6534 (Accum (v4i32 V128:$Rd), 6535 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6536 (extract_high_v8i16 V128:$Rm)))))]>; 6537 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6538 V128, V64, V64, 6539 asm, ".2d", ".2s", ".2s", 6540 [(set (v2i64 V128:$dst), 6541 (Accum (v2i64 V128:$Rd), 6542 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6543 (v2i32 V64:$Rm)))))]>; 6544 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6545 V128, V128, V128, 6546 asm#"2", ".2d", ".4s", ".4s", 6547 [(set (v2i64 V128:$dst), 6548 (Accum (v2i64 V128:$Rd), 6549 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6550 (extract_high_v4i32 V128:$Rm)))))]>; 6551} 6552 6553multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6554 SDPatternOperator OpNode> { 6555 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6556 V128, V128, V64, 6557 asm, ".8h", ".8h", ".8b", 6558 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6559 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6560 V128, V128, V128, 6561 asm#"2", ".8h", ".8h", ".16b", 6562 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6563 (extract_high_v16i8 V128:$Rm)))]>; 6564 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6565 V128, V128, V64, 6566 asm, ".4s", ".4s", ".4h", 6567 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6568 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6569 V128, V128, V128, 6570 asm#"2", ".4s", ".4s", ".8h", 6571 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6572 (extract_high_v8i16 V128:$Rm)))]>; 6573 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6574 V128, V128, V64, 6575 asm, ".2d", ".2d", ".2s", 6576 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6577 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6578 V128, V128, V128, 6579 asm#"2", ".2d", ".2d", ".4s", 6580 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6581 (extract_high_v4i32 V128:$Rm)))]>; 6582} 6583 6584//---------------------------------------------------------------------------- 6585// AdvSIMD bitwise extract from vector 6586//---------------------------------------------------------------------------- 6587 6588class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6589 string asm, string kind> 6590 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6591 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6592 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6593 [(set (vty regtype:$Rd), 6594 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6595 Sched<[WriteV]> { 6596 bits<5> Rd; 6597 bits<5> Rn; 6598 bits<5> Rm; 6599 bits<4> imm; 6600 let Inst{31} = 0; 6601 let Inst{30} = size; 6602 let Inst{29-21} = 0b101110000; 6603 let Inst{20-16} = Rm; 6604 let Inst{15} = 0; 6605 let Inst{14-11} = imm; 6606 let Inst{10} = 0; 6607 let Inst{9-5} = Rn; 6608 let Inst{4-0} = Rd; 6609} 6610 6611 6612multiclass SIMDBitwiseExtract<string asm> { 6613 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6614 let imm{3} = 0; 6615 } 6616 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6617} 6618 6619//---------------------------------------------------------------------------- 6620// AdvSIMD zip vector 6621//---------------------------------------------------------------------------- 6622 6623class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6624 string asm, string kind, SDNode OpNode, ValueType valty> 6625 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6626 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6627 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6628 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6629 Sched<[WriteV]> { 6630 bits<5> Rd; 6631 bits<5> Rn; 6632 bits<5> Rm; 6633 let Inst{31} = 0; 6634 let Inst{30} = size{0}; 6635 let Inst{29-24} = 0b001110; 6636 let Inst{23-22} = size{2-1}; 6637 let Inst{21} = 0; 6638 let Inst{20-16} = Rm; 6639 let Inst{15} = 0; 6640 let Inst{14-12} = opc; 6641 let Inst{11-10} = 0b10; 6642 let Inst{9-5} = Rn; 6643 let Inst{4-0} = Rd; 6644} 6645 6646multiclass SIMDZipVector<bits<3>opc, string asm, 6647 SDNode OpNode> { 6648 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6649 asm, ".8b", OpNode, v8i8>; 6650 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6651 asm, ".16b", OpNode, v16i8>; 6652 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6653 asm, ".4h", OpNode, v4i16>; 6654 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6655 asm, ".8h", OpNode, v8i16>; 6656 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6657 asm, ".2s", OpNode, v2i32>; 6658 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6659 asm, ".4s", OpNode, v4i32>; 6660 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6661 asm, ".2d", OpNode, v2i64>; 6662 6663 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6664 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6665 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6666 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6667 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6668 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6669 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6670 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6671 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6672 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6673} 6674 6675//---------------------------------------------------------------------------- 6676// AdvSIMD three register scalar instructions 6677//---------------------------------------------------------------------------- 6678 6679let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6680class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6681 RegisterClass regtype, string asm, 6682 list<dag> pattern> 6683 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6684 "\t$Rd, $Rn, $Rm", "", pattern>, 6685 Sched<[WriteV]> { 6686 bits<5> Rd; 6687 bits<5> Rn; 6688 bits<5> Rm; 6689 let Inst{31-30} = 0b01; 6690 let Inst{29} = U; 6691 let Inst{28-24} = 0b11110; 6692 let Inst{23-21} = size; 6693 let Inst{20-16} = Rm; 6694 let Inst{15-11} = opcode; 6695 let Inst{10} = 1; 6696 let Inst{9-5} = Rn; 6697 let Inst{4-0} = Rd; 6698} 6699 6700let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6701class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6702 dag oops, dag iops, string asm, 6703 list<dag> pattern> 6704 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6705 Sched<[WriteV]> { 6706 bits<5> Rd; 6707 bits<5> Rn; 6708 bits<5> Rm; 6709 let Inst{31-30} = 0b01; 6710 let Inst{29} = U; 6711 let Inst{28-24} = 0b11110; 6712 let Inst{23-22} = size; 6713 let Inst{21} = R; 6714 let Inst{20-16} = Rm; 6715 let Inst{15-11} = opcode; 6716 let Inst{10} = 1; 6717 let Inst{9-5} = Rn; 6718 let Inst{4-0} = Rd; 6719} 6720 6721multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6722 SDPatternOperator OpNode> { 6723 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6724 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6725} 6726 6727multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6728 SDPatternOperator OpNode> { 6729 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6730 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6731 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6732 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6733 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6734 6735 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6736 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6737 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6738 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6739} 6740 6741multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6742 SDPatternOperator OpNode> { 6743 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6744 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6745 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6746} 6747 6748multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6749 SDPatternOperator OpNode = null_frag> { 6750 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6751 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6752 asm, []>; 6753 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6754 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6755 asm, []>; 6756} 6757 6758multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6759 SDPatternOperator OpNode = null_frag> { 6760 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6761 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6762 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6763 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6764 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6765 let Predicates = [HasNEON, HasFullFP16] in { 6766 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6767 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6768 } // Predicates = [HasNEON, HasFullFP16] 6769 } 6770 6771 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6772 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6773} 6774 6775multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6776 SDPatternOperator OpNode = null_frag> { 6777 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6778 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6779 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6780 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6781 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6782 let Predicates = [HasNEON, HasFullFP16] in { 6783 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6784 []>; 6785 } // Predicates = [HasNEON, HasFullFP16] 6786 } 6787 6788 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6789 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6790} 6791 6792class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6793 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6794 : I<oops, iops, asm, 6795 "\t$Rd, $Rn, $Rm", cstr, pat>, 6796 Sched<[WriteV]> { 6797 bits<5> Rd; 6798 bits<5> Rn; 6799 bits<5> Rm; 6800 let Inst{31-30} = 0b01; 6801 let Inst{29} = U; 6802 let Inst{28-24} = 0b11110; 6803 let Inst{23-22} = size; 6804 let Inst{21} = 1; 6805 let Inst{20-16} = Rm; 6806 let Inst{15-11} = opcode; 6807 let Inst{10} = 0; 6808 let Inst{9-5} = Rn; 6809 let Inst{4-0} = Rd; 6810} 6811 6812let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6813multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6814 SDPatternOperator OpNode = null_frag> { 6815 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6816 (outs FPR32:$Rd), 6817 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6818 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6819 (outs FPR64:$Rd), 6820 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6821 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6822} 6823 6824let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6825multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6826 SDPatternOperator OpNode = null_frag> { 6827 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6828 (outs FPR32:$dst), 6829 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6830 asm, "$Rd = $dst", []>; 6831 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6832 (outs FPR64:$dst), 6833 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6834 asm, "$Rd = $dst", 6835 [(set (i64 FPR64:$dst), 6836 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6837} 6838 6839//---------------------------------------------------------------------------- 6840// AdvSIMD two register scalar instructions 6841//---------------------------------------------------------------------------- 6842 6843let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6844class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6845 RegisterClass regtype, RegisterClass regtype2, 6846 string asm, list<dag> pat> 6847 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6848 "\t$Rd, $Rn", "", pat>, 6849 Sched<[WriteV]> { 6850 bits<5> Rd; 6851 bits<5> Rn; 6852 let Inst{31-30} = 0b01; 6853 let Inst{29} = U; 6854 let Inst{28-24} = 0b11110; 6855 let Inst{23-22} = size; 6856 let Inst{21} = 0b1; 6857 let Inst{20-19} = size2; 6858 let Inst{18-17} = 0b00; 6859 let Inst{16-12} = opcode; 6860 let Inst{11-10} = 0b10; 6861 let Inst{9-5} = Rn; 6862 let Inst{4-0} = Rd; 6863} 6864 6865let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6866class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6867 RegisterClass regtype, RegisterClass regtype2, 6868 string asm, list<dag> pat> 6869 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6870 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6871 Sched<[WriteV]> { 6872 bits<5> Rd; 6873 bits<5> Rn; 6874 let Inst{31-30} = 0b01; 6875 let Inst{29} = U; 6876 let Inst{28-24} = 0b11110; 6877 let Inst{23-22} = size; 6878 let Inst{21-17} = 0b10000; 6879 let Inst{16-12} = opcode; 6880 let Inst{11-10} = 0b10; 6881 let Inst{9-5} = Rn; 6882 let Inst{4-0} = Rd; 6883} 6884 6885 6886let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6887class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6888 RegisterClass regtype, string asm, string zero> 6889 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6890 "\t$Rd, $Rn, #" # zero, "", []>, 6891 Sched<[WriteV]> { 6892 bits<5> Rd; 6893 bits<5> Rn; 6894 let Inst{31-30} = 0b01; 6895 let Inst{29} = U; 6896 let Inst{28-24} = 0b11110; 6897 let Inst{23-22} = size; 6898 let Inst{21} = 0b1; 6899 let Inst{20-19} = size2; 6900 let Inst{18-17} = 0b00; 6901 let Inst{16-12} = opcode; 6902 let Inst{11-10} = 0b10; 6903 let Inst{9-5} = Rn; 6904 let Inst{4-0} = Rd; 6905} 6906 6907class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6908 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6909 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6910 Sched<[WriteV]> { 6911 bits<5> Rd; 6912 bits<5> Rn; 6913 let Inst{31-17} = 0b011111100110000; 6914 let Inst{16-12} = opcode; 6915 let Inst{11-10} = 0b10; 6916 let Inst{9-5} = Rn; 6917 let Inst{4-0} = Rd; 6918} 6919 6920multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6921 SDPatternOperator OpNode> { 6922 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6923 6924 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6925 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6926} 6927 6928multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6929 SDPatternOperator OpNode> { 6930 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 6931 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 6932 let Predicates = [HasNEON, HasFullFP16] in { 6933 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 6934 } 6935 6936 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6937 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 6938 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6939 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 6940 let Predicates = [HasNEON, HasFullFP16] in { 6941 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6942 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 6943 } 6944 6945 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 6946 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6947} 6948 6949multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 6950 SDPatternOperator OpNode = null_frag> { 6951 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6952 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 6953 6954 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 6955 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 6956} 6957 6958multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 6959 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 6960 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 6961 let Predicates = [HasNEON, HasFullFP16] in { 6962 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 6963 } 6964} 6965 6966multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 6967 SDPatternOperator OpNode> { 6968 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 6969 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 6970 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 6971 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 6972 let Predicates = [HasNEON, HasFullFP16] in { 6973 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 6974 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 6975 } 6976} 6977 6978multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 6979 SDPatternOperator OpNode = null_frag> { 6980 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6981 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6982 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6983 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 6984 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 6985 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 6986 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 6987 } 6988 6989 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 6990 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 6991} 6992 6993multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 6994 Intrinsic OpNode> { 6995 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6996 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 6997 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 6998 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 6999 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7000 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7001 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7002 } 7003 7004 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7005 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7006} 7007 7008 7009 7010let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7011multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7012 SDPatternOperator OpNode = null_frag> { 7013 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7014 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7015 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7016 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7017} 7018 7019//---------------------------------------------------------------------------- 7020// AdvSIMD scalar pairwise instructions 7021//---------------------------------------------------------------------------- 7022 7023let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7024class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7025 RegisterOperand regtype, RegisterOperand vectype, 7026 string asm, string kind> 7027 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7028 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7029 Sched<[WriteV]> { 7030 bits<5> Rd; 7031 bits<5> Rn; 7032 let Inst{31-30} = 0b01; 7033 let Inst{29} = U; 7034 let Inst{28-24} = 0b11110; 7035 let Inst{23-22} = size; 7036 let Inst{21-17} = 0b11000; 7037 let Inst{16-12} = opcode; 7038 let Inst{11-10} = 0b10; 7039 let Inst{9-5} = Rn; 7040 let Inst{4-0} = Rd; 7041} 7042 7043multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7044 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7045 asm, ".2d">; 7046} 7047 7048multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7049 let Predicates = [HasNEON, HasFullFP16] in { 7050 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7051 asm, ".2h">; 7052 } 7053 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7054 asm, ".2s">; 7055 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7056 asm, ".2d">; 7057} 7058 7059//---------------------------------------------------------------------------- 7060// AdvSIMD across lanes instructions 7061//---------------------------------------------------------------------------- 7062 7063let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7064class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7065 RegisterClass regtype, RegisterOperand vectype, 7066 string asm, string kind, list<dag> pattern> 7067 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7068 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7069 Sched<[WriteV]> { 7070 bits<5> Rd; 7071 bits<5> Rn; 7072 let Inst{31} = 0; 7073 let Inst{30} = Q; 7074 let Inst{29} = U; 7075 let Inst{28-24} = 0b01110; 7076 let Inst{23-22} = size; 7077 let Inst{21-17} = 0b11000; 7078 let Inst{16-12} = opcode; 7079 let Inst{11-10} = 0b10; 7080 let Inst{9-5} = Rn; 7081 let Inst{4-0} = Rd; 7082} 7083 7084multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7085 string asm> { 7086 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7087 asm, ".8b", []>; 7088 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7089 asm, ".16b", []>; 7090 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7091 asm, ".4h", []>; 7092 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7093 asm, ".8h", []>; 7094 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7095 asm, ".4s", []>; 7096} 7097 7098multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7099 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7100 asm, ".8b", []>; 7101 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7102 asm, ".16b", []>; 7103 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7104 asm, ".4h", []>; 7105 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7106 asm, ".8h", []>; 7107 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7108 asm, ".4s", []>; 7109} 7110 7111multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7112 Intrinsic intOp> { 7113 let Predicates = [HasNEON, HasFullFP16] in { 7114 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7115 asm, ".4h", 7116 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7117 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7118 asm, ".8h", 7119 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7120 } // Predicates = [HasNEON, HasFullFP16] 7121 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7122 asm, ".4s", 7123 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7124} 7125 7126//---------------------------------------------------------------------------- 7127// AdvSIMD INS/DUP instructions 7128//---------------------------------------------------------------------------- 7129 7130// FIXME: There has got to be a better way to factor these. ugh. 7131 7132class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7133 string operands, string constraints, list<dag> pattern> 7134 : I<outs, ins, asm, operands, constraints, pattern>, 7135 Sched<[WriteV]> { 7136 bits<5> Rd; 7137 bits<5> Rn; 7138 let Inst{31} = 0; 7139 let Inst{30} = Q; 7140 let Inst{29} = op; 7141 let Inst{28-21} = 0b01110000; 7142 let Inst{15} = 0; 7143 let Inst{10} = 1; 7144 let Inst{9-5} = Rn; 7145 let Inst{4-0} = Rd; 7146} 7147 7148class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7149 RegisterOperand vecreg, RegisterClass regtype> 7150 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7151 "{\t$Rd" # size # ", $Rn" # 7152 "|" # size # "\t$Rd, $Rn}", "", 7153 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7154 let Inst{20-16} = imm5; 7155 let Inst{14-11} = 0b0001; 7156} 7157 7158class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7159 ValueType vectype, ValueType insreg, 7160 RegisterOperand vecreg, Operand idxtype, 7161 ValueType elttype, SDNode OpNode> 7162 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7163 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7164 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7165 [(set (vectype vecreg:$Rd), 7166 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7167 let Inst{14-11} = 0b0000; 7168} 7169 7170class SIMDDup64FromElement 7171 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7172 VectorIndexD, i64, AArch64duplane64> { 7173 bits<1> idx; 7174 let Inst{20} = idx; 7175 let Inst{19-16} = 0b1000; 7176} 7177 7178class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7179 RegisterOperand vecreg> 7180 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7181 VectorIndexS, i64, AArch64duplane32> { 7182 bits<2> idx; 7183 let Inst{20-19} = idx; 7184 let Inst{18-16} = 0b100; 7185} 7186 7187class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7188 RegisterOperand vecreg> 7189 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7190 VectorIndexH, i64, AArch64duplane16> { 7191 bits<3> idx; 7192 let Inst{20-18} = idx; 7193 let Inst{17-16} = 0b10; 7194} 7195 7196class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7197 RegisterOperand vecreg> 7198 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7199 VectorIndexB, i64, AArch64duplane8> { 7200 bits<4> idx; 7201 let Inst{20-17} = idx; 7202 let Inst{16} = 1; 7203} 7204 7205class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7206 Operand idxtype, string asm, list<dag> pattern> 7207 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7208 "{\t$Rd, $Rn" # size # "$idx" # 7209 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7210 let Inst{14-11} = imm4; 7211} 7212 7213class SIMDSMov<bit Q, string size, RegisterClass regtype, 7214 Operand idxtype> 7215 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7216class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7217 Operand idxtype> 7218 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7219 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7220 7221class SIMDMovAlias<string asm, string size, Instruction inst, 7222 RegisterClass regtype, Operand idxtype> 7223 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7224 "|" # size # "\t$dst, $src$idx}", 7225 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7226 7227multiclass SMov { 7228 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7229 bits<4> idx; 7230 let Inst{20-17} = idx; 7231 let Inst{16} = 1; 7232 } 7233 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7234 bits<4> idx; 7235 let Inst{20-17} = idx; 7236 let Inst{16} = 1; 7237 } 7238 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7239 bits<3> idx; 7240 let Inst{20-18} = idx; 7241 let Inst{17-16} = 0b10; 7242 } 7243 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7244 bits<3> idx; 7245 let Inst{20-18} = idx; 7246 let Inst{17-16} = 0b10; 7247 } 7248 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7249 bits<2> idx; 7250 let Inst{20-19} = idx; 7251 let Inst{18-16} = 0b100; 7252 } 7253} 7254 7255multiclass UMov { 7256 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7257 bits<4> idx; 7258 let Inst{20-17} = idx; 7259 let Inst{16} = 1; 7260 } 7261 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7262 bits<3> idx; 7263 let Inst{20-18} = idx; 7264 let Inst{17-16} = 0b10; 7265 } 7266 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7267 bits<2> idx; 7268 let Inst{20-19} = idx; 7269 let Inst{18-16} = 0b100; 7270 } 7271 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7272 bits<1> idx; 7273 let Inst{20} = idx; 7274 let Inst{19-16} = 0b1000; 7275 } 7276 def : SIMDMovAlias<"mov", ".s", 7277 !cast<Instruction>(NAME#"vi32"), 7278 GPR32, VectorIndexS>; 7279 def : SIMDMovAlias<"mov", ".d", 7280 !cast<Instruction>(NAME#"vi64"), 7281 GPR64, VectorIndexD>; 7282} 7283 7284class SIMDInsFromMain<string size, ValueType vectype, 7285 RegisterClass regtype, Operand idxtype> 7286 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7287 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7288 "{\t$Rd" # size # "$idx, $Rn" # 7289 "|" # size # "\t$Rd$idx, $Rn}", 7290 "$Rd = $dst", 7291 [(set V128:$dst, 7292 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7293 let Inst{14-11} = 0b0011; 7294} 7295 7296class SIMDInsFromElement<string size, ValueType vectype, 7297 ValueType elttype, Operand idxtype> 7298 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7299 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7300 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7301 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7302 "$Rd = $dst", 7303 [(set V128:$dst, 7304 (vector_insert 7305 (vectype V128:$Rd), 7306 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7307 idxtype:$idx))]>; 7308 7309class SIMDInsMainMovAlias<string size, Instruction inst, 7310 RegisterClass regtype, Operand idxtype> 7311 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7312 "|" # size #"\t$dst$idx, $src}", 7313 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7314class SIMDInsElementMovAlias<string size, Instruction inst, 7315 Operand idxtype> 7316 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7317 # "|" # size #"\t$dst$idx, $src$idx2}", 7318 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7319 7320 7321multiclass SIMDIns { 7322 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7323 bits<4> idx; 7324 let Inst{20-17} = idx; 7325 let Inst{16} = 1; 7326 } 7327 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7328 bits<3> idx; 7329 let Inst{20-18} = idx; 7330 let Inst{17-16} = 0b10; 7331 } 7332 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7333 bits<2> idx; 7334 let Inst{20-19} = idx; 7335 let Inst{18-16} = 0b100; 7336 } 7337 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7338 bits<1> idx; 7339 let Inst{20} = idx; 7340 let Inst{19-16} = 0b1000; 7341 } 7342 7343 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7344 bits<4> idx; 7345 bits<4> idx2; 7346 let Inst{20-17} = idx; 7347 let Inst{16} = 1; 7348 let Inst{14-11} = idx2; 7349 } 7350 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7351 bits<3> idx; 7352 bits<3> idx2; 7353 let Inst{20-18} = idx; 7354 let Inst{17-16} = 0b10; 7355 let Inst{14-12} = idx2; 7356 let Inst{11} = {?}; 7357 } 7358 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7359 bits<2> idx; 7360 bits<2> idx2; 7361 let Inst{20-19} = idx; 7362 let Inst{18-16} = 0b100; 7363 let Inst{14-13} = idx2; 7364 let Inst{12-11} = {?,?}; 7365 } 7366 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7367 bits<1> idx; 7368 bits<1> idx2; 7369 let Inst{20} = idx; 7370 let Inst{19-16} = 0b1000; 7371 let Inst{14} = idx2; 7372 let Inst{13-11} = {?,?,?}; 7373 } 7374 7375 // For all forms of the INS instruction, the "mov" mnemonic is the 7376 // preferred alias. Why they didn't just call the instruction "mov" in 7377 // the first place is a very good question indeed... 7378 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7379 GPR32, VectorIndexB>; 7380 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7381 GPR32, VectorIndexH>; 7382 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7383 GPR32, VectorIndexS>; 7384 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7385 GPR64, VectorIndexD>; 7386 7387 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7388 VectorIndexB>; 7389 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7390 VectorIndexH>; 7391 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7392 VectorIndexS>; 7393 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7394 VectorIndexD>; 7395} 7396 7397//---------------------------------------------------------------------------- 7398// AdvSIMD TBL/TBX 7399//---------------------------------------------------------------------------- 7400 7401let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7402class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7403 RegisterOperand listtype, string asm, string kind> 7404 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7405 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7406 Sched<[WriteV]> { 7407 bits<5> Vd; 7408 bits<5> Vn; 7409 bits<5> Vm; 7410 let Inst{31} = 0; 7411 let Inst{30} = Q; 7412 let Inst{29-21} = 0b001110000; 7413 let Inst{20-16} = Vm; 7414 let Inst{15} = 0; 7415 let Inst{14-13} = len; 7416 let Inst{12} = op; 7417 let Inst{11-10} = 0b00; 7418 let Inst{9-5} = Vn; 7419 let Inst{4-0} = Vd; 7420} 7421 7422let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7423class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7424 RegisterOperand listtype, string asm, string kind> 7425 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7426 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7427 Sched<[WriteV]> { 7428 bits<5> Vd; 7429 bits<5> Vn; 7430 bits<5> Vm; 7431 let Inst{31} = 0; 7432 let Inst{30} = Q; 7433 let Inst{29-21} = 0b001110000; 7434 let Inst{20-16} = Vm; 7435 let Inst{15} = 0; 7436 let Inst{14-13} = len; 7437 let Inst{12} = op; 7438 let Inst{11-10} = 0b00; 7439 let Inst{9-5} = Vn; 7440 let Inst{4-0} = Vd; 7441} 7442 7443class SIMDTableLookupAlias<string asm, Instruction inst, 7444 RegisterOperand vectype, RegisterOperand listtype> 7445 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7446 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7447 7448multiclass SIMDTableLookup<bit op, string asm> { 7449 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7450 asm, ".8b">; 7451 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7452 asm, ".8b">; 7453 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7454 asm, ".8b">; 7455 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7456 asm, ".8b">; 7457 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7458 asm, ".16b">; 7459 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7460 asm, ".16b">; 7461 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7462 asm, ".16b">; 7463 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7464 asm, ".16b">; 7465 7466 def : SIMDTableLookupAlias<asm # ".8b", 7467 !cast<Instruction>(NAME#"v8i8One"), 7468 V64, VecListOne128>; 7469 def : SIMDTableLookupAlias<asm # ".8b", 7470 !cast<Instruction>(NAME#"v8i8Two"), 7471 V64, VecListTwo128>; 7472 def : SIMDTableLookupAlias<asm # ".8b", 7473 !cast<Instruction>(NAME#"v8i8Three"), 7474 V64, VecListThree128>; 7475 def : SIMDTableLookupAlias<asm # ".8b", 7476 !cast<Instruction>(NAME#"v8i8Four"), 7477 V64, VecListFour128>; 7478 def : SIMDTableLookupAlias<asm # ".16b", 7479 !cast<Instruction>(NAME#"v16i8One"), 7480 V128, VecListOne128>; 7481 def : SIMDTableLookupAlias<asm # ".16b", 7482 !cast<Instruction>(NAME#"v16i8Two"), 7483 V128, VecListTwo128>; 7484 def : SIMDTableLookupAlias<asm # ".16b", 7485 !cast<Instruction>(NAME#"v16i8Three"), 7486 V128, VecListThree128>; 7487 def : SIMDTableLookupAlias<asm # ".16b", 7488 !cast<Instruction>(NAME#"v16i8Four"), 7489 V128, VecListFour128>; 7490} 7491 7492multiclass SIMDTableLookupTied<bit op, string asm> { 7493 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7494 asm, ".8b">; 7495 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7496 asm, ".8b">; 7497 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7498 asm, ".8b">; 7499 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7500 asm, ".8b">; 7501 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7502 asm, ".16b">; 7503 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7504 asm, ".16b">; 7505 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7506 asm, ".16b">; 7507 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7508 asm, ".16b">; 7509 7510 def : SIMDTableLookupAlias<asm # ".8b", 7511 !cast<Instruction>(NAME#"v8i8One"), 7512 V64, VecListOne128>; 7513 def : SIMDTableLookupAlias<asm # ".8b", 7514 !cast<Instruction>(NAME#"v8i8Two"), 7515 V64, VecListTwo128>; 7516 def : SIMDTableLookupAlias<asm # ".8b", 7517 !cast<Instruction>(NAME#"v8i8Three"), 7518 V64, VecListThree128>; 7519 def : SIMDTableLookupAlias<asm # ".8b", 7520 !cast<Instruction>(NAME#"v8i8Four"), 7521 V64, VecListFour128>; 7522 def : SIMDTableLookupAlias<asm # ".16b", 7523 !cast<Instruction>(NAME#"v16i8One"), 7524 V128, VecListOne128>; 7525 def : SIMDTableLookupAlias<asm # ".16b", 7526 !cast<Instruction>(NAME#"v16i8Two"), 7527 V128, VecListTwo128>; 7528 def : SIMDTableLookupAlias<asm # ".16b", 7529 !cast<Instruction>(NAME#"v16i8Three"), 7530 V128, VecListThree128>; 7531 def : SIMDTableLookupAlias<asm # ".16b", 7532 !cast<Instruction>(NAME#"v16i8Four"), 7533 V128, VecListFour128>; 7534} 7535 7536 7537//---------------------------------------------------------------------------- 7538// AdvSIMD scalar CPY 7539//---------------------------------------------------------------------------- 7540let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7541class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7542 string kind, Operand idxtype> 7543 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7544 "{\t$dst, $src" # kind # "$idx" # 7545 "|\t$dst, $src$idx}", "", []>, 7546 Sched<[WriteV]> { 7547 bits<5> dst; 7548 bits<5> src; 7549 let Inst{31-21} = 0b01011110000; 7550 let Inst{15-10} = 0b000001; 7551 let Inst{9-5} = src; 7552 let Inst{4-0} = dst; 7553} 7554 7555class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7556 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7557 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7558 # "|\t$dst, $src$index}", 7559 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7560 7561 7562multiclass SIMDScalarCPY<string asm> { 7563 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7564 bits<4> idx; 7565 let Inst{20-17} = idx; 7566 let Inst{16} = 1; 7567 } 7568 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7569 bits<3> idx; 7570 let Inst{20-18} = idx; 7571 let Inst{17-16} = 0b10; 7572 } 7573 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7574 bits<2> idx; 7575 let Inst{20-19} = idx; 7576 let Inst{18-16} = 0b100; 7577 } 7578 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7579 bits<1> idx; 7580 let Inst{20} = idx; 7581 let Inst{19-16} = 0b1000; 7582 } 7583 7584 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7585 VectorIndexD:$idx)))), 7586 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7587 7588 // 'DUP' mnemonic aliases. 7589 def : SIMDScalarCPYAlias<"dup", ".b", 7590 !cast<Instruction>(NAME#"i8"), 7591 FPR8, V128, VectorIndexB>; 7592 def : SIMDScalarCPYAlias<"dup", ".h", 7593 !cast<Instruction>(NAME#"i16"), 7594 FPR16, V128, VectorIndexH>; 7595 def : SIMDScalarCPYAlias<"dup", ".s", 7596 !cast<Instruction>(NAME#"i32"), 7597 FPR32, V128, VectorIndexS>; 7598 def : SIMDScalarCPYAlias<"dup", ".d", 7599 !cast<Instruction>(NAME#"i64"), 7600 FPR64, V128, VectorIndexD>; 7601} 7602 7603//---------------------------------------------------------------------------- 7604// AdvSIMD modified immediate instructions 7605//---------------------------------------------------------------------------- 7606 7607class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7608 string asm, string op_string, 7609 string cstr, list<dag> pattern> 7610 : I<oops, iops, asm, op_string, cstr, pattern>, 7611 Sched<[WriteV]> { 7612 bits<5> Rd; 7613 bits<8> imm8; 7614 let Inst{31} = 0; 7615 let Inst{30} = Q; 7616 let Inst{29} = op; 7617 let Inst{28-19} = 0b0111100000; 7618 let Inst{18-16} = imm8{7-5}; 7619 let Inst{11} = op2; 7620 let Inst{10} = 1; 7621 let Inst{9-5} = imm8{4-0}; 7622 let Inst{4-0} = Rd; 7623} 7624 7625class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7626 Operand immtype, dag opt_shift_iop, 7627 string opt_shift, string asm, string kind, 7628 list<dag> pattern> 7629 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7630 !con((ins immtype:$imm8), opt_shift_iop), asm, 7631 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7632 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7633 "", pattern> { 7634 let DecoderMethod = "DecodeModImmInstruction"; 7635} 7636 7637class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7638 Operand immtype, dag opt_shift_iop, 7639 string opt_shift, string asm, string kind, 7640 list<dag> pattern> 7641 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7642 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7643 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7644 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7645 "$Rd = $dst", pattern> { 7646 let DecoderMethod = "DecodeModImmTiedInstruction"; 7647} 7648 7649class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7650 RegisterOperand vectype, string asm, 7651 string kind, list<dag> pattern> 7652 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7653 (ins logical_vec_shift:$shift), 7654 "$shift", asm, kind, pattern> { 7655 bits<2> shift; 7656 let Inst{15} = b15_b12{1}; 7657 let Inst{14-13} = shift; 7658 let Inst{12} = b15_b12{0}; 7659} 7660 7661class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7662 RegisterOperand vectype, string asm, 7663 string kind, list<dag> pattern> 7664 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7665 (ins logical_vec_shift:$shift), 7666 "$shift", asm, kind, pattern> { 7667 bits<2> shift; 7668 let Inst{15} = b15_b12{1}; 7669 let Inst{14-13} = shift; 7670 let Inst{12} = b15_b12{0}; 7671} 7672 7673 7674class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7675 RegisterOperand vectype, string asm, 7676 string kind, list<dag> pattern> 7677 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7678 (ins logical_vec_hw_shift:$shift), 7679 "$shift", asm, kind, pattern> { 7680 bits<2> shift; 7681 let Inst{15} = b15_b12{1}; 7682 let Inst{14} = 0; 7683 let Inst{13} = shift{0}; 7684 let Inst{12} = b15_b12{0}; 7685} 7686 7687class BaseSIMDModifiedImmVectorShiftHalfTied<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_hw_shift:$shift), 7692 "$shift", asm, kind, pattern> { 7693 bits<2> shift; 7694 let Inst{15} = b15_b12{1}; 7695 let Inst{14} = 0; 7696 let Inst{13} = shift{0}; 7697 let Inst{12} = b15_b12{0}; 7698} 7699 7700multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7701 string asm> { 7702 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7703 asm, ".4h", []>; 7704 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7705 asm, ".8h", []>; 7706 7707 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7708 asm, ".2s", []>; 7709 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7710 asm, ".4s", []>; 7711} 7712 7713multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7714 bits<2> w_cmode, string asm, 7715 SDNode OpNode> { 7716 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7717 asm, ".4h", 7718 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7719 imm0_255:$imm8, 7720 (i32 imm:$shift)))]>; 7721 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7722 asm, ".8h", 7723 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7724 imm0_255:$imm8, 7725 (i32 imm:$shift)))]>; 7726 7727 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7728 asm, ".2s", 7729 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7730 imm0_255:$imm8, 7731 (i32 imm:$shift)))]>; 7732 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7733 asm, ".4s", 7734 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7735 imm0_255:$imm8, 7736 (i32 imm:$shift)))]>; 7737} 7738 7739class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7740 RegisterOperand vectype, string asm, 7741 string kind, list<dag> pattern> 7742 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7743 (ins move_vec_shift:$shift), 7744 "$shift", asm, kind, pattern> { 7745 bits<1> shift; 7746 let Inst{15-13} = cmode{3-1}; 7747 let Inst{12} = shift; 7748} 7749 7750class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7751 RegisterOperand vectype, 7752 Operand imm_type, string asm, 7753 string kind, list<dag> pattern> 7754 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7755 asm, kind, pattern> { 7756 let Inst{15-12} = cmode; 7757} 7758 7759class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7760 list<dag> pattern> 7761 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7762 "\t$Rd, $imm8", "", pattern> { 7763 let Inst{15-12} = cmode; 7764 let DecoderMethod = "DecodeModImmInstruction"; 7765} 7766 7767//---------------------------------------------------------------------------- 7768// AdvSIMD indexed element 7769//---------------------------------------------------------------------------- 7770 7771let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7772class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7773 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7774 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7775 string apple_kind, string dst_kind, string lhs_kind, 7776 string rhs_kind, list<dag> pattern> 7777 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7778 asm, 7779 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7780 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7781 Sched<[WriteV]> { 7782 bits<5> Rd; 7783 bits<5> Rn; 7784 bits<5> Rm; 7785 7786 let Inst{31} = 0; 7787 let Inst{30} = Q; 7788 let Inst{29} = U; 7789 let Inst{28} = Scalar; 7790 let Inst{27-24} = 0b1111; 7791 let Inst{23-22} = size; 7792 // Bit 21 must be set by the derived class. 7793 let Inst{20-16} = Rm; 7794 let Inst{15-12} = opc; 7795 // Bit 11 must be set by the derived class. 7796 let Inst{10} = 0; 7797 let Inst{9-5} = Rn; 7798 let Inst{4-0} = Rd; 7799} 7800 7801let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7802class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7803 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7804 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7805 string apple_kind, string dst_kind, string lhs_kind, 7806 string rhs_kind, list<dag> pattern> 7807 : I<(outs dst_reg:$dst), 7808 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7809 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7810 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7811 Sched<[WriteV]> { 7812 bits<5> Rd; 7813 bits<5> Rn; 7814 bits<5> Rm; 7815 7816 let Inst{31} = 0; 7817 let Inst{30} = Q; 7818 let Inst{29} = U; 7819 let Inst{28} = Scalar; 7820 let Inst{27-24} = 0b1111; 7821 let Inst{23-22} = size; 7822 // Bit 21 must be set by the derived class. 7823 let Inst{20-16} = Rm; 7824 let Inst{15-12} = opc; 7825 // Bit 11 must be set by the derived class. 7826 let Inst{10} = 0; 7827 let Inst{9-5} = Rn; 7828 let Inst{4-0} = Rd; 7829} 7830 7831 7832//---------------------------------------------------------------------------- 7833// Armv8.6 BFloat16 Extension 7834//---------------------------------------------------------------------------- 7835let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 7836 7837class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 7838 string kind2, RegisterOperand RegType, 7839 ValueType AccumType, ValueType InputType> 7840 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 7841 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 7842 (InputType RegType:$Rn), 7843 (InputType RegType:$Rm)))]> { 7844 let AsmString = !strconcat(asm, 7845 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 7846 ", $Rm" # kind2 # "}"); 7847} 7848 7849multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 7850 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 7851 v2f32, v4bf16>; 7852 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 7853 v4f32, v8bf16>; 7854} 7855 7856class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 7857 string dst_kind, string lhs_kind, 7858 string rhs_kind, 7859 RegisterOperand RegType, 7860 ValueType AccumType, 7861 ValueType InputType> 7862 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 7863 RegType, RegType, V128, VectorIndexS, 7864 asm, "", dst_kind, lhs_kind, rhs_kind, 7865 [(set (AccumType RegType:$dst), 7866 (AccumType (int_aarch64_neon_bfdot 7867 (AccumType RegType:$Rd), 7868 (InputType RegType:$Rn), 7869 (InputType (bitconvert (AccumType 7870 (AArch64duplane32 (v4f32 V128:$Rm), 7871 VectorIndexS:$idx)))))))]> { 7872 7873 bits<2> idx; 7874 let Inst{21} = idx{0}; // L 7875 let Inst{11} = idx{1}; // H 7876} 7877 7878multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 7879 7880 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 7881 ".2h", V64, v2f32, v4bf16>; 7882 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 7883 ".2h", V128, v4f32, v8bf16>; 7884} 7885 7886class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 7887 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 7888 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 7889 (v8bf16 V128:$Rn), 7890 (v8bf16 V128:$Rm)))]> { 7891 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 7892} 7893 7894class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 7895 : I<(outs V128:$dst), 7896 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 7897 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 7898 [(set (v4f32 V128:$dst), 7899 (v4f32 (OpNode (v4f32 V128:$Rd), 7900 (v8bf16 V128:$Rn), 7901 (v8bf16 7902 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 7903 VectorIndexH:$idx)))))]>, 7904 Sched<[WriteV]> { 7905 bits<5> Rd; 7906 bits<5> Rn; 7907 bits<4> Rm; 7908 bits<3> idx; 7909 7910 let Inst{31} = 0; 7911 let Inst{30} = Q; 7912 let Inst{29-22} = 0b00111111; 7913 let Inst{21-20} = idx{1-0}; 7914 let Inst{19-16} = Rm; 7915 let Inst{15-12} = 0b1111; 7916 let Inst{11} = idx{2}; // H 7917 let Inst{10} = 0; 7918 let Inst{9-5} = Rn; 7919 let Inst{4-0} = Rd; 7920} 7921 7922class SIMDThreeSameVectorBF16MatrixMul<string asm> 7923 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 7924 V128, asm, ".4s", 7925 [(set (v4f32 V128:$dst), 7926 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 7927 (v8bf16 V128:$Rn), 7928 (v8bf16 V128:$Rm)))]> { 7929 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 7930 ", $Rm", ".8h", "}"); 7931} 7932 7933class SIMD_BFCVTN 7934 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 7935 "bfcvtn", ".4h", ".4s", 7936 [(set (v8bf16 V128:$Rd), 7937 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 7938 7939class SIMD_BFCVTN2 7940 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 7941 "bfcvtn2", ".8h", ".4s", 7942 [(set (v8bf16 V128:$dst), 7943 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 7944 7945class BF16ToSinglePrecision<string asm> 7946 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 7947 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 7948 Sched<[WriteFCvt]> { 7949 bits<5> Rd; 7950 bits<5> Rn; 7951 let Inst{31-10} = 0b0001111001100011010000; 7952 let Inst{9-5} = Rn; 7953 let Inst{4-0} = Rd; 7954} 7955} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 7956 7957//---------------------------------------------------------------------------- 7958// Armv8.6 Matrix Multiply Extension 7959//---------------------------------------------------------------------------- 7960 7961class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 7962 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 7963 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 7964 (v16i8 V128:$Rn), 7965 (v16i8 V128:$Rm)))]> { 7966 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 7967} 7968 7969//---------------------------------------------------------------------------- 7970// ARMv8.2-A Dot Product Instructions (Indexed) 7971class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 7972 string dst_kind, string lhs_kind, string rhs_kind, 7973 RegisterOperand RegType, 7974 ValueType AccumType, ValueType InputType, 7975 SDPatternOperator OpNode> : 7976 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 7977 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 7978 [(set (AccumType RegType:$dst), 7979 (AccumType (OpNode (AccumType RegType:$Rd), 7980 (InputType RegType:$Rn), 7981 (InputType (bitconvert (AccumType 7982 (AArch64duplane32 (v4i32 V128:$Rm), 7983 VectorIndexS:$idx)))))))]> { 7984 bits<2> idx; 7985 let Inst{21} = idx{0}; // L 7986 let Inst{11} = idx{1}; // H 7987} 7988 7989multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 7990 SDPatternOperator OpNode> { 7991 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 7992 V64, v2i32, v8i8, OpNode>; 7993 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 7994 V128, v4i32, v16i8, OpNode>; 7995} 7996 7997// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 7998class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 7999 string dst_kind, string lhs_kind, 8000 string rhs_kind, RegisterOperand RegType, 8001 ValueType AccumType, ValueType InputType, 8002 SDPatternOperator OpNode> : 8003 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8004 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8005 [(set (AccumType RegType:$dst), 8006 (AccumType (OpNode (AccumType RegType:$Rd), 8007 (InputType RegType:$Rn), 8008 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8009 VectorIndexH:$idx)))))]> { 8010 // idx = H:L:M 8011 bits<3> idx; 8012 let Inst{11} = idx{2}; // H 8013 let Inst{21} = idx{1}; // L 8014 let Inst{20} = idx{0}; // M 8015} 8016 8017multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8018 SDPatternOperator OpNode> { 8019 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8020 V64, v2f32, v4f16, OpNode>; 8021 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8022 V128, v4f32, v8f16, OpNode>; 8023} 8024 8025multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8026 SDPatternOperator OpNode> { 8027 let Predicates = [HasNEON, HasFullFP16] in { 8028 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8029 V64, V64, 8030 V128_lo, VectorIndexH, 8031 asm, ".4h", ".4h", ".4h", ".h", 8032 [(set (v4f16 V64:$Rd), 8033 (OpNode (v4f16 V64:$Rn), 8034 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8035 bits<3> idx; 8036 let Inst{11} = idx{2}; 8037 let Inst{21} = idx{1}; 8038 let Inst{20} = idx{0}; 8039 } 8040 8041 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8042 V128, V128, 8043 V128_lo, VectorIndexH, 8044 asm, ".8h", ".8h", ".8h", ".h", 8045 [(set (v8f16 V128:$Rd), 8046 (OpNode (v8f16 V128:$Rn), 8047 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8048 bits<3> idx; 8049 let Inst{11} = idx{2}; 8050 let Inst{21} = idx{1}; 8051 let Inst{20} = idx{0}; 8052 } 8053 } // Predicates = [HasNEON, HasFullFP16] 8054 8055 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8056 V64, V64, 8057 V128, VectorIndexS, 8058 asm, ".2s", ".2s", ".2s", ".s", 8059 [(set (v2f32 V64:$Rd), 8060 (OpNode (v2f32 V64:$Rn), 8061 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8062 bits<2> idx; 8063 let Inst{11} = idx{1}; 8064 let Inst{21} = idx{0}; 8065 } 8066 8067 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8068 V128, V128, 8069 V128, VectorIndexS, 8070 asm, ".4s", ".4s", ".4s", ".s", 8071 [(set (v4f32 V128:$Rd), 8072 (OpNode (v4f32 V128:$Rn), 8073 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8074 bits<2> idx; 8075 let Inst{11} = idx{1}; 8076 let Inst{21} = idx{0}; 8077 } 8078 8079 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8080 V128, V128, 8081 V128, VectorIndexD, 8082 asm, ".2d", ".2d", ".2d", ".d", 8083 [(set (v2f64 V128:$Rd), 8084 (OpNode (v2f64 V128:$Rn), 8085 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8086 bits<1> idx; 8087 let Inst{11} = idx{0}; 8088 let Inst{21} = 0; 8089 } 8090 8091 let Predicates = [HasNEON, HasFullFP16] in { 8092 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8093 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8094 asm, ".h", "", "", ".h", 8095 [(set (f16 FPR16Op:$Rd), 8096 (OpNode (f16 FPR16Op:$Rn), 8097 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8098 VectorIndexH:$idx))))]> { 8099 bits<3> idx; 8100 let Inst{11} = idx{2}; 8101 let Inst{21} = idx{1}; 8102 let Inst{20} = idx{0}; 8103 } 8104 } // Predicates = [HasNEON, HasFullFP16] 8105 8106 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8107 FPR32Op, FPR32Op, V128, VectorIndexS, 8108 asm, ".s", "", "", ".s", 8109 [(set (f32 FPR32Op:$Rd), 8110 (OpNode (f32 FPR32Op:$Rn), 8111 (f32 (vector_extract (v4f32 V128:$Rm), 8112 VectorIndexS:$idx))))]> { 8113 bits<2> idx; 8114 let Inst{11} = idx{1}; 8115 let Inst{21} = idx{0}; 8116 } 8117 8118 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8119 FPR64Op, FPR64Op, V128, VectorIndexD, 8120 asm, ".d", "", "", ".d", 8121 [(set (f64 FPR64Op:$Rd), 8122 (OpNode (f64 FPR64Op:$Rn), 8123 (f64 (vector_extract (v2f64 V128:$Rm), 8124 VectorIndexD:$idx))))]> { 8125 bits<1> idx; 8126 let Inst{11} = idx{0}; 8127 let Inst{21} = 0; 8128 } 8129} 8130 8131multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8132 let Predicates = [HasNEON, HasFullFP16] in { 8133 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8134 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8135 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8136 VectorIndexH:$idx))), 8137 (!cast<Instruction>(INST # "v8i16_indexed") 8138 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8139 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8140 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8141 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8142 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8143 8144 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8145 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8146 VectorIndexH:$idx))), 8147 (!cast<Instruction>(INST # "v4i16_indexed") 8148 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8149 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8150 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8151 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8152 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8153 8154 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8155 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8156 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8157 V128_lo:$Rm, VectorIndexH:$idx)>; 8158 } // Predicates = [HasNEON, HasFullFP16] 8159 8160 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8161 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8162 (AArch64duplane32 (v4f32 V128:$Rm), 8163 VectorIndexS:$idx))), 8164 (!cast<Instruction>(INST # v2i32_indexed) 8165 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8166 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8167 (AArch64dup (f32 FPR32Op:$Rm)))), 8168 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8169 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8170 8171 8172 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8173 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8174 (AArch64duplane32 (v4f32 V128:$Rm), 8175 VectorIndexS:$idx))), 8176 (!cast<Instruction>(INST # "v4i32_indexed") 8177 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8178 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8179 (AArch64dup (f32 FPR32Op:$Rm)))), 8180 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8181 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8182 8183 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8184 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8185 (AArch64duplane64 (v2f64 V128:$Rm), 8186 VectorIndexD:$idx))), 8187 (!cast<Instruction>(INST # "v2i64_indexed") 8188 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8189 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8190 (AArch64dup (f64 FPR64Op:$Rm)))), 8191 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8192 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8193 8194 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8195 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8196 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8197 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8198 V128:$Rm, VectorIndexS:$idx)>; 8199 8200 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8201 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8202 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8203 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8204 V128:$Rm, VectorIndexD:$idx)>; 8205} 8206 8207multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8208 let Predicates = [HasNEON, HasFullFP16] in { 8209 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8210 V128_lo, VectorIndexH, 8211 asm, ".4h", ".4h", ".4h", ".h", []> { 8212 bits<3> idx; 8213 let Inst{11} = idx{2}; 8214 let Inst{21} = idx{1}; 8215 let Inst{20} = idx{0}; 8216 } 8217 8218 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8219 V128, V128, 8220 V128_lo, VectorIndexH, 8221 asm, ".8h", ".8h", ".8h", ".h", []> { 8222 bits<3> idx; 8223 let Inst{11} = idx{2}; 8224 let Inst{21} = idx{1}; 8225 let Inst{20} = idx{0}; 8226 } 8227 } // Predicates = [HasNEON, HasFullFP16] 8228 8229 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8230 V128, VectorIndexS, 8231 asm, ".2s", ".2s", ".2s", ".s", []> { 8232 bits<2> idx; 8233 let Inst{11} = idx{1}; 8234 let Inst{21} = idx{0}; 8235 } 8236 8237 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8238 V128, V128, 8239 V128, VectorIndexS, 8240 asm, ".4s", ".4s", ".4s", ".s", []> { 8241 bits<2> idx; 8242 let Inst{11} = idx{1}; 8243 let Inst{21} = idx{0}; 8244 } 8245 8246 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8247 V128, V128, 8248 V128, VectorIndexD, 8249 asm, ".2d", ".2d", ".2d", ".d", []> { 8250 bits<1> idx; 8251 let Inst{11} = idx{0}; 8252 let Inst{21} = 0; 8253 } 8254 8255 let Predicates = [HasNEON, HasFullFP16] in { 8256 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8257 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8258 asm, ".h", "", "", ".h", []> { 8259 bits<3> idx; 8260 let Inst{11} = idx{2}; 8261 let Inst{21} = idx{1}; 8262 let Inst{20} = idx{0}; 8263 } 8264 } // Predicates = [HasNEON, HasFullFP16] 8265 8266 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8267 FPR32Op, FPR32Op, V128, VectorIndexS, 8268 asm, ".s", "", "", ".s", []> { 8269 bits<2> idx; 8270 let Inst{11} = idx{1}; 8271 let Inst{21} = idx{0}; 8272 } 8273 8274 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8275 FPR64Op, FPR64Op, V128, VectorIndexD, 8276 asm, ".d", "", "", ".d", []> { 8277 bits<1> idx; 8278 let Inst{11} = idx{0}; 8279 let Inst{21} = 0; 8280 } 8281} 8282 8283multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8284 SDPatternOperator OpNodeLaneQ> { 8285 8286 def : Pat<(v4i16 (OpNodeLane 8287 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8288 VectorIndexS32b:$idx)), 8289 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8290 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8291 (UImmS1XForm $idx))>; 8292 8293 def : Pat<(v4i16 (OpNodeLaneQ 8294 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8295 VectorIndexH32b:$idx)), 8296 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8297 (UImmS1XForm $idx))>; 8298 8299 def : Pat<(v8i16 (OpNodeLane 8300 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8301 VectorIndexS32b:$idx)), 8302 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8303 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8304 (UImmS1XForm $idx))>; 8305 8306 def : Pat<(v8i16 (OpNodeLaneQ 8307 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8308 VectorIndexH32b:$idx)), 8309 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8310 (UImmS1XForm $idx))>; 8311 8312 def : Pat<(v2i32 (OpNodeLane 8313 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8314 VectorIndexD32b:$idx)), 8315 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8316 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8317 (UImmS1XForm $idx))>; 8318 8319 def : Pat<(v2i32 (OpNodeLaneQ 8320 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8321 VectorIndexS32b:$idx)), 8322 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8323 (UImmS1XForm $idx))>; 8324 8325 def : Pat<(v4i32 (OpNodeLane 8326 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8327 VectorIndexD32b:$idx)), 8328 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8329 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8330 (UImmS1XForm $idx))>; 8331 8332 def : Pat<(v4i32 (OpNodeLaneQ 8333 (v4i32 V128:$Rn), 8334 (v4i32 V128:$Rm), 8335 VectorIndexS32b:$idx)), 8336 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8337 (UImmS1XForm $idx))>; 8338 8339} 8340 8341multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8342 SDPatternOperator OpNode> { 8343 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8344 V128_lo, VectorIndexH, 8345 asm, ".4h", ".4h", ".4h", ".h", 8346 [(set (v4i16 V64:$Rd), 8347 (OpNode (v4i16 V64:$Rn), 8348 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8349 bits<3> idx; 8350 let Inst{11} = idx{2}; 8351 let Inst{21} = idx{1}; 8352 let Inst{20} = idx{0}; 8353 } 8354 8355 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8356 V128, V128, 8357 V128_lo, VectorIndexH, 8358 asm, ".8h", ".8h", ".8h", ".h", 8359 [(set (v8i16 V128:$Rd), 8360 (OpNode (v8i16 V128:$Rn), 8361 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8362 bits<3> idx; 8363 let Inst{11} = idx{2}; 8364 let Inst{21} = idx{1}; 8365 let Inst{20} = idx{0}; 8366 } 8367 8368 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8369 V64, V64, 8370 V128, VectorIndexS, 8371 asm, ".2s", ".2s", ".2s", ".s", 8372 [(set (v2i32 V64:$Rd), 8373 (OpNode (v2i32 V64:$Rn), 8374 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8375 bits<2> idx; 8376 let Inst{11} = idx{1}; 8377 let Inst{21} = idx{0}; 8378 } 8379 8380 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8381 V128, V128, 8382 V128, VectorIndexS, 8383 asm, ".4s", ".4s", ".4s", ".s", 8384 [(set (v4i32 V128:$Rd), 8385 (OpNode (v4i32 V128:$Rn), 8386 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8387 bits<2> idx; 8388 let Inst{11} = idx{1}; 8389 let Inst{21} = idx{0}; 8390 } 8391 8392 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8393 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8394 asm, ".h", "", "", ".h", []> { 8395 bits<3> idx; 8396 let Inst{11} = idx{2}; 8397 let Inst{21} = idx{1}; 8398 let Inst{20} = idx{0}; 8399 } 8400 8401 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8402 FPR32Op, FPR32Op, V128, VectorIndexS, 8403 asm, ".s", "", "", ".s", 8404 [(set (i32 FPR32Op:$Rd), 8405 (OpNode FPR32Op:$Rn, 8406 (i32 (vector_extract (v4i32 V128:$Rm), 8407 VectorIndexS:$idx))))]> { 8408 bits<2> idx; 8409 let Inst{11} = idx{1}; 8410 let Inst{21} = idx{0}; 8411 } 8412} 8413 8414multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8415 SDPatternOperator OpNode> { 8416 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8417 V64, V64, 8418 V128_lo, VectorIndexH, 8419 asm, ".4h", ".4h", ".4h", ".h", 8420 [(set (v4i16 V64:$Rd), 8421 (OpNode (v4i16 V64:$Rn), 8422 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8423 bits<3> idx; 8424 let Inst{11} = idx{2}; 8425 let Inst{21} = idx{1}; 8426 let Inst{20} = idx{0}; 8427 } 8428 8429 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8430 V128, V128, 8431 V128_lo, VectorIndexH, 8432 asm, ".8h", ".8h", ".8h", ".h", 8433 [(set (v8i16 V128:$Rd), 8434 (OpNode (v8i16 V128:$Rn), 8435 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8436 bits<3> idx; 8437 let Inst{11} = idx{2}; 8438 let Inst{21} = idx{1}; 8439 let Inst{20} = idx{0}; 8440 } 8441 8442 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8443 V64, V64, 8444 V128, VectorIndexS, 8445 asm, ".2s", ".2s", ".2s", ".s", 8446 [(set (v2i32 V64:$Rd), 8447 (OpNode (v2i32 V64:$Rn), 8448 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8449 bits<2> idx; 8450 let Inst{11} = idx{1}; 8451 let Inst{21} = idx{0}; 8452 } 8453 8454 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8455 V128, V128, 8456 V128, VectorIndexS, 8457 asm, ".4s", ".4s", ".4s", ".s", 8458 [(set (v4i32 V128:$Rd), 8459 (OpNode (v4i32 V128:$Rn), 8460 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8461 bits<2> idx; 8462 let Inst{11} = idx{1}; 8463 let Inst{21} = idx{0}; 8464 } 8465} 8466 8467multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8468 SDPatternOperator OpNode> { 8469 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8470 V128_lo, VectorIndexH, 8471 asm, ".4h", ".4h", ".4h", ".h", 8472 [(set (v4i16 V64:$dst), 8473 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8474 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8475 bits<3> idx; 8476 let Inst{11} = idx{2}; 8477 let Inst{21} = idx{1}; 8478 let Inst{20} = idx{0}; 8479 } 8480 8481 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8482 V128, V128, 8483 V128_lo, VectorIndexH, 8484 asm, ".8h", ".8h", ".8h", ".h", 8485 [(set (v8i16 V128:$dst), 8486 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8487 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8488 bits<3> idx; 8489 let Inst{11} = idx{2}; 8490 let Inst{21} = idx{1}; 8491 let Inst{20} = idx{0}; 8492 } 8493 8494 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8495 V64, V64, 8496 V128, VectorIndexS, 8497 asm, ".2s", ".2s", ".2s", ".s", 8498 [(set (v2i32 V64:$dst), 8499 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8500 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8501 bits<2> idx; 8502 let Inst{11} = idx{1}; 8503 let Inst{21} = idx{0}; 8504 } 8505 8506 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8507 V128, V128, 8508 V128, VectorIndexS, 8509 asm, ".4s", ".4s", ".4s", ".s", 8510 [(set (v4i32 V128:$dst), 8511 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8512 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8513 bits<2> idx; 8514 let Inst{11} = idx{1}; 8515 let Inst{21} = idx{0}; 8516 } 8517} 8518 8519multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8520 SDPatternOperator OpNode> { 8521 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8522 V128, V64, 8523 V128_lo, VectorIndexH, 8524 asm, ".4s", ".4s", ".4h", ".h", 8525 [(set (v4i32 V128:$Rd), 8526 (OpNode (v4i16 V64:$Rn), 8527 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8528 bits<3> idx; 8529 let Inst{11} = idx{2}; 8530 let Inst{21} = idx{1}; 8531 let Inst{20} = idx{0}; 8532 } 8533 8534 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8535 V128, V128, 8536 V128_lo, VectorIndexH, 8537 asm#"2", ".4s", ".4s", ".8h", ".h", 8538 [(set (v4i32 V128:$Rd), 8539 (OpNode (extract_high_v8i16 V128:$Rn), 8540 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8541 VectorIndexH:$idx))))]> { 8542 8543 bits<3> idx; 8544 let Inst{11} = idx{2}; 8545 let Inst{21} = idx{1}; 8546 let Inst{20} = idx{0}; 8547 } 8548 8549 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8550 V128, V64, 8551 V128, VectorIndexS, 8552 asm, ".2d", ".2d", ".2s", ".s", 8553 [(set (v2i64 V128:$Rd), 8554 (OpNode (v2i32 V64:$Rn), 8555 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8556 bits<2> idx; 8557 let Inst{11} = idx{1}; 8558 let Inst{21} = idx{0}; 8559 } 8560 8561 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8562 V128, V128, 8563 V128, VectorIndexS, 8564 asm#"2", ".2d", ".2d", ".4s", ".s", 8565 [(set (v2i64 V128:$Rd), 8566 (OpNode (extract_high_v4i32 V128:$Rn), 8567 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8568 VectorIndexS:$idx))))]> { 8569 bits<2> idx; 8570 let Inst{11} = idx{1}; 8571 let Inst{21} = idx{0}; 8572 } 8573 8574 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8575 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8576 asm, ".h", "", "", ".h", []> { 8577 bits<3> idx; 8578 let Inst{11} = idx{2}; 8579 let Inst{21} = idx{1}; 8580 let Inst{20} = idx{0}; 8581 } 8582 8583 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8584 FPR64Op, FPR32Op, V128, VectorIndexS, 8585 asm, ".s", "", "", ".s", []> { 8586 bits<2> idx; 8587 let Inst{11} = idx{1}; 8588 let Inst{21} = idx{0}; 8589 } 8590} 8591 8592multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8593 SDPatternOperator Accum> { 8594 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8595 V128, V64, 8596 V128_lo, VectorIndexH, 8597 asm, ".4s", ".4s", ".4h", ".h", 8598 [(set (v4i32 V128:$dst), 8599 (Accum (v4i32 V128:$Rd), 8600 (v4i32 (int_aarch64_neon_sqdmull 8601 (v4i16 V64:$Rn), 8602 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8603 VectorIndexH:$idx))))))]> { 8604 bits<3> idx; 8605 let Inst{11} = idx{2}; 8606 let Inst{21} = idx{1}; 8607 let Inst{20} = idx{0}; 8608 } 8609 8610 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8611 // intermediate EXTRACT_SUBREG would be untyped. 8612 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8613 (i32 (vector_extract (v4i32 8614 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8615 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8616 VectorIndexH:$idx)))), 8617 (i64 0))))), 8618 (EXTRACT_SUBREG 8619 (!cast<Instruction>(NAME # v4i16_indexed) 8620 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8621 V128_lo:$Rm, VectorIndexH:$idx), 8622 ssub)>; 8623 8624 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8625 V128, V128, 8626 V128_lo, VectorIndexH, 8627 asm#"2", ".4s", ".4s", ".8h", ".h", 8628 [(set (v4i32 V128:$dst), 8629 (Accum (v4i32 V128:$Rd), 8630 (v4i32 (int_aarch64_neon_sqdmull 8631 (extract_high_v8i16 V128:$Rn), 8632 (extract_high_v8i16 8633 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8634 VectorIndexH:$idx))))))]> { 8635 bits<3> idx; 8636 let Inst{11} = idx{2}; 8637 let Inst{21} = idx{1}; 8638 let Inst{20} = idx{0}; 8639 } 8640 8641 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8642 V128, V64, 8643 V128, VectorIndexS, 8644 asm, ".2d", ".2d", ".2s", ".s", 8645 [(set (v2i64 V128:$dst), 8646 (Accum (v2i64 V128:$Rd), 8647 (v2i64 (int_aarch64_neon_sqdmull 8648 (v2i32 V64:$Rn), 8649 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8650 VectorIndexS:$idx))))))]> { 8651 bits<2> idx; 8652 let Inst{11} = idx{1}; 8653 let Inst{21} = idx{0}; 8654 } 8655 8656 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8657 V128, V128, 8658 V128, VectorIndexS, 8659 asm#"2", ".2d", ".2d", ".4s", ".s", 8660 [(set (v2i64 V128:$dst), 8661 (Accum (v2i64 V128:$Rd), 8662 (v2i64 (int_aarch64_neon_sqdmull 8663 (extract_high_v4i32 V128:$Rn), 8664 (extract_high_v4i32 8665 (AArch64duplane32 (v4i32 V128:$Rm), 8666 VectorIndexS:$idx))))))]> { 8667 bits<2> idx; 8668 let Inst{11} = idx{1}; 8669 let Inst{21} = idx{0}; 8670 } 8671 8672 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8673 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8674 asm, ".h", "", "", ".h", []> { 8675 bits<3> idx; 8676 let Inst{11} = idx{2}; 8677 let Inst{21} = idx{1}; 8678 let Inst{20} = idx{0}; 8679 } 8680 8681 8682 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8683 FPR64Op, FPR32Op, V128, VectorIndexS, 8684 asm, ".s", "", "", ".s", 8685 [(set (i64 FPR64Op:$dst), 8686 (Accum (i64 FPR64Op:$Rd), 8687 (i64 (int_aarch64_neon_sqdmulls_scalar 8688 (i32 FPR32Op:$Rn), 8689 (i32 (vector_extract (v4i32 V128:$Rm), 8690 VectorIndexS:$idx))))))]> { 8691 8692 bits<2> idx; 8693 let Inst{11} = idx{1}; 8694 let Inst{21} = idx{0}; 8695 } 8696} 8697 8698multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8699 SDPatternOperator OpNode> { 8700 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8701 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8702 V128, V64, 8703 V128_lo, VectorIndexH, 8704 asm, ".4s", ".4s", ".4h", ".h", 8705 [(set (v4i32 V128:$Rd), 8706 (OpNode (v4i16 V64:$Rn), 8707 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8708 bits<3> idx; 8709 let Inst{11} = idx{2}; 8710 let Inst{21} = idx{1}; 8711 let Inst{20} = idx{0}; 8712 } 8713 8714 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8715 V128, V128, 8716 V128_lo, VectorIndexH, 8717 asm#"2", ".4s", ".4s", ".8h", ".h", 8718 [(set (v4i32 V128:$Rd), 8719 (OpNode (extract_high_v8i16 V128:$Rn), 8720 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8721 VectorIndexH:$idx))))]> { 8722 8723 bits<3> idx; 8724 let Inst{11} = idx{2}; 8725 let Inst{21} = idx{1}; 8726 let Inst{20} = idx{0}; 8727 } 8728 8729 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8730 V128, V64, 8731 V128, VectorIndexS, 8732 asm, ".2d", ".2d", ".2s", ".s", 8733 [(set (v2i64 V128:$Rd), 8734 (OpNode (v2i32 V64:$Rn), 8735 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8736 bits<2> idx; 8737 let Inst{11} = idx{1}; 8738 let Inst{21} = idx{0}; 8739 } 8740 8741 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8742 V128, V128, 8743 V128, VectorIndexS, 8744 asm#"2", ".2d", ".2d", ".4s", ".s", 8745 [(set (v2i64 V128:$Rd), 8746 (OpNode (extract_high_v4i32 V128:$Rn), 8747 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8748 VectorIndexS:$idx))))]> { 8749 bits<2> idx; 8750 let Inst{11} = idx{1}; 8751 let Inst{21} = idx{0}; 8752 } 8753 } 8754} 8755 8756multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8757 SDPatternOperator OpNode> { 8758 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8759 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8760 V128, V64, 8761 V128_lo, VectorIndexH, 8762 asm, ".4s", ".4s", ".4h", ".h", 8763 [(set (v4i32 V128:$dst), 8764 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8765 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8766 bits<3> idx; 8767 let Inst{11} = idx{2}; 8768 let Inst{21} = idx{1}; 8769 let Inst{20} = idx{0}; 8770 } 8771 8772 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8773 V128, V128, 8774 V128_lo, VectorIndexH, 8775 asm#"2", ".4s", ".4s", ".8h", ".h", 8776 [(set (v4i32 V128:$dst), 8777 (OpNode (v4i32 V128:$Rd), 8778 (extract_high_v8i16 V128:$Rn), 8779 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8780 VectorIndexH:$idx))))]> { 8781 bits<3> idx; 8782 let Inst{11} = idx{2}; 8783 let Inst{21} = idx{1}; 8784 let Inst{20} = idx{0}; 8785 } 8786 8787 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8788 V128, V64, 8789 V128, VectorIndexS, 8790 asm, ".2d", ".2d", ".2s", ".s", 8791 [(set (v2i64 V128:$dst), 8792 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8793 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8794 bits<2> idx; 8795 let Inst{11} = idx{1}; 8796 let Inst{21} = idx{0}; 8797 } 8798 8799 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8800 V128, V128, 8801 V128, VectorIndexS, 8802 asm#"2", ".2d", ".2d", ".4s", ".s", 8803 [(set (v2i64 V128:$dst), 8804 (OpNode (v2i64 V128:$Rd), 8805 (extract_high_v4i32 V128:$Rn), 8806 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8807 VectorIndexS:$idx))))]> { 8808 bits<2> idx; 8809 let Inst{11} = idx{1}; 8810 let Inst{21} = idx{0}; 8811 } 8812 } 8813} 8814 8815//---------------------------------------------------------------------------- 8816// AdvSIMD scalar shift by immediate 8817//---------------------------------------------------------------------------- 8818 8819let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8820class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8821 RegisterClass regtype1, RegisterClass regtype2, 8822 Operand immtype, string asm, list<dag> pattern> 8823 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8824 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8825 Sched<[WriteV]> { 8826 bits<5> Rd; 8827 bits<5> Rn; 8828 bits<7> imm; 8829 let Inst{31-30} = 0b01; 8830 let Inst{29} = U; 8831 let Inst{28-23} = 0b111110; 8832 let Inst{22-16} = fixed_imm; 8833 let Inst{15-11} = opc; 8834 let Inst{10} = 1; 8835 let Inst{9-5} = Rn; 8836 let Inst{4-0} = Rd; 8837} 8838 8839let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8840class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8841 RegisterClass regtype1, RegisterClass regtype2, 8842 Operand immtype, string asm, list<dag> pattern> 8843 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8844 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8845 Sched<[WriteV]> { 8846 bits<5> Rd; 8847 bits<5> Rn; 8848 bits<7> imm; 8849 let Inst{31-30} = 0b01; 8850 let Inst{29} = U; 8851 let Inst{28-23} = 0b111110; 8852 let Inst{22-16} = fixed_imm; 8853 let Inst{15-11} = opc; 8854 let Inst{10} = 1; 8855 let Inst{9-5} = Rn; 8856 let Inst{4-0} = Rd; 8857} 8858 8859 8860multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8861 let Predicates = [HasNEON, HasFullFP16] in { 8862 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8863 FPR16, FPR16, vecshiftR16, asm, []> { 8864 let Inst{19-16} = imm{3-0}; 8865 } 8866 } // Predicates = [HasNEON, HasFullFP16] 8867 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8868 FPR32, FPR32, vecshiftR32, asm, []> { 8869 let Inst{20-16} = imm{4-0}; 8870 } 8871 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8872 FPR64, FPR64, vecshiftR64, asm, []> { 8873 let Inst{21-16} = imm{5-0}; 8874 } 8875} 8876 8877multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8878 SDPatternOperator OpNode> { 8879 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8880 FPR64, FPR64, vecshiftR64, asm, 8881 [(set (i64 FPR64:$Rd), 8882 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8883 let Inst{21-16} = imm{5-0}; 8884 } 8885 8886 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8887 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8888} 8889 8890multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8891 SDPatternOperator OpNode = null_frag> { 8892 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8893 FPR64, FPR64, vecshiftR64, asm, 8894 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8895 (i32 vecshiftR64:$imm)))]> { 8896 let Inst{21-16} = imm{5-0}; 8897 } 8898 8899 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8900 (i32 vecshiftR64:$imm))), 8901 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8902 vecshiftR64:$imm)>; 8903} 8904 8905multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8906 SDPatternOperator OpNode> { 8907 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8908 FPR64, FPR64, vecshiftL64, asm, 8909 [(set (v1i64 FPR64:$Rd), 8910 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8911 let Inst{21-16} = imm{5-0}; 8912 } 8913} 8914 8915let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8916multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8917 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8918 FPR64, FPR64, vecshiftL64, asm, []> { 8919 let Inst{21-16} = imm{5-0}; 8920 } 8921} 8922 8923let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8924multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8925 SDPatternOperator OpNode = null_frag> { 8926 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8927 FPR8, FPR16, vecshiftR8, asm, []> { 8928 let Inst{18-16} = imm{2-0}; 8929 } 8930 8931 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8932 FPR16, FPR32, vecshiftR16, asm, []> { 8933 let Inst{19-16} = imm{3-0}; 8934 } 8935 8936 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8937 FPR32, FPR64, vecshiftR32, asm, 8938 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 8939 let Inst{20-16} = imm{4-0}; 8940 } 8941} 8942 8943multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 8944 SDPatternOperator OpNode> { 8945 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8946 FPR8, FPR8, vecshiftL8, asm, []> { 8947 let Inst{18-16} = imm{2-0}; 8948 } 8949 8950 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8951 FPR16, FPR16, vecshiftL16, asm, []> { 8952 let Inst{19-16} = imm{3-0}; 8953 } 8954 8955 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8956 FPR32, FPR32, vecshiftL32, asm, 8957 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 8958 let Inst{20-16} = imm{4-0}; 8959 } 8960 8961 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8962 FPR64, FPR64, vecshiftL64, asm, 8963 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8964 let Inst{21-16} = imm{5-0}; 8965 } 8966 8967 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8968 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8969} 8970 8971multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 8972 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8973 FPR8, FPR8, vecshiftR8, asm, []> { 8974 let Inst{18-16} = imm{2-0}; 8975 } 8976 8977 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8978 FPR16, FPR16, vecshiftR16, asm, []> { 8979 let Inst{19-16} = imm{3-0}; 8980 } 8981 8982 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8983 FPR32, FPR32, vecshiftR32, asm, []> { 8984 let Inst{20-16} = imm{4-0}; 8985 } 8986 8987 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8988 FPR64, FPR64, vecshiftR64, asm, []> { 8989 let Inst{21-16} = imm{5-0}; 8990 } 8991} 8992 8993//---------------------------------------------------------------------------- 8994// AdvSIMD vector x indexed element 8995//---------------------------------------------------------------------------- 8996 8997let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8998class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 8999 RegisterOperand dst_reg, RegisterOperand src_reg, 9000 Operand immtype, 9001 string asm, string dst_kind, string src_kind, 9002 list<dag> pattern> 9003 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9004 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9005 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9006 Sched<[WriteV]> { 9007 bits<5> Rd; 9008 bits<5> Rn; 9009 let Inst{31} = 0; 9010 let Inst{30} = Q; 9011 let Inst{29} = U; 9012 let Inst{28-23} = 0b011110; 9013 let Inst{22-16} = fixed_imm; 9014 let Inst{15-11} = opc; 9015 let Inst{10} = 1; 9016 let Inst{9-5} = Rn; 9017 let Inst{4-0} = Rd; 9018} 9019 9020let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9021class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9022 RegisterOperand vectype1, RegisterOperand vectype2, 9023 Operand immtype, 9024 string asm, string dst_kind, string src_kind, 9025 list<dag> pattern> 9026 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9027 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9028 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9029 Sched<[WriteV]> { 9030 bits<5> Rd; 9031 bits<5> Rn; 9032 let Inst{31} = 0; 9033 let Inst{30} = Q; 9034 let Inst{29} = U; 9035 let Inst{28-23} = 0b011110; 9036 let Inst{22-16} = fixed_imm; 9037 let Inst{15-11} = opc; 9038 let Inst{10} = 1; 9039 let Inst{9-5} = Rn; 9040 let Inst{4-0} = Rd; 9041} 9042 9043multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9044 Intrinsic OpNode> { 9045 let Predicates = [HasNEON, HasFullFP16] in { 9046 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9047 V64, V64, vecshiftR16, 9048 asm, ".4h", ".4h", 9049 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9050 bits<4> imm; 9051 let Inst{19-16} = imm; 9052 } 9053 9054 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9055 V128, V128, vecshiftR16, 9056 asm, ".8h", ".8h", 9057 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9058 bits<4> imm; 9059 let Inst{19-16} = imm; 9060 } 9061 } // Predicates = [HasNEON, HasFullFP16] 9062 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9063 V64, V64, vecshiftR32, 9064 asm, ".2s", ".2s", 9065 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9066 bits<5> imm; 9067 let Inst{20-16} = imm; 9068 } 9069 9070 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9071 V128, V128, vecshiftR32, 9072 asm, ".4s", ".4s", 9073 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9074 bits<5> imm; 9075 let Inst{20-16} = imm; 9076 } 9077 9078 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9079 V128, V128, vecshiftR64, 9080 asm, ".2d", ".2d", 9081 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9082 bits<6> imm; 9083 let Inst{21-16} = imm; 9084 } 9085} 9086 9087multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9088 Intrinsic OpNode> { 9089 let Predicates = [HasNEON, HasFullFP16] in { 9090 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9091 V64, V64, vecshiftR16, 9092 asm, ".4h", ".4h", 9093 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9094 bits<4> imm; 9095 let Inst{19-16} = imm; 9096 } 9097 9098 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9099 V128, V128, vecshiftR16, 9100 asm, ".8h", ".8h", 9101 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9102 bits<4> imm; 9103 let Inst{19-16} = imm; 9104 } 9105 } // Predicates = [HasNEON, HasFullFP16] 9106 9107 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9108 V64, V64, vecshiftR32, 9109 asm, ".2s", ".2s", 9110 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9111 bits<5> imm; 9112 let Inst{20-16} = imm; 9113 } 9114 9115 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9116 V128, V128, vecshiftR32, 9117 asm, ".4s", ".4s", 9118 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9119 bits<5> imm; 9120 let Inst{20-16} = imm; 9121 } 9122 9123 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9124 V128, V128, vecshiftR64, 9125 asm, ".2d", ".2d", 9126 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9127 bits<6> imm; 9128 let Inst{21-16} = imm; 9129 } 9130} 9131 9132multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9133 SDPatternOperator OpNode> { 9134 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9135 V64, V128, vecshiftR16Narrow, 9136 asm, ".8b", ".8h", 9137 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9138 bits<3> imm; 9139 let Inst{18-16} = imm; 9140 } 9141 9142 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9143 V128, V128, vecshiftR16Narrow, 9144 asm#"2", ".16b", ".8h", []> { 9145 bits<3> imm; 9146 let Inst{18-16} = imm; 9147 let hasSideEffects = 0; 9148 } 9149 9150 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9151 V64, V128, vecshiftR32Narrow, 9152 asm, ".4h", ".4s", 9153 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9154 bits<4> imm; 9155 let Inst{19-16} = imm; 9156 } 9157 9158 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9159 V128, V128, vecshiftR32Narrow, 9160 asm#"2", ".8h", ".4s", []> { 9161 bits<4> imm; 9162 let Inst{19-16} = imm; 9163 let hasSideEffects = 0; 9164 } 9165 9166 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9167 V64, V128, vecshiftR64Narrow, 9168 asm, ".2s", ".2d", 9169 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9170 bits<5> imm; 9171 let Inst{20-16} = imm; 9172 } 9173 9174 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9175 V128, V128, vecshiftR64Narrow, 9176 asm#"2", ".4s", ".2d", []> { 9177 bits<5> imm; 9178 let Inst{20-16} = imm; 9179 let hasSideEffects = 0; 9180 } 9181 9182 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9183 // themselves, so put them here instead. 9184 9185 // Patterns involving what's effectively an insert high and a normal 9186 // intrinsic, represented by CONCAT_VECTORS. 9187 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9188 vecshiftR16Narrow:$imm)), 9189 (!cast<Instruction>(NAME # "v16i8_shift") 9190 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9191 V128:$Rn, vecshiftR16Narrow:$imm)>; 9192 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9193 vecshiftR32Narrow:$imm)), 9194 (!cast<Instruction>(NAME # "v8i16_shift") 9195 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9196 V128:$Rn, vecshiftR32Narrow:$imm)>; 9197 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9198 vecshiftR64Narrow:$imm)), 9199 (!cast<Instruction>(NAME # "v4i32_shift") 9200 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9201 V128:$Rn, vecshiftR64Narrow:$imm)>; 9202} 9203 9204multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9205 SDPatternOperator OpNode> { 9206 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9207 V64, V64, vecshiftL8, 9208 asm, ".8b", ".8b", 9209 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9210 (i32 vecshiftL8:$imm)))]> { 9211 bits<3> imm; 9212 let Inst{18-16} = imm; 9213 } 9214 9215 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9216 V128, V128, vecshiftL8, 9217 asm, ".16b", ".16b", 9218 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9219 (i32 vecshiftL8:$imm)))]> { 9220 bits<3> imm; 9221 let Inst{18-16} = imm; 9222 } 9223 9224 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9225 V64, V64, vecshiftL16, 9226 asm, ".4h", ".4h", 9227 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9228 (i32 vecshiftL16:$imm)))]> { 9229 bits<4> imm; 9230 let Inst{19-16} = imm; 9231 } 9232 9233 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9234 V128, V128, vecshiftL16, 9235 asm, ".8h", ".8h", 9236 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9237 (i32 vecshiftL16:$imm)))]> { 9238 bits<4> imm; 9239 let Inst{19-16} = imm; 9240 } 9241 9242 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9243 V64, V64, vecshiftL32, 9244 asm, ".2s", ".2s", 9245 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9246 (i32 vecshiftL32:$imm)))]> { 9247 bits<5> imm; 9248 let Inst{20-16} = imm; 9249 } 9250 9251 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9252 V128, V128, vecshiftL32, 9253 asm, ".4s", ".4s", 9254 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9255 (i32 vecshiftL32:$imm)))]> { 9256 bits<5> imm; 9257 let Inst{20-16} = imm; 9258 } 9259 9260 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9261 V128, V128, vecshiftL64, 9262 asm, ".2d", ".2d", 9263 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9264 (i32 vecshiftL64:$imm)))]> { 9265 bits<6> imm; 9266 let Inst{21-16} = imm; 9267 } 9268} 9269 9270multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9271 SDPatternOperator OpNode> { 9272 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9273 V64, V64, vecshiftR8, 9274 asm, ".8b", ".8b", 9275 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9276 (i32 vecshiftR8:$imm)))]> { 9277 bits<3> imm; 9278 let Inst{18-16} = imm; 9279 } 9280 9281 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9282 V128, V128, vecshiftR8, 9283 asm, ".16b", ".16b", 9284 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9285 (i32 vecshiftR8:$imm)))]> { 9286 bits<3> imm; 9287 let Inst{18-16} = imm; 9288 } 9289 9290 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9291 V64, V64, vecshiftR16, 9292 asm, ".4h", ".4h", 9293 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9294 (i32 vecshiftR16:$imm)))]> { 9295 bits<4> imm; 9296 let Inst{19-16} = imm; 9297 } 9298 9299 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9300 V128, V128, vecshiftR16, 9301 asm, ".8h", ".8h", 9302 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9303 (i32 vecshiftR16:$imm)))]> { 9304 bits<4> imm; 9305 let Inst{19-16} = imm; 9306 } 9307 9308 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9309 V64, V64, vecshiftR32, 9310 asm, ".2s", ".2s", 9311 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9312 (i32 vecshiftR32:$imm)))]> { 9313 bits<5> imm; 9314 let Inst{20-16} = imm; 9315 } 9316 9317 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9318 V128, V128, vecshiftR32, 9319 asm, ".4s", ".4s", 9320 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9321 (i32 vecshiftR32:$imm)))]> { 9322 bits<5> imm; 9323 let Inst{20-16} = imm; 9324 } 9325 9326 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9327 V128, V128, vecshiftR64, 9328 asm, ".2d", ".2d", 9329 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9330 (i32 vecshiftR64:$imm)))]> { 9331 bits<6> imm; 9332 let Inst{21-16} = imm; 9333 } 9334} 9335 9336let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9337multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9338 SDPatternOperator OpNode = null_frag> { 9339 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9340 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9341 [(set (v8i8 V64:$dst), 9342 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9343 (i32 vecshiftR8:$imm)))]> { 9344 bits<3> imm; 9345 let Inst{18-16} = imm; 9346 } 9347 9348 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9349 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9350 [(set (v16i8 V128:$dst), 9351 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9352 (i32 vecshiftR8:$imm)))]> { 9353 bits<3> imm; 9354 let Inst{18-16} = imm; 9355 } 9356 9357 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9358 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9359 [(set (v4i16 V64:$dst), 9360 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9361 (i32 vecshiftR16:$imm)))]> { 9362 bits<4> imm; 9363 let Inst{19-16} = imm; 9364 } 9365 9366 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9367 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9368 [(set (v8i16 V128:$dst), 9369 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9370 (i32 vecshiftR16:$imm)))]> { 9371 bits<4> imm; 9372 let Inst{19-16} = imm; 9373 } 9374 9375 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9376 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9377 [(set (v2i32 V64:$dst), 9378 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9379 (i32 vecshiftR32:$imm)))]> { 9380 bits<5> imm; 9381 let Inst{20-16} = imm; 9382 } 9383 9384 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9385 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9386 [(set (v4i32 V128:$dst), 9387 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9388 (i32 vecshiftR32:$imm)))]> { 9389 bits<5> imm; 9390 let Inst{20-16} = imm; 9391 } 9392 9393 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9394 V128, V128, vecshiftR64, 9395 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9396 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9397 (i32 vecshiftR64:$imm)))]> { 9398 bits<6> imm; 9399 let Inst{21-16} = imm; 9400 } 9401} 9402 9403multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9404 SDPatternOperator OpNode = null_frag> { 9405 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9406 V64, V64, vecshiftL8, 9407 asm, ".8b", ".8b", 9408 [(set (v8i8 V64:$dst), 9409 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9410 (i32 vecshiftL8:$imm)))]> { 9411 bits<3> imm; 9412 let Inst{18-16} = imm; 9413 } 9414 9415 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9416 V128, V128, vecshiftL8, 9417 asm, ".16b", ".16b", 9418 [(set (v16i8 V128:$dst), 9419 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9420 (i32 vecshiftL8:$imm)))]> { 9421 bits<3> imm; 9422 let Inst{18-16} = imm; 9423 } 9424 9425 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9426 V64, V64, vecshiftL16, 9427 asm, ".4h", ".4h", 9428 [(set (v4i16 V64:$dst), 9429 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9430 (i32 vecshiftL16:$imm)))]> { 9431 bits<4> imm; 9432 let Inst{19-16} = imm; 9433 } 9434 9435 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9436 V128, V128, vecshiftL16, 9437 asm, ".8h", ".8h", 9438 [(set (v8i16 V128:$dst), 9439 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9440 (i32 vecshiftL16:$imm)))]> { 9441 bits<4> imm; 9442 let Inst{19-16} = imm; 9443 } 9444 9445 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9446 V64, V64, vecshiftL32, 9447 asm, ".2s", ".2s", 9448 [(set (v2i32 V64:$dst), 9449 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9450 (i32 vecshiftL32:$imm)))]> { 9451 bits<5> imm; 9452 let Inst{20-16} = imm; 9453 } 9454 9455 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9456 V128, V128, vecshiftL32, 9457 asm, ".4s", ".4s", 9458 [(set (v4i32 V128:$dst), 9459 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9460 (i32 vecshiftL32:$imm)))]> { 9461 bits<5> imm; 9462 let Inst{20-16} = imm; 9463 } 9464 9465 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9466 V128, V128, vecshiftL64, 9467 asm, ".2d", ".2d", 9468 [(set (v2i64 V128:$dst), 9469 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9470 (i32 vecshiftL64:$imm)))]> { 9471 bits<6> imm; 9472 let Inst{21-16} = imm; 9473 } 9474} 9475 9476multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9477 SDPatternOperator OpNode> { 9478 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9479 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9480 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9481 bits<3> imm; 9482 let Inst{18-16} = imm; 9483 } 9484 9485 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9486 V128, V128, vecshiftL8, 9487 asm#"2", ".8h", ".16b", 9488 [(set (v8i16 V128:$Rd), 9489 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9490 bits<3> imm; 9491 let Inst{18-16} = imm; 9492 } 9493 9494 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9495 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9496 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9497 bits<4> imm; 9498 let Inst{19-16} = imm; 9499 } 9500 9501 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9502 V128, V128, vecshiftL16, 9503 asm#"2", ".4s", ".8h", 9504 [(set (v4i32 V128:$Rd), 9505 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9506 9507 bits<4> imm; 9508 let Inst{19-16} = imm; 9509 } 9510 9511 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9512 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9513 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9514 bits<5> imm; 9515 let Inst{20-16} = imm; 9516 } 9517 9518 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9519 V128, V128, vecshiftL32, 9520 asm#"2", ".2d", ".4s", 9521 [(set (v2i64 V128:$Rd), 9522 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9523 bits<5> imm; 9524 let Inst{20-16} = imm; 9525 } 9526} 9527 9528 9529//--- 9530// Vector load/store 9531//--- 9532// SIMD ldX/stX no-index memory references don't allow the optional 9533// ", #0" constant and handle post-indexing explicitly, so we use 9534// a more specialized parse method for them. Otherwise, it's the same as 9535// the general GPR64sp handling. 9536 9537class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9538 string asm, dag oops, dag iops, list<dag> pattern> 9539 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9540 bits<5> Vt; 9541 bits<5> Rn; 9542 let Inst{31} = 0; 9543 let Inst{30} = Q; 9544 let Inst{29-23} = 0b0011000; 9545 let Inst{22} = L; 9546 let Inst{21-16} = 0b000000; 9547 let Inst{15-12} = opcode; 9548 let Inst{11-10} = size; 9549 let Inst{9-5} = Rn; 9550 let Inst{4-0} = Vt; 9551} 9552 9553class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9554 string asm, dag oops, dag iops> 9555 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9556 bits<5> Vt; 9557 bits<5> Rn; 9558 bits<5> Xm; 9559 let Inst{31} = 0; 9560 let Inst{30} = Q; 9561 let Inst{29-23} = 0b0011001; 9562 let Inst{22} = L; 9563 let Inst{21} = 0; 9564 let Inst{20-16} = Xm; 9565 let Inst{15-12} = opcode; 9566 let Inst{11-10} = size; 9567 let Inst{9-5} = Rn; 9568 let Inst{4-0} = Vt; 9569} 9570 9571// The immediate form of AdvSIMD post-indexed addressing is encoded with 9572// register post-index addressing from the zero register. 9573multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9574 int Offset, int Size> { 9575 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9576 // "ld1\t$Vt, [$Rn], #16" 9577 // may get mapped to 9578 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9579 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9580 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9581 GPR64sp:$Rn, 9582 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9583 XZR), 1>; 9584 9585 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9586 // "ld1.8b\t$Vt, [$Rn], #16" 9587 // may get mapped to 9588 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9589 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9590 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9591 GPR64sp:$Rn, 9592 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9593 XZR), 0>; 9594 9595 // E.g. "ld1.8b { v0, v1 }, [x1]" 9596 // "ld1\t$Vt, [$Rn]" 9597 // may get mapped to 9598 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9599 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9600 (!cast<Instruction>(BaseName # Count # "v" # layout) 9601 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9602 GPR64sp:$Rn), 0>; 9603 9604 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9605 // "ld1\t$Vt, [$Rn], $Xm" 9606 // may get mapped to 9607 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9608 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9609 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9610 GPR64sp:$Rn, 9611 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9612 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9613} 9614 9615multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9616 int Offset128, int Offset64, bits<4> opcode> { 9617 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9618 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9619 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9620 (ins GPR64sp:$Rn), []>; 9621 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9622 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9623 (ins GPR64sp:$Rn), []>; 9624 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9625 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9626 (ins GPR64sp:$Rn), []>; 9627 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9628 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9629 (ins GPR64sp:$Rn), []>; 9630 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9631 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9632 (ins GPR64sp:$Rn), []>; 9633 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9634 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9635 (ins GPR64sp:$Rn), []>; 9636 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9637 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9638 (ins GPR64sp:$Rn), []>; 9639 9640 9641 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9642 (outs GPR64sp:$wback, 9643 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9644 (ins GPR64sp:$Rn, 9645 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9646 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9647 (outs GPR64sp:$wback, 9648 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9649 (ins GPR64sp:$Rn, 9650 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9651 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9652 (outs GPR64sp:$wback, 9653 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9654 (ins GPR64sp:$Rn, 9655 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9656 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9657 (outs GPR64sp:$wback, 9658 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9659 (ins GPR64sp:$Rn, 9660 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9661 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9662 (outs GPR64sp:$wback, 9663 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9664 (ins GPR64sp:$Rn, 9665 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9666 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9667 (outs GPR64sp:$wback, 9668 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9669 (ins GPR64sp:$Rn, 9670 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9671 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9672 (outs GPR64sp:$wback, 9673 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9674 (ins GPR64sp:$Rn, 9675 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9676 } 9677 9678 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9679 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9680 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9681 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9682 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9683 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9684 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9685} 9686 9687// Only ld1/st1 has a v1d version. 9688multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9689 int Offset128, int Offset64, bits<4> opcode> { 9690 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9691 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9692 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9693 GPR64sp:$Rn), []>; 9694 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9695 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9696 GPR64sp:$Rn), []>; 9697 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9698 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9699 GPR64sp:$Rn), []>; 9700 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9701 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9702 GPR64sp:$Rn), []>; 9703 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9704 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9705 GPR64sp:$Rn), []>; 9706 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9707 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9708 GPR64sp:$Rn), []>; 9709 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9710 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9711 GPR64sp:$Rn), []>; 9712 9713 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9714 (outs GPR64sp:$wback), 9715 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9716 GPR64sp:$Rn, 9717 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9718 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9719 (outs GPR64sp:$wback), 9720 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9721 GPR64sp:$Rn, 9722 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9723 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9724 (outs GPR64sp:$wback), 9725 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9726 GPR64sp:$Rn, 9727 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9728 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9729 (outs GPR64sp:$wback), 9730 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9731 GPR64sp:$Rn, 9732 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9733 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9734 (outs GPR64sp:$wback), 9735 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9736 GPR64sp:$Rn, 9737 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9738 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9739 (outs GPR64sp:$wback), 9740 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9741 GPR64sp:$Rn, 9742 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9743 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9744 (outs GPR64sp:$wback), 9745 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9746 GPR64sp:$Rn, 9747 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9748 } 9749 9750 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9751 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9752 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9753 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9754 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9755 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9756 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9757} 9758 9759multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9760 int Offset128, int Offset64, bits<4> opcode> 9761 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9762 9763 // LD1 instructions have extra "1d" variants. 9764 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9765 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9766 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9767 (ins GPR64sp:$Rn), []>; 9768 9769 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9770 (outs GPR64sp:$wback, 9771 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9772 (ins GPR64sp:$Rn, 9773 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9774 } 9775 9776 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9777} 9778 9779multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9780 int Offset128, int Offset64, bits<4> opcode> 9781 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9782 9783 // ST1 instructions have extra "1d" variants. 9784 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9785 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9786 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9787 GPR64sp:$Rn), []>; 9788 9789 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9790 (outs GPR64sp:$wback), 9791 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9792 GPR64sp:$Rn, 9793 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9794 } 9795 9796 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9797} 9798 9799multiclass SIMDLd1Multiple<string asm> { 9800 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9801 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9802 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9803 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9804} 9805 9806multiclass SIMDSt1Multiple<string asm> { 9807 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9808 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9809 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9810 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9811} 9812 9813multiclass SIMDLd2Multiple<string asm> { 9814 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9815} 9816 9817multiclass SIMDSt2Multiple<string asm> { 9818 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9819} 9820 9821multiclass SIMDLd3Multiple<string asm> { 9822 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9823} 9824 9825multiclass SIMDSt3Multiple<string asm> { 9826 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9827} 9828 9829multiclass SIMDLd4Multiple<string asm> { 9830 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9831} 9832 9833multiclass SIMDSt4Multiple<string asm> { 9834 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9835} 9836 9837//--- 9838// AdvSIMD Load/store single-element 9839//--- 9840 9841class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9842 string asm, string operands, string cst, 9843 dag oops, dag iops, list<dag> pattern> 9844 : I<oops, iops, asm, operands, cst, pattern> { 9845 bits<5> Vt; 9846 bits<5> Rn; 9847 let Inst{31} = 0; 9848 let Inst{29-24} = 0b001101; 9849 let Inst{22} = L; 9850 let Inst{21} = R; 9851 let Inst{15-13} = opcode; 9852 let Inst{9-5} = Rn; 9853 let Inst{4-0} = Vt; 9854} 9855 9856class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9857 string asm, string operands, string cst, 9858 dag oops, dag iops, list<dag> pattern> 9859 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9860 bits<5> Vt; 9861 bits<5> Rn; 9862 let Inst{31} = 0; 9863 let Inst{29-24} = 0b001101; 9864 let Inst{22} = L; 9865 let Inst{21} = R; 9866 let Inst{15-13} = opcode; 9867 let Inst{9-5} = Rn; 9868 let Inst{4-0} = Vt; 9869} 9870 9871 9872let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9873class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9874 DAGOperand listtype> 9875 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9876 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9877 []> { 9878 let Inst{30} = Q; 9879 let Inst{23} = 0; 9880 let Inst{20-16} = 0b00000; 9881 let Inst{12} = S; 9882 let Inst{11-10} = size; 9883} 9884let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9885class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9886 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9887 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9888 "$Rn = $wback", 9889 (outs GPR64sp:$wback, listtype:$Vt), 9890 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9891 bits<5> Xm; 9892 let Inst{30} = Q; 9893 let Inst{23} = 1; 9894 let Inst{20-16} = Xm; 9895 let Inst{12} = S; 9896 let Inst{11-10} = size; 9897} 9898 9899multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9900 int Offset, int Size> { 9901 // E.g. "ld1r { v0.8b }, [x1], #1" 9902 // "ld1r.8b\t$Vt, [$Rn], #1" 9903 // may get mapped to 9904 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9905 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9906 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9907 GPR64sp:$Rn, 9908 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9909 XZR), 1>; 9910 9911 // E.g. "ld1r.8b { v0 }, [x1], #1" 9912 // "ld1r.8b\t$Vt, [$Rn], #1" 9913 // may get mapped to 9914 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9915 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9916 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9917 GPR64sp:$Rn, 9918 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9919 XZR), 0>; 9920 9921 // E.g. "ld1r.8b { v0 }, [x1]" 9922 // "ld1r.8b\t$Vt, [$Rn]" 9923 // may get mapped to 9924 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9925 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9926 (!cast<Instruction>(BaseName # "v" # layout) 9927 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9928 GPR64sp:$Rn), 0>; 9929 9930 // E.g. "ld1r.8b { v0 }, [x1], x2" 9931 // "ld1r.8b\t$Vt, [$Rn], $Xm" 9932 // may get mapped to 9933 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9934 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9935 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9936 GPR64sp:$Rn, 9937 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9938 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9939} 9940 9941multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 9942 int Offset1, int Offset2, int Offset4, int Offset8> { 9943 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 9944 !cast<DAGOperand>("VecList" # Count # "8b")>; 9945 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 9946 !cast<DAGOperand>("VecList" # Count #"16b")>; 9947 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 9948 !cast<DAGOperand>("VecList" # Count #"4h")>; 9949 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 9950 !cast<DAGOperand>("VecList" # Count #"8h")>; 9951 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 9952 !cast<DAGOperand>("VecList" # Count #"2s")>; 9953 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 9954 !cast<DAGOperand>("VecList" # Count #"4s")>; 9955 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 9956 !cast<DAGOperand>("VecList" # Count #"1d")>; 9957 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 9958 !cast<DAGOperand>("VecList" # Count #"2d")>; 9959 9960 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 9961 !cast<DAGOperand>("VecList" # Count # "8b"), 9962 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9963 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 9964 !cast<DAGOperand>("VecList" # Count # "16b"), 9965 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9966 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 9967 !cast<DAGOperand>("VecList" # Count # "4h"), 9968 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9969 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 9970 !cast<DAGOperand>("VecList" # Count # "8h"), 9971 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9972 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 9973 !cast<DAGOperand>("VecList" # Count # "2s"), 9974 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9975 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 9976 !cast<DAGOperand>("VecList" # Count # "4s"), 9977 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9978 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 9979 !cast<DAGOperand>("VecList" # Count # "1d"), 9980 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9981 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 9982 !cast<DAGOperand>("VecList" # Count # "2d"), 9983 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9984 9985 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 9986 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 9987 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 9988 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 9989 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 9990 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 9991 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 9992 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 9993} 9994 9995class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 9996 dag oops, dag iops, list<dag> pattern> 9997 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9998 pattern> { 9999 // idx encoded in Q:S:size fields. 10000 bits<4> idx; 10001 let Inst{30} = idx{3}; 10002 let Inst{23} = 0; 10003 let Inst{20-16} = 0b00000; 10004 let Inst{12} = idx{2}; 10005 let Inst{11-10} = idx{1-0}; 10006} 10007class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10008 dag oops, dag iops, list<dag> pattern> 10009 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10010 oops, iops, pattern> { 10011 // idx encoded in Q:S:size fields. 10012 bits<4> idx; 10013 let Inst{30} = idx{3}; 10014 let Inst{23} = 0; 10015 let Inst{20-16} = 0b00000; 10016 let Inst{12} = idx{2}; 10017 let Inst{11-10} = idx{1-0}; 10018} 10019class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10020 dag oops, dag iops> 10021 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10022 "$Rn = $wback", oops, iops, []> { 10023 // idx encoded in Q:S:size fields. 10024 bits<4> idx; 10025 bits<5> Xm; 10026 let Inst{30} = idx{3}; 10027 let Inst{23} = 1; 10028 let Inst{20-16} = Xm; 10029 let Inst{12} = idx{2}; 10030 let Inst{11-10} = idx{1-0}; 10031} 10032class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10033 dag oops, dag iops> 10034 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10035 "$Rn = $wback", oops, iops, []> { 10036 // idx encoded in Q:S:size fields. 10037 bits<4> idx; 10038 bits<5> Xm; 10039 let Inst{30} = idx{3}; 10040 let Inst{23} = 1; 10041 let Inst{20-16} = Xm; 10042 let Inst{12} = idx{2}; 10043 let Inst{11-10} = idx{1-0}; 10044} 10045 10046class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10047 dag oops, dag iops, list<dag> pattern> 10048 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10049 pattern> { 10050 // idx encoded in Q:S:size<1> fields. 10051 bits<3> idx; 10052 let Inst{30} = idx{2}; 10053 let Inst{23} = 0; 10054 let Inst{20-16} = 0b00000; 10055 let Inst{12} = idx{1}; 10056 let Inst{11} = idx{0}; 10057 let Inst{10} = size; 10058} 10059class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10060 dag oops, dag iops, list<dag> pattern> 10061 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10062 oops, iops, pattern> { 10063 // idx encoded in Q:S:size<1> fields. 10064 bits<3> idx; 10065 let Inst{30} = idx{2}; 10066 let Inst{23} = 0; 10067 let Inst{20-16} = 0b00000; 10068 let Inst{12} = idx{1}; 10069 let Inst{11} = idx{0}; 10070 let Inst{10} = size; 10071} 10072 10073class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10074 dag oops, dag iops> 10075 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10076 "$Rn = $wback", oops, iops, []> { 10077 // idx encoded in Q:S:size<1> fields. 10078 bits<3> idx; 10079 bits<5> Xm; 10080 let Inst{30} = idx{2}; 10081 let Inst{23} = 1; 10082 let Inst{20-16} = Xm; 10083 let Inst{12} = idx{1}; 10084 let Inst{11} = idx{0}; 10085 let Inst{10} = size; 10086} 10087class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10088 dag oops, dag iops> 10089 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10090 "$Rn = $wback", oops, iops, []> { 10091 // idx encoded in Q:S:size<1> fields. 10092 bits<3> idx; 10093 bits<5> Xm; 10094 let Inst{30} = idx{2}; 10095 let Inst{23} = 1; 10096 let Inst{20-16} = Xm; 10097 let Inst{12} = idx{1}; 10098 let Inst{11} = idx{0}; 10099 let Inst{10} = size; 10100} 10101class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10102 dag oops, dag iops, list<dag> pattern> 10103 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10104 pattern> { 10105 // idx encoded in Q:S fields. 10106 bits<2> idx; 10107 let Inst{30} = idx{1}; 10108 let Inst{23} = 0; 10109 let Inst{20-16} = 0b00000; 10110 let Inst{12} = idx{0}; 10111 let Inst{11-10} = size; 10112} 10113class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10114 dag oops, dag iops, list<dag> pattern> 10115 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10116 oops, iops, pattern> { 10117 // idx encoded in Q:S fields. 10118 bits<2> idx; 10119 let Inst{30} = idx{1}; 10120 let Inst{23} = 0; 10121 let Inst{20-16} = 0b00000; 10122 let Inst{12} = idx{0}; 10123 let Inst{11-10} = size; 10124} 10125class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10126 string asm, dag oops, dag iops> 10127 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10128 "$Rn = $wback", oops, iops, []> { 10129 // idx encoded in Q:S fields. 10130 bits<2> idx; 10131 bits<5> Xm; 10132 let Inst{30} = idx{1}; 10133 let Inst{23} = 1; 10134 let Inst{20-16} = Xm; 10135 let Inst{12} = idx{0}; 10136 let Inst{11-10} = size; 10137} 10138class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10139 string asm, dag oops, dag iops> 10140 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10141 "$Rn = $wback", oops, iops, []> { 10142 // idx encoded in Q:S fields. 10143 bits<2> idx; 10144 bits<5> Xm; 10145 let Inst{30} = idx{1}; 10146 let Inst{23} = 1; 10147 let Inst{20-16} = Xm; 10148 let Inst{12} = idx{0}; 10149 let Inst{11-10} = size; 10150} 10151class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10152 dag oops, dag iops, list<dag> pattern> 10153 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10154 pattern> { 10155 // idx encoded in Q field. 10156 bits<1> idx; 10157 let Inst{30} = idx; 10158 let Inst{23} = 0; 10159 let Inst{20-16} = 0b00000; 10160 let Inst{12} = 0; 10161 let Inst{11-10} = size; 10162} 10163class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10164 dag oops, dag iops, list<dag> pattern> 10165 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10166 oops, iops, pattern> { 10167 // idx encoded in Q field. 10168 bits<1> idx; 10169 let Inst{30} = idx; 10170 let Inst{23} = 0; 10171 let Inst{20-16} = 0b00000; 10172 let Inst{12} = 0; 10173 let Inst{11-10} = size; 10174} 10175class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10176 string asm, dag oops, dag iops> 10177 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10178 "$Rn = $wback", oops, iops, []> { 10179 // idx encoded in Q field. 10180 bits<1> idx; 10181 bits<5> Xm; 10182 let Inst{30} = idx; 10183 let Inst{23} = 1; 10184 let Inst{20-16} = Xm; 10185 let Inst{12} = 0; 10186 let Inst{11-10} = size; 10187} 10188class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10189 string asm, dag oops, dag iops> 10190 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10191 "$Rn = $wback", oops, iops, []> { 10192 // idx encoded in Q field. 10193 bits<1> idx; 10194 bits<5> Xm; 10195 let Inst{30} = idx; 10196 let Inst{23} = 1; 10197 let Inst{20-16} = Xm; 10198 let Inst{12} = 0; 10199 let Inst{11-10} = size; 10200} 10201 10202let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10203multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10204 RegisterOperand listtype, 10205 RegisterOperand GPR64pi> { 10206 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10207 (outs listtype:$dst), 10208 (ins listtype:$Vt, VectorIndexB:$idx, 10209 GPR64sp:$Rn), []>; 10210 10211 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10212 (outs GPR64sp:$wback, listtype:$dst), 10213 (ins listtype:$Vt, VectorIndexB:$idx, 10214 GPR64sp:$Rn, GPR64pi:$Xm)>; 10215} 10216let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10217multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10218 RegisterOperand listtype, 10219 RegisterOperand GPR64pi> { 10220 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10221 (outs listtype:$dst), 10222 (ins listtype:$Vt, VectorIndexH:$idx, 10223 GPR64sp:$Rn), []>; 10224 10225 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10226 (outs GPR64sp:$wback, listtype:$dst), 10227 (ins listtype:$Vt, VectorIndexH:$idx, 10228 GPR64sp:$Rn, GPR64pi:$Xm)>; 10229} 10230let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10231multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10232 RegisterOperand listtype, 10233 RegisterOperand GPR64pi> { 10234 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10235 (outs listtype:$dst), 10236 (ins listtype:$Vt, VectorIndexS:$idx, 10237 GPR64sp:$Rn), []>; 10238 10239 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10240 (outs GPR64sp:$wback, listtype:$dst), 10241 (ins listtype:$Vt, VectorIndexS:$idx, 10242 GPR64sp:$Rn, GPR64pi:$Xm)>; 10243} 10244let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10245multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10246 RegisterOperand listtype, RegisterOperand GPR64pi> { 10247 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10248 (outs listtype:$dst), 10249 (ins listtype:$Vt, VectorIndexD:$idx, 10250 GPR64sp:$Rn), []>; 10251 10252 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10253 (outs GPR64sp:$wback, listtype:$dst), 10254 (ins listtype:$Vt, VectorIndexD:$idx, 10255 GPR64sp:$Rn, GPR64pi:$Xm)>; 10256} 10257let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10258multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10259 RegisterOperand listtype, RegisterOperand GPR64pi> { 10260 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10261 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10262 GPR64sp:$Rn), []>; 10263 10264 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10265 (outs GPR64sp:$wback), 10266 (ins listtype:$Vt, VectorIndexB:$idx, 10267 GPR64sp:$Rn, GPR64pi:$Xm)>; 10268} 10269let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10270multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10271 RegisterOperand listtype, RegisterOperand GPR64pi> { 10272 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10273 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10274 GPR64sp:$Rn), []>; 10275 10276 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10277 (outs GPR64sp:$wback), 10278 (ins listtype:$Vt, VectorIndexH:$idx, 10279 GPR64sp:$Rn, GPR64pi:$Xm)>; 10280} 10281let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10282multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10283 RegisterOperand listtype, RegisterOperand GPR64pi> { 10284 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10285 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10286 GPR64sp:$Rn), []>; 10287 10288 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10289 (outs GPR64sp:$wback), 10290 (ins listtype:$Vt, VectorIndexS:$idx, 10291 GPR64sp:$Rn, GPR64pi:$Xm)>; 10292} 10293let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10294multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10295 RegisterOperand listtype, RegisterOperand GPR64pi> { 10296 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10297 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10298 GPR64sp:$Rn), []>; 10299 10300 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10301 (outs GPR64sp:$wback), 10302 (ins listtype:$Vt, VectorIndexD:$idx, 10303 GPR64sp:$Rn, GPR64pi:$Xm)>; 10304} 10305 10306multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10307 string Count, int Offset, Operand idxtype> { 10308 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10309 // "ld1\t$Vt, [$Rn], #1" 10310 // may get mapped to 10311 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10312 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10313 (!cast<Instruction>(NAME # Type # "_POST") 10314 GPR64sp:$Rn, 10315 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10316 idxtype:$idx, XZR), 1>; 10317 10318 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10319 // "ld1.8b\t$Vt, [$Rn], #1" 10320 // may get mapped to 10321 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10322 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10323 (!cast<Instruction>(NAME # Type # "_POST") 10324 GPR64sp:$Rn, 10325 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10326 idxtype:$idx, XZR), 0>; 10327 10328 // E.g. "ld1.8b { v0 }[0], [x1]" 10329 // "ld1.8b\t$Vt, [$Rn]" 10330 // may get mapped to 10331 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10332 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10333 (!cast<Instruction>(NAME # Type) 10334 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10335 idxtype:$idx, GPR64sp:$Rn), 0>; 10336 10337 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10338 // "ld1.8b\t$Vt, [$Rn], $Xm" 10339 // may get mapped to 10340 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10341 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10342 (!cast<Instruction>(NAME # Type # "_POST") 10343 GPR64sp:$Rn, 10344 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10345 idxtype:$idx, 10346 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10347} 10348 10349multiclass SIMDLdSt1SingleAliases<string asm> { 10350 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10351 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10352 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10353 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10354} 10355 10356multiclass SIMDLdSt2SingleAliases<string asm> { 10357 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10358 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10359 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10360 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10361} 10362 10363multiclass SIMDLdSt3SingleAliases<string asm> { 10364 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10365 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10366 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10367 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10368} 10369 10370multiclass SIMDLdSt4SingleAliases<string asm> { 10371 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10372 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10373 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10374 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10375} 10376} // end of 'let Predicates = [HasNEON]' 10377 10378//---------------------------------------------------------------------------- 10379// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10380//---------------------------------------------------------------------------- 10381 10382let Predicates = [HasNEON, HasRDM] in { 10383 10384class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10385 RegisterOperand regtype, string asm, 10386 string kind, list<dag> pattern> 10387 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10388 pattern> { 10389} 10390multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10391 SDPatternOperator Accum> { 10392 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10393 [(set (v4i16 V64:$dst), 10394 (Accum (v4i16 V64:$Rd), 10395 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 10396 (v4i16 V64:$Rm)))))]>; 10397 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10398 [(set (v8i16 V128:$dst), 10399 (Accum (v8i16 V128:$Rd), 10400 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 10401 (v8i16 V128:$Rm)))))]>; 10402 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10403 [(set (v2i32 V64:$dst), 10404 (Accum (v2i32 V64:$Rd), 10405 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 10406 (v2i32 V64:$Rm)))))]>; 10407 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10408 [(set (v4i32 V128:$dst), 10409 (Accum (v4i32 V128:$Rd), 10410 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 10411 (v4i32 V128:$Rm)))))]>; 10412} 10413 10414multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10415 SDPatternOperator Accum> { 10416 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10417 V64, V64, V128_lo, VectorIndexH, 10418 asm, ".4h", ".4h", ".4h", ".h", 10419 [(set (v4i16 V64:$dst), 10420 (Accum (v4i16 V64:$Rd), 10421 (v4i16 (int_aarch64_neon_sqrdmulh 10422 (v4i16 V64:$Rn), 10423 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10424 VectorIndexH:$idx))))))]> { 10425 bits<3> idx; 10426 let Inst{11} = idx{2}; 10427 let Inst{21} = idx{1}; 10428 let Inst{20} = idx{0}; 10429 } 10430 10431 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10432 V128, V128, V128_lo, VectorIndexH, 10433 asm, ".8h", ".8h", ".8h", ".h", 10434 [(set (v8i16 V128:$dst), 10435 (Accum (v8i16 V128:$Rd), 10436 (v8i16 (int_aarch64_neon_sqrdmulh 10437 (v8i16 V128:$Rn), 10438 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10439 VectorIndexH:$idx))))))]> { 10440 bits<3> idx; 10441 let Inst{11} = idx{2}; 10442 let Inst{21} = idx{1}; 10443 let Inst{20} = idx{0}; 10444 } 10445 10446 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10447 V64, V64, V128, VectorIndexS, 10448 asm, ".2s", ".2s", ".2s", ".s", 10449 [(set (v2i32 V64:$dst), 10450 (Accum (v2i32 V64:$Rd), 10451 (v2i32 (int_aarch64_neon_sqrdmulh 10452 (v2i32 V64:$Rn), 10453 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10454 VectorIndexS:$idx))))))]> { 10455 bits<2> idx; 10456 let Inst{11} = idx{1}; 10457 let Inst{21} = idx{0}; 10458 } 10459 10460 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10461 // an intermediate EXTRACT_SUBREG would be untyped. 10462 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 10463 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 10464 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10465 (i32 (vector_extract 10466 (v4i32 (insert_subvector 10467 (undef), 10468 (v2i32 (int_aarch64_neon_sqrdmulh 10469 (v2i32 V64:$Rn), 10470 (v2i32 (AArch64duplane32 10471 (v4i32 V128:$Rm), 10472 VectorIndexS:$idx)))), 10473 (i32 0))), 10474 (i64 0))))), 10475 (EXTRACT_SUBREG 10476 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 10477 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 10478 FPR32Op:$Rd, 10479 ssub)), 10480 V64:$Rn, 10481 V128:$Rm, 10482 VectorIndexS:$idx)), 10483 ssub)>; 10484 10485 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10486 V128, V128, V128, VectorIndexS, 10487 asm, ".4s", ".4s", ".4s", ".s", 10488 [(set (v4i32 V128:$dst), 10489 (Accum (v4i32 V128:$Rd), 10490 (v4i32 (int_aarch64_neon_sqrdmulh 10491 (v4i32 V128:$Rn), 10492 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10493 VectorIndexS:$idx))))))]> { 10494 bits<2> idx; 10495 let Inst{11} = idx{1}; 10496 let Inst{21} = idx{0}; 10497 } 10498 10499 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10500 // an intermediate EXTRACT_SUBREG would be untyped. 10501 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10502 (i32 (vector_extract 10503 (v4i32 (int_aarch64_neon_sqrdmulh 10504 (v4i32 V128:$Rn), 10505 (v4i32 (AArch64duplane32 10506 (v4i32 V128:$Rm), 10507 VectorIndexS:$idx)))), 10508 (i64 0))))), 10509 (EXTRACT_SUBREG 10510 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 10511 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 10512 FPR32Op:$Rd, 10513 ssub)), 10514 V128:$Rn, 10515 V128:$Rm, 10516 VectorIndexS:$idx)), 10517 ssub)>; 10518 10519 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10520 FPR16Op, FPR16Op, V128_lo, 10521 VectorIndexH, asm, ".h", "", "", ".h", 10522 []> { 10523 bits<3> idx; 10524 let Inst{11} = idx{2}; 10525 let Inst{21} = idx{1}; 10526 let Inst{20} = idx{0}; 10527 } 10528 10529 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10530 FPR32Op, FPR32Op, V128, VectorIndexS, 10531 asm, ".s", "", "", ".s", 10532 [(set (i32 FPR32Op:$dst), 10533 (Accum (i32 FPR32Op:$Rd), 10534 (i32 (int_aarch64_neon_sqrdmulh 10535 (i32 FPR32Op:$Rn), 10536 (i32 (vector_extract (v4i32 V128:$Rm), 10537 VectorIndexS:$idx))))))]> { 10538 bits<2> idx; 10539 let Inst{11} = idx{1}; 10540 let Inst{21} = idx{0}; 10541 } 10542} 10543} // let Predicates = [HasNeon, HasRDM] 10544 10545//---------------------------------------------------------------------------- 10546// ARMv8.3 Complex ADD/MLA instructions 10547//---------------------------------------------------------------------------- 10548 10549class ComplexRotationOperand<int Angle, int Remainder, string Type> 10550 : AsmOperandClass { 10551 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10552 let DiagnosticType = "InvalidComplexRotation" # Type; 10553 let Name = "ComplexRotation" # Type; 10554} 10555def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10556 SDNodeXForm<imm, [{ 10557 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10558}]>> { 10559 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10560 let PrintMethod = "printComplexRotationOp<90, 0>"; 10561} 10562def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10563 SDNodeXForm<imm, [{ 10564 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10565}]>> { 10566 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10567 let PrintMethod = "printComplexRotationOp<180, 90>"; 10568} 10569let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10570class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10571 RegisterOperand regtype, Operand rottype, 10572 string asm, string kind, list<dag> pattern> 10573 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10574 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10575 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10576 Sched<[WriteV]> { 10577 bits<5> Rd; 10578 bits<5> Rn; 10579 bits<5> Rm; 10580 bits<1> rot; 10581 let Inst{31} = 0; 10582 let Inst{30} = Q; 10583 let Inst{29} = U; 10584 let Inst{28-24} = 0b01110; 10585 let Inst{23-22} = size; 10586 let Inst{21} = 0; 10587 let Inst{20-16} = Rm; 10588 let Inst{15-13} = opcode; 10589 // Non-tied version (FCADD) only has one rotation bit 10590 let Inst{12} = rot; 10591 let Inst{11} = 0; 10592 let Inst{10} = 1; 10593 let Inst{9-5} = Rn; 10594 let Inst{4-0} = Rd; 10595} 10596 10597//8.3 CompNum - Floating-point complex number support 10598multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10599 string asm, SDPatternOperator OpNode>{ 10600 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10601 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10602 asm, ".4h", 10603 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10604 (v4f16 V64:$Rn), 10605 (v4f16 V64:$Rm), 10606 (i32 rottype:$rot)))]>; 10607 10608 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10609 asm, ".8h", 10610 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10611 (v8f16 V128:$Rn), 10612 (v8f16 V128:$Rm), 10613 (i32 rottype:$rot)))]>; 10614 } 10615 10616 let Predicates = [HasComplxNum, HasNEON] in { 10617 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10618 asm, ".2s", 10619 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10620 (v2f32 V64:$Rn), 10621 (v2f32 V64:$Rm), 10622 (i32 rottype:$rot)))]>; 10623 10624 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10625 asm, ".4s", 10626 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10627 (v4f32 V128:$Rn), 10628 (v4f32 V128:$Rm), 10629 (i32 rottype:$rot)))]>; 10630 10631 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10632 asm, ".2d", 10633 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10634 (v2f64 V128:$Rn), 10635 (v2f64 V128:$Rm), 10636 (i32 rottype:$rot)))]>; 10637 } 10638} 10639 10640let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10641class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10642 bits<3> opcode, 10643 RegisterOperand regtype, 10644 Operand rottype, string asm, 10645 string kind, list<dag> pattern> 10646 : I<(outs regtype:$dst), 10647 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10648 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10649 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10650 Sched<[WriteV]> { 10651 bits<5> Rd; 10652 bits<5> Rn; 10653 bits<5> Rm; 10654 bits<2> rot; 10655 let Inst{31} = 0; 10656 let Inst{30} = Q; 10657 let Inst{29} = U; 10658 let Inst{28-24} = 0b01110; 10659 let Inst{23-22} = size; 10660 let Inst{21} = 0; 10661 let Inst{20-16} = Rm; 10662 let Inst{15-13} = opcode; 10663 let Inst{12-11} = rot; 10664 let Inst{10} = 1; 10665 let Inst{9-5} = Rn; 10666 let Inst{4-0} = Rd; 10667} 10668 10669multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10670 Operand rottype, string asm, 10671 SDPatternOperator OpNode> { 10672 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10673 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10674 rottype, asm, ".4h", 10675 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10676 (v4f16 V64:$Rn), 10677 (v4f16 V64:$Rm), 10678 (i32 rottype:$rot)))]>; 10679 10680 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10681 rottype, asm, ".8h", 10682 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10683 (v8f16 V128:$Rn), 10684 (v8f16 V128:$Rm), 10685 (i32 rottype:$rot)))]>; 10686 } 10687 10688 let Predicates = [HasComplxNum, HasNEON] in { 10689 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10690 rottype, asm, ".2s", 10691 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10692 (v2f32 V64:$Rn), 10693 (v2f32 V64:$Rm), 10694 (i32 rottype:$rot)))]>; 10695 10696 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10697 rottype, asm, ".4s", 10698 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10699 (v4f32 V128:$Rn), 10700 (v4f32 V128:$Rm), 10701 (i32 rottype:$rot)))]>; 10702 10703 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10704 rottype, asm, ".2d", 10705 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10706 (v2f64 V128:$Rn), 10707 (v2f64 V128:$Rm), 10708 (i32 rottype:$rot)))]>; 10709 } 10710} 10711 10712let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10713class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10714 bit opc1, bit opc2, RegisterOperand dst_reg, 10715 RegisterOperand lhs_reg, 10716 RegisterOperand rhs_reg, Operand vec_idx, 10717 Operand rottype, string asm, string apple_kind, 10718 string dst_kind, string lhs_kind, 10719 string rhs_kind, list<dag> pattern> 10720 : I<(outs dst_reg:$dst), 10721 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10722 asm, 10723 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10724 "$idx, $rot" # "|" # apple_kind # 10725 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10726 Sched<[WriteV]> { 10727 bits<5> Rd; 10728 bits<5> Rn; 10729 bits<5> Rm; 10730 bits<2> rot; 10731 10732 let Inst{31} = 0; 10733 let Inst{30} = Q; 10734 let Inst{29} = U; 10735 let Inst{28} = Scalar; 10736 let Inst{27-24} = 0b1111; 10737 let Inst{23-22} = size; 10738 // Bit 21 must be set by the derived class. 10739 let Inst{20-16} = Rm; 10740 let Inst{15} = opc1; 10741 let Inst{14-13} = rot; 10742 let Inst{12} = opc2; 10743 // Bit 11 must be set by the derived class. 10744 let Inst{10} = 0; 10745 let Inst{9-5} = Rn; 10746 let Inst{4-0} = Rd; 10747} 10748 10749// The complex instructions index by pairs of elements, so the VectorIndexes 10750// don't match the lane types, and the index bits are different to the other 10751// classes. 10752multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10753 string asm, SDPatternOperator OpNode> { 10754 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10755 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10756 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10757 ".4h", ".h", []> { 10758 bits<1> idx; 10759 let Inst{11} = 0; 10760 let Inst{21} = idx{0}; 10761 } 10762 10763 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10764 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10765 ".8h", ".8h", ".h", []> { 10766 bits<2> idx; 10767 let Inst{11} = idx{1}; 10768 let Inst{21} = idx{0}; 10769 } 10770 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10771 10772 let Predicates = [HasComplxNum, HasNEON] in { 10773 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10774 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10775 ".4s", ".4s", ".s", []> { 10776 bits<1> idx; 10777 let Inst{11} = idx{0}; 10778 let Inst{21} = 0; 10779 } 10780 } // Predicates = [HasComplxNum, HasNEON] 10781} 10782 10783//---------------------------------------------------------------------------- 10784// Crypto extensions 10785//---------------------------------------------------------------------------- 10786 10787let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10788class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10789 list<dag> pat> 10790 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10791 Sched<[WriteV]>{ 10792 bits<5> Rd; 10793 bits<5> Rn; 10794 let Inst{31-16} = 0b0100111000101000; 10795 let Inst{15-12} = opc; 10796 let Inst{11-10} = 0b10; 10797 let Inst{9-5} = Rn; 10798 let Inst{4-0} = Rd; 10799} 10800 10801class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10802 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10803 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10804 10805class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10806 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10807 "$Rd = $dst", 10808 [(set (v16i8 V128:$dst), 10809 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10810 10811let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10812class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10813 dag oops, dag iops, list<dag> pat> 10814 : I<oops, iops, asm, 10815 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10816 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10817 Sched<[WriteV]>{ 10818 bits<5> Rd; 10819 bits<5> Rn; 10820 bits<5> Rm; 10821 let Inst{31-21} = 0b01011110000; 10822 let Inst{20-16} = Rm; 10823 let Inst{15} = 0; 10824 let Inst{14-12} = opc; 10825 let Inst{11-10} = 0b00; 10826 let Inst{9-5} = Rn; 10827 let Inst{4-0} = Rd; 10828} 10829 10830class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10831 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10832 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10833 [(set (v4i32 FPR128:$dst), 10834 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10835 (v4i32 V128:$Rm)))]>; 10836 10837class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10838 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10839 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10840 [(set (v4i32 V128:$dst), 10841 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10842 (v4i32 V128:$Rm)))]>; 10843 10844class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10845 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10846 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10847 [(set (v4i32 FPR128:$dst), 10848 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10849 (v4i32 V128:$Rm)))]>; 10850 10851let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10852class SHA2OpInst<bits<4> opc, string asm, string kind, 10853 string cstr, dag oops, dag iops, 10854 list<dag> pat> 10855 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10856 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10857 Sched<[WriteV]>{ 10858 bits<5> Rd; 10859 bits<5> Rn; 10860 let Inst{31-16} = 0b0101111000101000; 10861 let Inst{15-12} = opc; 10862 let Inst{11-10} = 0b10; 10863 let Inst{9-5} = Rn; 10864 let Inst{4-0} = Rd; 10865} 10866 10867class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10868 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10869 (ins V128:$Rd, V128:$Rn), 10870 [(set (v4i32 V128:$dst), 10871 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10872 10873class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10874 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10875 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10876 10877// Armv8.2-A Crypto extensions 10878class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10879 list<dag> pattern> 10880 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10881 bits<5> Vd; 10882 bits<5> Vn; 10883 let Inst{31-25} = 0b1100111; 10884 let Inst{9-5} = Vn; 10885 let Inst{4-0} = Vd; 10886} 10887 10888class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10889 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops, 10890 "$Vm = $Vd", []> { 10891 let Inst{31-25} = 0b1100111; 10892 let Inst{24-21} = 0b0110; 10893 let Inst{20-15} = 0b000001; 10894 let Inst{14} = op0; 10895 let Inst{13-12} = 0b00; 10896 let Inst{11-10} = op1; 10897} 10898class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10899 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 10900class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10901 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 10902 10903class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10904 string asmops, string cst> 10905 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10906 bits<5> Vm; 10907 let Inst{24-21} = 0b0011; 10908 let Inst{20-16} = Vm; 10909 let Inst{15} = 0b1; 10910 let Inst{14} = op0; 10911 let Inst{13-12} = 0b00; 10912 let Inst{11-10} = op1; 10913} 10914class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10915 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10916 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 10917class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10918 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10919 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10920class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10921 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10922 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 10923class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10924 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10925 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10926class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 10927 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 10928 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10929 10930class CryptoRRRR<bits<2>op0, string asm, string asmops> 10931 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 10932 asmops, "", []> { 10933 bits<5> Vm; 10934 bits<5> Va; 10935 let Inst{24-23} = 0b00; 10936 let Inst{22-21} = op0; 10937 let Inst{20-16} = Vm; 10938 let Inst{15} = 0b0; 10939 let Inst{14-10} = Va; 10940} 10941class CryptoRRRR_16B<bits<2>op0, string asm> 10942 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 10943 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 10944} 10945class CryptoRRRR_4S<bits<2>op0, string asm> 10946 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 10947 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 10948} 10949 10950class CryptoRRRi6<string asm> 10951 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 10952 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 10953 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 10954 bits<6> imm; 10955 bits<5> Vm; 10956 let Inst{24-21} = 0b0100; 10957 let Inst{20-16} = Vm; 10958 let Inst{15-10} = imm; 10959 let Inst{9-5} = Vn; 10960 let Inst{4-0} = Vd; 10961} 10962 10963class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 10964 : BaseCryptoV82<(outs V128:$Vdst), 10965 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 10966 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 10967 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 10968 bits<2> imm; 10969 bits<5> Vm; 10970 let Inst{24-21} = 0b0010; 10971 let Inst{20-16} = Vm; 10972 let Inst{15} = 0b1; 10973 let Inst{14} = op0; 10974 let Inst{13-12} = imm; 10975 let Inst{11-10} = op1; 10976} 10977 10978//---------------------------------------------------------------------------- 10979// v8.1 atomic instructions extension: 10980// * CAS 10981// * CASP 10982// * SWP 10983// * LDOPregister<OP>, and aliases STOPregister<OP> 10984 10985// Instruction encodings: 10986// 10987// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 10988// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 10989// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 10990// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 10991// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 10992// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 10993 10994// Instruction syntax: 10995// 10996// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10997// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 10998// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 10999// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11000// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11001// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11002// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11003// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11004// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11005// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11006 11007let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11008class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11009 string cstr, list<dag> pattern> 11010 : I<oops, iops, asm, operands, cstr, pattern> { 11011 bits<2> Sz; 11012 bit NP; 11013 bit Acq; 11014 bit Rel; 11015 bits<5> Rs; 11016 bits<5> Rn; 11017 bits<5> Rt; 11018 let Inst{31-30} = Sz; 11019 let Inst{29-24} = 0b001000; 11020 let Inst{23} = NP; 11021 let Inst{22} = Acq; 11022 let Inst{21} = 0b1; 11023 let Inst{20-16} = Rs; 11024 let Inst{15} = Rel; 11025 let Inst{14-10} = 0b11111; 11026 let Inst{9-5} = Rn; 11027 let Inst{4-0} = Rt; 11028 let Predicates = [HasLSE]; 11029} 11030 11031class BaseCAS<string order, string size, RegisterClass RC> 11032 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11033 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11034 "$out = $Rs",[]>, 11035 Sched<[WriteAtomic]> { 11036 let NP = 1; 11037} 11038 11039multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11040 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11041 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11042 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11043 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11044} 11045 11046class BaseCASP<string order, string size, RegisterOperand RC> 11047 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11048 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11049 "$out = $Rs",[]>, 11050 Sched<[WriteAtomic]> { 11051 let NP = 0; 11052} 11053 11054multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11055 let Sz = 0b00, Acq = Acq, Rel = Rel in 11056 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11057 let Sz = 0b01, Acq = Acq, Rel = Rel in 11058 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11059} 11060 11061let Predicates = [HasLSE] in 11062class BaseSWP<string order, string size, RegisterClass RC> 11063 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11064 "\t$Rs, $Rt, [$Rn]","",[]>, 11065 Sched<[WriteAtomic]> { 11066 bits<2> Sz; 11067 bit Acq; 11068 bit Rel; 11069 bits<5> Rs; 11070 bits<3> opc = 0b000; 11071 bits<5> Rn; 11072 bits<5> Rt; 11073 let Inst{31-30} = Sz; 11074 let Inst{29-24} = 0b111000; 11075 let Inst{23} = Acq; 11076 let Inst{22} = Rel; 11077 let Inst{21} = 0b1; 11078 let Inst{20-16} = Rs; 11079 let Inst{15} = 0b1; 11080 let Inst{14-12} = opc; 11081 let Inst{11-10} = 0b00; 11082 let Inst{9-5} = Rn; 11083 let Inst{4-0} = Rt; 11084 let Predicates = [HasLSE]; 11085} 11086 11087multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11088 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11089 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11090 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11091 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11092} 11093 11094let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11095class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11096 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11097 "\t$Rs, $Rt, [$Rn]","",[]>, 11098 Sched<[WriteAtomic]> { 11099 bits<2> Sz; 11100 bit Acq; 11101 bit Rel; 11102 bits<5> Rs; 11103 bits<3> opc; 11104 bits<5> Rn; 11105 bits<5> Rt; 11106 let Inst{31-30} = Sz; 11107 let Inst{29-24} = 0b111000; 11108 let Inst{23} = Acq; 11109 let Inst{22} = Rel; 11110 let Inst{21} = 0b1; 11111 let Inst{20-16} = Rs; 11112 let Inst{15} = 0b0; 11113 let Inst{14-12} = opc; 11114 let Inst{11-10} = 0b00; 11115 let Inst{9-5} = Rn; 11116 let Inst{4-0} = Rt; 11117 let Predicates = [HasLSE]; 11118} 11119 11120multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11121 string order> { 11122 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11123 def B : BaseLDOPregister<op, order, "b", GPR32>; 11124 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11125 def H : BaseLDOPregister<op, order, "h", GPR32>; 11126 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11127 def W : BaseLDOPregister<op, order, "", GPR32>; 11128 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11129 def X : BaseLDOPregister<op, order, "", GPR64>; 11130} 11131 11132// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11133// complex DAG for DstRHS. 11134let Predicates = [HasLSE] in 11135multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11136 string size, dag SrcRHS, dag DstRHS> { 11137 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11138 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11139 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11140 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11141 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11142 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11143 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11144 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11145 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11146 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11147} 11148 11149multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11150 string size, dag RHS> { 11151 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11152} 11153 11154multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11155 string size, dag LHS, dag RHS> { 11156 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11157} 11158 11159multiclass LDOPregister_patterns<string inst, string op> { 11160 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11161 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11162 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11163 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11164} 11165 11166multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11167 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11168 (i64 GPR64:$Rm), 11169 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11170 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11171 (i32 GPR32:$Rm), 11172 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11173 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11174 (i32 GPR32:$Rm), 11175 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11176 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11177 (i32 GPR32:$Rm), 11178 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11179} 11180 11181let Predicates = [HasLSE] in 11182multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11183 string size, dag OLD, dag NEW> { 11184 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11185 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11186 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11187 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11188 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11189 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11190 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11191 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11192 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11193 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11194} 11195 11196multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11197 string size, dag OLD, dag NEW> { 11198 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11199} 11200 11201multiclass CASregister_patterns<string inst, string op> { 11202 defm : CASregister_patterns_ord<inst, "X", op, "64", 11203 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11204 defm : CASregister_patterns_ord<inst, "W", op, "32", 11205 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11206 defm : CASregister_patterns_ord<inst, "H", op, "16", 11207 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11208 defm : CASregister_patterns_ord<inst, "B", op, "8", 11209 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11210} 11211 11212let Predicates = [HasLSE] in 11213class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11214 Instruction inst> : 11215 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11216 11217multiclass STOPregister<string asm, string instr> { 11218 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11219 !cast<Instruction>(instr # "LB")>; 11220 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11221 !cast<Instruction>(instr # "LH")>; 11222 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11223 !cast<Instruction>(instr # "LW")>; 11224 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11225 !cast<Instruction>(instr # "LX")>; 11226 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11227 !cast<Instruction>(instr # "B")>; 11228 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11229 !cast<Instruction>(instr # "H")>; 11230 def : BaseSTOPregister<asm, GPR32, WZR, 11231 !cast<Instruction>(instr # "W")>; 11232 def : BaseSTOPregister<asm, GPR64, XZR, 11233 !cast<Instruction>(instr # "X")>; 11234} 11235 11236//---------------------------------------------------------------------------- 11237// Allow the size specifier tokens to be upper case, not just lower. 11238def : TokenAlias<".4B", ".4b">; // Add dot product 11239def : TokenAlias<".8B", ".8b">; 11240def : TokenAlias<".4H", ".4h">; 11241def : TokenAlias<".2S", ".2s">; 11242def : TokenAlias<".1D", ".1d">; 11243def : TokenAlias<".16B", ".16b">; 11244def : TokenAlias<".8H", ".8h">; 11245def : TokenAlias<".4S", ".4s">; 11246def : TokenAlias<".2D", ".2d">; 11247def : TokenAlias<".1Q", ".1q">; 11248def : TokenAlias<".2H", ".2h">; 11249def : TokenAlias<".B", ".b">; 11250def : TokenAlias<".H", ".h">; 11251def : TokenAlias<".S", ".s">; 11252def : TokenAlias<".D", ".d">; 11253def : TokenAlias<".Q", ".q">; 11254