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// imm0_15 predicate - True if the immediate is in the range [0,15] 918def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 919 return ((uint64_t)Imm) < 16; 920}]> { 921 let ParserMatchClass = Imm0_15Operand; 922} 923 924// imm0_7 predicate - True if the immediate is in the range [0,7] 925def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 926 return ((uint64_t)Imm) < 8; 927}]> { 928 let ParserMatchClass = Imm0_7Operand; 929} 930 931// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 932def imm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 933 return ((uint32_t)Imm) < 8; 934}]> { 935 let ParserMatchClass = Imm0_7Operand; 936} 937 938// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 939def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 940 return ((uint32_t)Imm) < 16; 941}]> { 942 let ParserMatchClass = Imm0_15Operand; 943} 944 945// An arithmetic shifter operand: 946// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 947// {5-0} - imm6 948class arith_shift<ValueType Ty, int width> : Operand<Ty> { 949 let PrintMethod = "printShifter"; 950 let ParserMatchClass = !cast<AsmOperandClass>( 951 "ArithmeticShifterOperand" # width); 952} 953 954def arith_shift32 : arith_shift<i32, 32>; 955def arith_shift64 : arith_shift<i64, 64>; 956 957class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 958 : Operand<Ty>, 959 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 960 let PrintMethod = "printShiftedRegister"; 961 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 962} 963 964def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 965def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 966 967def gi_arith_shifted_reg32 : 968 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 969 GIComplexPatternEquiv<arith_shifted_reg32>; 970 971def gi_arith_shifted_reg64 : 972 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 973 GIComplexPatternEquiv<arith_shifted_reg64>; 974 975// An arithmetic shifter operand: 976// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 977// {5-0} - imm6 978class logical_shift<int width> : Operand<i32> { 979 let PrintMethod = "printShifter"; 980 let ParserMatchClass = !cast<AsmOperandClass>( 981 "LogicalShifterOperand" # width); 982} 983 984def logical_shift32 : logical_shift<32>; 985def logical_shift64 : logical_shift<64>; 986 987class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 988 : Operand<Ty>, 989 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 990 let PrintMethod = "printShiftedRegister"; 991 let MIOperandInfo = (ops regclass, shiftop); 992} 993 994def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 995def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 996 997def gi_logical_shifted_reg32 : 998 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 999 GIComplexPatternEquiv<logical_shifted_reg32>; 1000 1001def gi_logical_shifted_reg64 : 1002 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1003 GIComplexPatternEquiv<logical_shifted_reg64>; 1004 1005// A logical vector shifter operand: 1006// {7-6} - shift type: 00 = lsl 1007// {5-0} - imm6: #0, #8, #16, or #24 1008def logical_vec_shift : Operand<i32> { 1009 let PrintMethod = "printShifter"; 1010 let EncoderMethod = "getVecShifterOpValue"; 1011 let ParserMatchClass = LogicalVecShifterOperand; 1012} 1013 1014// A logical vector half-word shifter operand: 1015// {7-6} - shift type: 00 = lsl 1016// {5-0} - imm6: #0 or #8 1017def logical_vec_hw_shift : Operand<i32> { 1018 let PrintMethod = "printShifter"; 1019 let EncoderMethod = "getVecShifterOpValue"; 1020 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1021} 1022 1023// A vector move shifter operand: 1024// {0} - imm1: #8 or #16 1025def move_vec_shift : Operand<i32> { 1026 let PrintMethod = "printShifter"; 1027 let EncoderMethod = "getMoveVecShifterOpValue"; 1028 let ParserMatchClass = MoveVecShifterOperand; 1029} 1030 1031let DiagnosticType = "AddSubSecondSource" in { 1032 def AddSubImmOperand : AsmOperandClass { 1033 let Name = "AddSubImm"; 1034 let ParserMethod = "tryParseImmWithOptionalShift"; 1035 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1036 } 1037 def AddSubImmNegOperand : AsmOperandClass { 1038 let Name = "AddSubImmNeg"; 1039 let ParserMethod = "tryParseImmWithOptionalShift"; 1040 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1041 } 1042} 1043// An ADD/SUB immediate shifter operand: 1044// second operand: 1045// {7-6} - shift type: 00 = lsl 1046// {5-0} - imm6: #0 or #12 1047class addsub_shifted_imm<ValueType Ty> 1048 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1049 let PrintMethod = "printAddSubImm"; 1050 let EncoderMethod = "getAddSubImmOpValue"; 1051 let ParserMatchClass = AddSubImmOperand; 1052 let MIOperandInfo = (ops i32imm, i32imm); 1053} 1054 1055class addsub_shifted_imm_neg<ValueType Ty> 1056 : Operand<Ty> { 1057 let EncoderMethod = "getAddSubImmOpValue"; 1058 let ParserMatchClass = AddSubImmNegOperand; 1059 let MIOperandInfo = (ops i32imm, i32imm); 1060} 1061 1062def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1063def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1064def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1065def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1066 1067def gi_addsub_shifted_imm32 : 1068 GIComplexOperandMatcher<s32, "selectArithImmed">, 1069 GIComplexPatternEquiv<addsub_shifted_imm32>; 1070 1071def gi_addsub_shifted_imm64 : 1072 GIComplexOperandMatcher<s64, "selectArithImmed">, 1073 GIComplexPatternEquiv<addsub_shifted_imm64>; 1074 1075class neg_addsub_shifted_imm<ValueType Ty> 1076 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1077 let PrintMethod = "printAddSubImm"; 1078 let EncoderMethod = "getAddSubImmOpValue"; 1079 let ParserMatchClass = AddSubImmOperand; 1080 let MIOperandInfo = (ops i32imm, i32imm); 1081} 1082 1083def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1084def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1085 1086def gi_neg_addsub_shifted_imm32 : 1087 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1088 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1089 1090def gi_neg_addsub_shifted_imm64 : 1091 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1092 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1093 1094// An extend operand: 1095// {5-3} - extend type 1096// {2-0} - imm3 1097def arith_extend : Operand<i32> { 1098 let PrintMethod = "printArithExtend"; 1099 let ParserMatchClass = ExtendOperand; 1100} 1101def arith_extend64 : Operand<i32> { 1102 let PrintMethod = "printArithExtend"; 1103 let ParserMatchClass = ExtendOperand64; 1104} 1105 1106// 'extend' that's a lsl of a 64-bit register. 1107def arith_extendlsl64 : Operand<i32> { 1108 let PrintMethod = "printArithExtend"; 1109 let ParserMatchClass = ExtendOperandLSL64; 1110} 1111 1112class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1113 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1114 let PrintMethod = "printExtendedRegister"; 1115 let MIOperandInfo = (ops GPR32, arith_extend); 1116} 1117 1118class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1119 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1120 let PrintMethod = "printExtendedRegister"; 1121 let MIOperandInfo = (ops GPR32, arith_extend64); 1122} 1123 1124def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1125def gi_arith_extended_reg32_i32 : 1126 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1127 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1128 1129def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1130def gi_arith_extended_reg32_i64 : 1131 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1132 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1133 1134def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1135def gi_arith_extended_reg32to64_i64 : 1136 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1137 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1138 1139// Floating-point immediate. 1140def fpimm16 : Operand<f16>, 1141 FPImmLeaf<f16, [{ 1142 return AArch64_AM::getFP16Imm(Imm) != -1; 1143 }], SDNodeXForm<fpimm, [{ 1144 APFloat InVal = N->getValueAPF(); 1145 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1146 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1147 }]>> { 1148 let ParserMatchClass = FPImmOperand; 1149 let PrintMethod = "printFPImmOperand"; 1150} 1151def fpimm32 : Operand<f32>, 1152 FPImmLeaf<f32, [{ 1153 return AArch64_AM::getFP32Imm(Imm) != -1; 1154 }], SDNodeXForm<fpimm, [{ 1155 APFloat InVal = N->getValueAPF(); 1156 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1157 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1158 }]>> { 1159 let ParserMatchClass = FPImmOperand; 1160 let PrintMethod = "printFPImmOperand"; 1161} 1162def fpimm64 : Operand<f64>, 1163 FPImmLeaf<f64, [{ 1164 return AArch64_AM::getFP64Imm(Imm) != -1; 1165 }], SDNodeXForm<fpimm, [{ 1166 APFloat InVal = N->getValueAPF(); 1167 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1168 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1169 }]>> { 1170 let ParserMatchClass = FPImmOperand; 1171 let PrintMethod = "printFPImmOperand"; 1172} 1173 1174def fpimm8 : Operand<i32> { 1175 let ParserMatchClass = FPImmOperand; 1176 let PrintMethod = "printFPImmOperand"; 1177} 1178 1179def fpimm0 : FPImmLeaf<fAny, [{ 1180 return Imm.isExactlyValue(+0.0); 1181}]>; 1182 1183// Vector lane operands 1184class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1185 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1186 let DiagnosticType = "Invalid" # Name; 1187 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1188 let RenderMethod = "addVectorIndexOperands"; 1189} 1190 1191class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1192 : Operand<ty> { 1193 let ParserMatchClass = mc; 1194 let PrintMethod = "printVectorIndex"; 1195} 1196 1197multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1198 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1199 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1200} 1201 1202def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1203def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1204def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1205def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1206def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1207 1208defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1209 [{ return ((uint64_t)Imm) == 1; }]>; 1210defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1211 [{ return ((uint64_t)Imm) < 16; }]>; 1212defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1213 [{ return ((uint64_t)Imm) < 8; }]>; 1214defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1215 [{ return ((uint64_t)Imm) < 4; }]>; 1216defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1217 [{ return ((uint64_t)Imm) < 2; }]>; 1218 1219defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1220 [{ return ((uint64_t)Imm) == 1; }]>; 1221defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1222 [{ return ((uint64_t)Imm) < 16; }]>; 1223defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1224 [{ return ((uint64_t)Imm) < 8; }]>; 1225defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1226 [{ return ((uint64_t)Imm) < 4; }]>; 1227defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1228 [{ return ((uint64_t)Imm) < 2; }]>; 1229 1230def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1231def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1232def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1233def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1234def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1235 1236defm sve_elm_idx_extdup_b 1237 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1238 [{ return ((uint64_t)Imm) < 64; }]>; 1239defm sve_elm_idx_extdup_h 1240 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1241 [{ return ((uint64_t)Imm) < 32; }]>; 1242defm sve_elm_idx_extdup_s 1243 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1244 [{ return ((uint64_t)Imm) < 16; }]>; 1245defm sve_elm_idx_extdup_d 1246 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1247 [{ return ((uint64_t)Imm) < 8; }]>; 1248defm sve_elm_idx_extdup_q 1249 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1250 [{ return ((uint64_t)Imm) < 4; }]>; 1251 1252// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1253// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1254// are encoded as the eight bit value 'abcdefgh'. 1255def simdimmtype10 : Operand<i32>, 1256 FPImmLeaf<f64, [{ 1257 return AArch64_AM::isAdvSIMDModImmType10( 1258 Imm.bitcastToAPInt().getZExtValue()); 1259 }], SDNodeXForm<fpimm, [{ 1260 APFloat InVal = N->getValueAPF(); 1261 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1262 .bitcastToAPInt() 1263 .getZExtValue()); 1264 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1265 }]>> { 1266 let ParserMatchClass = SIMDImmType10Operand; 1267 let PrintMethod = "printSIMDType10Operand"; 1268} 1269 1270 1271//--- 1272// System management 1273//--- 1274 1275// Base encoding for system instruction operands. 1276let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1277class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1278 list<dag> pattern = []> 1279 : I<oops, iops, asm, operands, "", pattern> { 1280 let Inst{31-22} = 0b1101010100; 1281 let Inst{21} = L; 1282} 1283 1284// System instructions which do not have an Rt register. 1285class SimpleSystemI<bit L, dag iops, string asm, string operands, 1286 list<dag> pattern = []> 1287 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1288 let Inst{4-0} = 0b11111; 1289} 1290 1291// System instructions which have an Rt register. 1292class RtSystemI<bit L, dag oops, dag iops, string asm, string operands> 1293 : BaseSystemI<L, oops, iops, asm, operands>, 1294 Sched<[WriteSys]> { 1295 bits<5> Rt; 1296 let Inst{4-0} = Rt; 1297} 1298 1299// System instructions for transactional memory extension 1300class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1301 string asm, string operands, list<dag> pattern> 1302 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1303 Sched<[WriteSys]> { 1304 let Inst{20-12} = 0b000110011; 1305 let Inst{11-8} = CRm; 1306 let Inst{7-5} = op2; 1307 let DecoderMethod = ""; 1308 1309 let mayLoad = 1; 1310 let mayStore = 1; 1311} 1312 1313// System instructions for transactional memory - single input operand 1314class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1315 : TMBaseSystemI<0b1, CRm, 0b011, 1316 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1317 bits<5> Rt; 1318 let Inst{4-0} = Rt; 1319} 1320 1321// System instructions for transactional memory - no operand 1322class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1323 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1324 let Inst{4-0} = 0b11111; 1325} 1326 1327// System instructions for exit from transactions 1328class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1329 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1330 Sched<[WriteSys]> { 1331 bits<16> imm; 1332 let Inst{31-24} = 0b11010100; 1333 let Inst{23-21} = op1; 1334 let Inst{20-5} = imm; 1335 let Inst{4-0} = 0b00000; 1336} 1337 1338// Hint instructions that take both a CRm and a 3-bit immediate. 1339// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1340// model patterns with sufficiently fine granularity 1341let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1342 class HintI<string mnemonic> 1343 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1344 [(int_aarch64_hint imm0_127:$imm)]>, 1345 Sched<[WriteHint]> { 1346 bits <7> imm; 1347 let Inst{20-12} = 0b000110010; 1348 let Inst{11-5} = imm; 1349 } 1350 1351// System instructions taking a single literal operand which encodes into 1352// CRm. op2 differentiates the opcodes. 1353def BarrierAsmOperand : AsmOperandClass { 1354 let Name = "Barrier"; 1355 let ParserMethod = "tryParseBarrierOperand"; 1356} 1357def barrier_op : Operand<i32> { 1358 let PrintMethod = "printBarrierOption"; 1359 let ParserMatchClass = BarrierAsmOperand; 1360} 1361class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1362 list<dag> pattern = []> 1363 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1364 Sched<[WriteBarrier]> { 1365 bits<4> CRm; 1366 let Inst{20-12} = 0b000110011; 1367 let Inst{11-8} = CRm; 1368 let Inst{7-5} = opc; 1369} 1370 1371class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1372 : SimpleSystemI<0, (ins), asm, "", pattern>, 1373 Sched<[]> { 1374 bits<4> CRm; 1375 let CRm = 0b0011; 1376 let Inst{31-12} = 0b11010101000000110010; 1377 let Inst{11-8} = CRm; 1378 let Inst{7-5} = op2; 1379 let Inst{4-0} = 0b11111; 1380} 1381 1382// MRS/MSR system instructions. These have different operand classes because 1383// a different subset of registers can be accessed through each instruction. 1384def MRSSystemRegisterOperand : AsmOperandClass { 1385 let Name = "MRSSystemRegister"; 1386 let ParserMethod = "tryParseSysReg"; 1387 let DiagnosticType = "MRS"; 1388} 1389// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1390def mrs_sysreg_op : Operand<i32> { 1391 let ParserMatchClass = MRSSystemRegisterOperand; 1392 let DecoderMethod = "DecodeMRSSystemRegister"; 1393 let PrintMethod = "printMRSSystemRegister"; 1394} 1395 1396def MSRSystemRegisterOperand : AsmOperandClass { 1397 let Name = "MSRSystemRegister"; 1398 let ParserMethod = "tryParseSysReg"; 1399 let DiagnosticType = "MSR"; 1400} 1401def msr_sysreg_op : Operand<i32> { 1402 let ParserMatchClass = MSRSystemRegisterOperand; 1403 let DecoderMethod = "DecodeMSRSystemRegister"; 1404 let PrintMethod = "printMSRSystemRegister"; 1405} 1406 1407def PSBHintOperand : AsmOperandClass { 1408 let Name = "PSBHint"; 1409 let ParserMethod = "tryParsePSBHint"; 1410} 1411def psbhint_op : Operand<i32> { 1412 let ParserMatchClass = PSBHintOperand; 1413 let PrintMethod = "printPSBHintOp"; 1414 let MCOperandPredicate = [{ 1415 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1416 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1417 if (!MCOp.isImm()) 1418 return false; 1419 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1420 }]; 1421} 1422 1423def BTIHintOperand : AsmOperandClass { 1424 let Name = "BTIHint"; 1425 let ParserMethod = "tryParseBTIHint"; 1426} 1427def btihint_op : Operand<i32> { 1428 let ParserMatchClass = BTIHintOperand; 1429 let PrintMethod = "printBTIHintOp"; 1430 let MCOperandPredicate = [{ 1431 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1432 if (!MCOp.isImm()) 1433 return false; 1434 return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr; 1435 }]; 1436} 1437 1438class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1439 "mrs", "\t$Rt, $systemreg"> { 1440 bits<16> systemreg; 1441 let Inst{20-5} = systemreg; 1442} 1443 1444// FIXME: Some of these def NZCV, others don't. Best way to model that? 1445// Explicitly modeling each of the system register as a register class 1446// would do it, but feels like overkill at this point. 1447class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1448 "msr", "\t$systemreg, $Rt"> { 1449 bits<16> systemreg; 1450 let Inst{20-5} = systemreg; 1451} 1452 1453def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1454 let Name = "SystemPStateFieldWithImm0_15"; 1455 let ParserMethod = "tryParseSysReg"; 1456} 1457def pstatefield4_op : Operand<i32> { 1458 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1459 let PrintMethod = "printSystemPStateField"; 1460} 1461 1462// Instructions to modify PSTATE, no input reg 1463let Defs = [NZCV] in 1464class PstateWriteSimple<dag iops, string asm, string operands> 1465 : SimpleSystemI<0, iops, asm, operands> { 1466 1467 let Inst{20-19} = 0b00; 1468 let Inst{15-12} = 0b0100; 1469} 1470 1471class MSRpstateImm0_15 1472 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1473 "\t$pstatefield, $imm">, 1474 Sched<[WriteSys]> { 1475 1476 bits<6> pstatefield; 1477 bits<4> imm; 1478 let Inst{18-16} = pstatefield{5-3}; 1479 let Inst{11-8} = imm; 1480 let Inst{7-5} = pstatefield{2-0}; 1481 1482 let DecoderMethod = "DecodeSystemPStateInstruction"; 1483 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1484 // Fail the decoder should attempt to decode the instruction as MSRI. 1485 let hasCompleteDecoder = 0; 1486} 1487 1488def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1489 let Name = "SystemPStateFieldWithImm0_1"; 1490 let ParserMethod = "tryParseSysReg"; 1491} 1492def pstatefield1_op : Operand<i32> { 1493 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1494 let PrintMethod = "printSystemPStateField"; 1495} 1496 1497class MSRpstateImm0_1 1498 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1499 "\t$pstatefield, $imm">, 1500 Sched<[WriteSys]> { 1501 1502 bits<6> pstatefield; 1503 bit imm; 1504 let Inst{18-16} = pstatefield{5-3}; 1505 let Inst{11-9} = 0b000; 1506 let Inst{8} = imm; 1507 let Inst{7-5} = pstatefield{2-0}; 1508 1509 let DecoderMethod = "DecodeSystemPStateInstruction"; 1510 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1511 // Fail the decoder should attempt to decode the instruction as MSRI. 1512 let hasCompleteDecoder = 0; 1513} 1514 1515// SYS and SYSL generic system instructions. 1516def SysCRAsmOperand : AsmOperandClass { 1517 let Name = "SysCR"; 1518 let ParserMethod = "tryParseSysCROperand"; 1519} 1520 1521def sys_cr_op : Operand<i32> { 1522 let PrintMethod = "printSysCROperand"; 1523 let ParserMatchClass = SysCRAsmOperand; 1524} 1525 1526class SystemXtI<bit L, string asm> 1527 : RtSystemI<L, (outs), 1528 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1529 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1530 bits<3> op1; 1531 bits<4> Cn; 1532 bits<4> Cm; 1533 bits<3> op2; 1534 let Inst{20-19} = 0b01; 1535 let Inst{18-16} = op1; 1536 let Inst{15-12} = Cn; 1537 let Inst{11-8} = Cm; 1538 let Inst{7-5} = op2; 1539} 1540 1541class SystemLXtI<bit L, string asm> 1542 : RtSystemI<L, (outs), 1543 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1544 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1545 bits<3> op1; 1546 bits<4> Cn; 1547 bits<4> Cm; 1548 bits<3> op2; 1549 let Inst{20-19} = 0b01; 1550 let Inst{18-16} = op1; 1551 let Inst{15-12} = Cn; 1552 let Inst{11-8} = Cm; 1553 let Inst{7-5} = op2; 1554} 1555 1556 1557// Branch (register) instructions: 1558// 1559// case opc of 1560// 0001 blr 1561// 0000 br 1562// 0101 dret 1563// 0100 eret 1564// 0010 ret 1565// otherwise UNDEFINED 1566class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1567 string operands, list<dag> pattern> 1568 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1569 let Inst{31-25} = 0b1101011; 1570 let Inst{24-21} = opc; 1571 let Inst{20-16} = 0b11111; 1572 let Inst{15-10} = 0b000000; 1573 let Inst{4-0} = 0b00000; 1574} 1575 1576class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1577 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1578 bits<5> Rn; 1579 let Inst{9-5} = Rn; 1580} 1581 1582let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1583class SpecialReturn<bits<4> opc, string asm> 1584 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1585 let Inst{9-5} = 0b11111; 1586} 1587 1588let mayLoad = 1 in 1589class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1590 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1591 Sched<[]> { 1592 bits<5> Rn; 1593 bits<5> Rt; 1594 let Inst{31-30} = sz; 1595 let Inst{29-10} = 0b11100010111111110000; 1596 let Inst{9-5} = Rn; 1597 let Inst{4-0} = Rt; 1598} 1599 1600class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1601 list<dag> pattern> 1602 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1603 let isAuthenticated = 1; 1604 let Inst{31-25} = 0b1101011; 1605 let Inst{20-11} = 0b1111100001; 1606 let Inst{10} = M; 1607 let Inst{4-0} = 0b11111; 1608} 1609 1610class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1611 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1612 bits<5> Rn; 1613 bits<5> Rm; 1614 let Inst{24-22} = 0b100; 1615 let Inst{21} = op; 1616 let Inst{9-5} = Rn; 1617 let Inst{4-0} = Rm; 1618} 1619 1620class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1621 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1622 bits<5> Rn; 1623 let Inst{24} = 0; 1624 let Inst{23-21} = opc; 1625 let Inst{9-5} = Rn; 1626} 1627 1628let Uses = [LR,SP] in 1629class AuthReturn<bits<3> op, bits<1> M, string asm> 1630 : AuthBase<M, (outs), (ins), asm, "", []> { 1631 let Inst{24} = 0; 1632 let Inst{23-21} = op; 1633 let Inst{9-0} = 0b1111111111; 1634} 1635 1636let mayLoad = 1 in 1637class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1638 string operands, string cstr, Operand opr> 1639 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1640 bits<10> offset; 1641 bits<5> Rn; 1642 bits<5> Rt; 1643 let isAuthenticated = 1; 1644 let Inst{31-24} = 0b11111000; 1645 let Inst{23} = M; 1646 let Inst{22} = offset{9}; 1647 let Inst{21} = 1; 1648 let Inst{20-12} = offset{8-0}; 1649 let Inst{11} = W; 1650 let Inst{10} = 1; 1651 let Inst{9-5} = Rn; 1652 let Inst{4-0} = Rt; 1653 1654 let DecoderMethod = "DecodeAuthLoadInstruction"; 1655} 1656 1657multiclass AuthLoad<bit M, string asm, Operand opr> { 1658 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1659 (ins GPR64sp:$Rn, opr:$offset), 1660 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1661 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1662 (ins GPR64sp:$Rn, opr:$offset), 1663 asm, "\t$Rt, [$Rn, $offset]!", 1664 "$Rn = $wback,@earlyclobber $wback", opr>; 1665 1666 def : InstAlias<asm # "\t$Rt, [$Rn]", 1667 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1668 1669 def : InstAlias<asm # "\t$Rt, [$wback]!", 1670 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1671} 1672 1673//--- 1674// Conditional branch instruction. 1675//--- 1676 1677// Condition code. 1678// 4-bit immediate. Pretty-printed as <cc> 1679def ccode : Operand<i32> { 1680 let PrintMethod = "printCondCode"; 1681 let ParserMatchClass = CondCode; 1682} 1683def inv_ccode : Operand<i32> { 1684 // AL and NV are invalid in the aliases which use inv_ccode 1685 let PrintMethod = "printInverseCondCode"; 1686 let ParserMatchClass = CondCode; 1687 let MCOperandPredicate = [{ 1688 return MCOp.isImm() && 1689 MCOp.getImm() != AArch64CC::AL && 1690 MCOp.getImm() != AArch64CC::NV; 1691 }]; 1692} 1693 1694// Conditional branch target. 19-bit immediate. The low two bits of the target 1695// offset are implied zero and so are not part of the immediate. 1696def am_brcond : Operand<OtherVT> { 1697 let EncoderMethod = "getCondBranchTargetOpValue"; 1698 let DecoderMethod = "DecodePCRelLabel19"; 1699 let PrintMethod = "printAlignedLabel"; 1700 let ParserMatchClass = PCRelLabel19Operand; 1701 let OperandType = "OPERAND_PCREL"; 1702} 1703 1704class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1705 "b", ".$cond\t$target", "", 1706 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1707 Sched<[WriteBr]> { 1708 let isBranch = 1; 1709 let isTerminator = 1; 1710 let Uses = [NZCV]; 1711 1712 bits<4> cond; 1713 bits<19> target; 1714 let Inst{31-24} = 0b01010100; 1715 let Inst{23-5} = target; 1716 let Inst{4} = 0; 1717 let Inst{3-0} = cond; 1718} 1719 1720//--- 1721// Compare-and-branch instructions. 1722//--- 1723class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1724 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1725 asm, "\t$Rt, $target", "", 1726 [(node regtype:$Rt, bb:$target)]>, 1727 Sched<[WriteBr]> { 1728 let isBranch = 1; 1729 let isTerminator = 1; 1730 1731 bits<5> Rt; 1732 bits<19> target; 1733 let Inst{30-25} = 0b011010; 1734 let Inst{24} = op; 1735 let Inst{23-5} = target; 1736 let Inst{4-0} = Rt; 1737} 1738 1739multiclass CmpBranch<bit op, string asm, SDNode node> { 1740 def W : BaseCmpBranch<GPR32, op, asm, node> { 1741 let Inst{31} = 0; 1742 } 1743 def X : BaseCmpBranch<GPR64, op, asm, node> { 1744 let Inst{31} = 1; 1745 } 1746} 1747 1748//--- 1749// Test-bit-and-branch instructions. 1750//--- 1751// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1752// the target offset are implied zero and so are not part of the immediate. 1753def am_tbrcond : Operand<OtherVT> { 1754 let EncoderMethod = "getTestBranchTargetOpValue"; 1755 let PrintMethod = "printAlignedLabel"; 1756 let ParserMatchClass = BranchTarget14Operand; 1757 let OperandType = "OPERAND_PCREL"; 1758} 1759 1760// AsmOperand classes to emit (or not) special diagnostics 1761def TBZImm0_31Operand : AsmOperandClass { 1762 let Name = "TBZImm0_31"; 1763 let PredicateMethod = "isImmInRange<0,31>"; 1764 let RenderMethod = "addImmOperands"; 1765} 1766def TBZImm32_63Operand : AsmOperandClass { 1767 let Name = "Imm32_63"; 1768 let PredicateMethod = "isImmInRange<32,63>"; 1769 let DiagnosticType = "InvalidImm0_63"; 1770 let RenderMethod = "addImmOperands"; 1771} 1772 1773class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1774 return (((uint32_t)Imm) < 32); 1775}]> { 1776 let ParserMatchClass = matcher; 1777} 1778 1779def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1780def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1781 1782def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1783 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1784}]> { 1785 let ParserMatchClass = TBZImm32_63Operand; 1786} 1787 1788class BaseTestBranch<RegisterClass regtype, Operand immtype, 1789 bit op, string asm, SDNode node> 1790 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1791 asm, "\t$Rt, $bit_off, $target", "", 1792 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1793 Sched<[WriteBr]> { 1794 let isBranch = 1; 1795 let isTerminator = 1; 1796 1797 bits<5> Rt; 1798 bits<6> bit_off; 1799 bits<14> target; 1800 1801 let Inst{30-25} = 0b011011; 1802 let Inst{24} = op; 1803 let Inst{23-19} = bit_off{4-0}; 1804 let Inst{18-5} = target; 1805 let Inst{4-0} = Rt; 1806 1807 let DecoderMethod = "DecodeTestAndBranch"; 1808} 1809 1810multiclass TestBranch<bit op, string asm, SDNode node> { 1811 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1812 let Inst{31} = 0; 1813 } 1814 1815 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1816 let Inst{31} = 1; 1817 } 1818 1819 // Alias X-reg with 0-31 imm to W-Reg. 1820 def : InstAlias<asm # "\t$Rd, $imm, $target", 1821 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1822 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1823 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1824 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1825 tbz_imm0_31_diag:$imm, bb:$target)>; 1826} 1827 1828//--- 1829// Unconditional branch (immediate) instructions. 1830//--- 1831def am_b_target : Operand<OtherVT> { 1832 let EncoderMethod = "getBranchTargetOpValue"; 1833 let PrintMethod = "printAlignedLabel"; 1834 let ParserMatchClass = BranchTarget26Operand; 1835 let OperandType = "OPERAND_PCREL"; 1836} 1837def am_bl_target : Operand<i64> { 1838 let EncoderMethod = "getBranchTargetOpValue"; 1839 let PrintMethod = "printAlignedLabel"; 1840 let ParserMatchClass = BranchTarget26Operand; 1841 let OperandType = "OPERAND_PCREL"; 1842} 1843 1844class BImm<bit op, dag iops, string asm, list<dag> pattern> 1845 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1846 bits<26> addr; 1847 let Inst{31} = op; 1848 let Inst{30-26} = 0b00101; 1849 let Inst{25-0} = addr; 1850 1851 let DecoderMethod = "DecodeUnconditionalBranch"; 1852} 1853 1854class BranchImm<bit op, string asm, list<dag> pattern> 1855 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1856class CallImm<bit op, string asm, list<dag> pattern> 1857 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1858 1859//--- 1860// Basic one-operand data processing instructions. 1861//--- 1862 1863let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1864class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1865 SDPatternOperator node> 1866 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1867 [(set regtype:$Rd, (node regtype:$Rn))]>, 1868 Sched<[WriteI, ReadI]> { 1869 bits<5> Rd; 1870 bits<5> Rn; 1871 1872 let Inst{30-13} = 0b101101011000000000; 1873 let Inst{12-10} = opc; 1874 let Inst{9-5} = Rn; 1875 let Inst{4-0} = Rd; 1876} 1877 1878let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1879multiclass OneOperandData<bits<3> opc, string asm, 1880 SDPatternOperator node = null_frag> { 1881 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1882 let Inst{31} = 0; 1883 } 1884 1885 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1886 let Inst{31} = 1; 1887 } 1888} 1889 1890class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1891 : BaseOneOperandData<opc, GPR32, asm, node> { 1892 let Inst{31} = 0; 1893} 1894 1895class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1896 : BaseOneOperandData<opc, GPR64, asm, node> { 1897 let Inst{31} = 1; 1898} 1899 1900class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1901 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "", 1902 []>, 1903 Sched<[WriteI, ReadI]> { 1904 bits<5> Rd; 1905 bits<5> Rn; 1906 let Inst{31-15} = 0b11011010110000010; 1907 let Inst{14-12} = opcode_prefix; 1908 let Inst{11-10} = opcode; 1909 let Inst{9-5} = Rn; 1910 let Inst{4-0} = Rd; 1911} 1912 1913class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1914 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> { 1915 bits<5> Rd; 1916 let Inst{31-15} = 0b11011010110000010; 1917 let Inst{14-12} = opcode_prefix; 1918 let Inst{11-10} = opcode; 1919 let Inst{9-5} = 0b11111; 1920 let Inst{4-0} = Rd; 1921} 1922 1923class SignAuthTwoOperand<bits<4> opc, string asm, 1924 SDPatternOperator OpNode> 1925 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1926 asm, "\t$Rd, $Rn, $Rm", "", 1927 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1928 Sched<[WriteI, ReadI, ReadI]> { 1929 bits<5> Rd; 1930 bits<5> Rn; 1931 bits<5> Rm; 1932 let Inst{31-21} = 0b10011010110; 1933 let Inst{20-16} = Rm; 1934 let Inst{15-14} = 0b00; 1935 let Inst{13-10} = opc; 1936 let Inst{9-5} = Rn; 1937 let Inst{4-0} = Rd; 1938} 1939 1940// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 1941class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 1942 : I<(outs), iops, asm, ops, "", []>, 1943 Sched<[WriteI, ReadI, ReadI]> { 1944 let Uses = [NZCV]; 1945 bits<5> Rn; 1946 let Inst{31} = sf; 1947 let Inst{30-15} = 0b0111010000000000; 1948 let Inst{14} = sz; 1949 let Inst{13-10} = 0b0010; 1950 let Inst{9-5} = Rn; 1951 let Inst{4-0} = 0b01101; 1952} 1953 1954class FlagRotate<dag iops, string asm, string ops> 1955 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 1956 bits<6> imm; 1957 bits<4> mask; 1958 let Inst{20-15} = imm; 1959 let Inst{13-10} = 0b0001; 1960 let Inst{4} = 0b0; 1961 let Inst{3-0} = mask; 1962} 1963 1964//--- 1965// Basic two-operand data processing instructions. 1966//--- 1967class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1968 list<dag> pattern> 1969 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1970 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1971 Sched<[WriteI, ReadI, ReadI]> { 1972 let Uses = [NZCV]; 1973 bits<5> Rd; 1974 bits<5> Rn; 1975 bits<5> Rm; 1976 let Inst{30} = isSub; 1977 let Inst{28-21} = 0b11010000; 1978 let Inst{20-16} = Rm; 1979 let Inst{15-10} = 0; 1980 let Inst{9-5} = Rn; 1981 let Inst{4-0} = Rd; 1982} 1983 1984class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1985 SDNode OpNode> 1986 : BaseBaseAddSubCarry<isSub, regtype, asm, 1987 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 1988 1989class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 1990 SDNode OpNode> 1991 : BaseBaseAddSubCarry<isSub, regtype, asm, 1992 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 1993 (implicit NZCV)]> { 1994 let Defs = [NZCV]; 1995} 1996 1997multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 1998 SDNode OpNode, SDNode OpNode_setflags> { 1999 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2000 let Inst{31} = 0; 2001 let Inst{29} = 0; 2002 } 2003 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2004 let Inst{31} = 1; 2005 let Inst{29} = 0; 2006 } 2007 2008 // Sets flags. 2009 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2010 OpNode_setflags> { 2011 let Inst{31} = 0; 2012 let Inst{29} = 1; 2013 } 2014 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2015 OpNode_setflags> { 2016 let Inst{31} = 1; 2017 let Inst{29} = 1; 2018 } 2019} 2020 2021class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 2022 SDPatternOperator OpNode, 2023 RegisterClass in1regtype = regtype, 2024 RegisterClass in2regtype = regtype> 2025 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2026 asm, "\t$Rd, $Rn, $Rm", "", 2027 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2028 bits<5> Rd; 2029 bits<5> Rn; 2030 bits<5> Rm; 2031 let Inst{30-21} = 0b0011010110; 2032 let Inst{20-16} = Rm; 2033 let Inst{15-14} = 0b00; 2034 let Inst{13-10} = opc; 2035 let Inst{9-5} = Rn; 2036 let Inst{4-0} = Rd; 2037} 2038 2039class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 2040 SDPatternOperator OpNode> 2041 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 2042 let Inst{10} = isSigned; 2043} 2044 2045multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2046 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 2047 Sched<[WriteID32, ReadID, ReadID]> { 2048 let Inst{31} = 0; 2049 } 2050 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 2051 Sched<[WriteID64, ReadID, ReadID]> { 2052 let Inst{31} = 1; 2053 } 2054} 2055 2056class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 2057 SDPatternOperator OpNode = null_frag> 2058 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 2059 Sched<[WriteIS, ReadI]> { 2060 let Inst{11-10} = shift_type; 2061} 2062 2063multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2064 def Wr : BaseShift<shift_type, GPR32, asm> { 2065 let Inst{31} = 0; 2066 } 2067 2068 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 2069 let Inst{31} = 1; 2070 } 2071 2072 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2073 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2074 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2075 2076 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2077 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2078 2079 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2080 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2081 2082 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2083 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2084 2085 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2086 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2087 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2088 2089 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2090 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2091 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2092} 2093 2094class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2095 : InstAlias<asm#"\t$dst, $src1, $src2", 2096 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2097 2098class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2099 RegisterClass addtype, string asm, 2100 list<dag> pattern> 2101 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2102 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2103 bits<5> Rd; 2104 bits<5> Rn; 2105 bits<5> Rm; 2106 bits<5> Ra; 2107 let Inst{30-24} = 0b0011011; 2108 let Inst{23-21} = opc; 2109 let Inst{20-16} = Rm; 2110 let Inst{15} = isSub; 2111 let Inst{14-10} = Ra; 2112 let Inst{9-5} = Rn; 2113 let Inst{4-0} = Rd; 2114} 2115 2116multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 2117 // MADD/MSUB generation is decided by MachineCombiner.cpp 2118 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 2119 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 2120 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2121 let Inst{31} = 0; 2122 } 2123 2124 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 2125 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 2126 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2127 let Inst{31} = 1; 2128 } 2129} 2130 2131class WideMulAccum<bit isSub, bits<3> opc, string asm, 2132 SDNode AccNode, SDNode ExtNode> 2133 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2134 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2135 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2136 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2137 let Inst{31} = 1; 2138} 2139 2140class MulHi<bits<3> opc, string asm, SDNode OpNode> 2141 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2142 asm, "\t$Rd, $Rn, $Rm", "", 2143 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2144 Sched<[WriteIM64, ReadIM, ReadIM]> { 2145 bits<5> Rd; 2146 bits<5> Rn; 2147 bits<5> Rm; 2148 let Inst{31-24} = 0b10011011; 2149 let Inst{23-21} = opc; 2150 let Inst{20-16} = Rm; 2151 let Inst{15} = 0; 2152 let Inst{9-5} = Rn; 2153 let Inst{4-0} = Rd; 2154 2155 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2156 // (i.e. all bits 1) but is ignored by the processor. 2157 let PostEncoderMethod = "fixMulHigh"; 2158} 2159 2160class MulAccumWAlias<string asm, Instruction inst> 2161 : InstAlias<asm#"\t$dst, $src1, $src2", 2162 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2163class MulAccumXAlias<string asm, Instruction inst> 2164 : InstAlias<asm#"\t$dst, $src1, $src2", 2165 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2166class WideMulAccumAlias<string asm, Instruction inst> 2167 : InstAlias<asm#"\t$dst, $src1, $src2", 2168 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2169 2170class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2171 SDPatternOperator OpNode, string asm> 2172 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2173 asm, "\t$Rd, $Rn, $Rm", "", 2174 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2175 Sched<[WriteISReg, ReadI, ReadISReg]> { 2176 bits<5> Rd; 2177 bits<5> Rn; 2178 bits<5> Rm; 2179 2180 let Inst{31} = sf; 2181 let Inst{30-21} = 0b0011010110; 2182 let Inst{20-16} = Rm; 2183 let Inst{15-13} = 0b010; 2184 let Inst{12} = C; 2185 let Inst{11-10} = sz; 2186 let Inst{9-5} = Rn; 2187 let Inst{4-0} = Rd; 2188 let Predicates = [HasCRC]; 2189} 2190 2191//--- 2192// Address generation. 2193//--- 2194 2195class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2196 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2197 pattern>, 2198 Sched<[WriteI]> { 2199 bits<5> Xd; 2200 bits<21> label; 2201 let Inst{31} = page; 2202 let Inst{30-29} = label{1-0}; 2203 let Inst{28-24} = 0b10000; 2204 let Inst{23-5} = label{20-2}; 2205 let Inst{4-0} = Xd; 2206 2207 let DecoderMethod = "DecodeAdrInstruction"; 2208} 2209 2210//--- 2211// Move immediate. 2212//--- 2213 2214def movimm32_imm : Operand<i32> { 2215 let ParserMatchClass = AsmImmRange<0, 65535>; 2216 let EncoderMethod = "getMoveWideImmOpValue"; 2217 let PrintMethod = "printImm"; 2218} 2219def movimm32_shift : Operand<i32> { 2220 let PrintMethod = "printShifter"; 2221 let ParserMatchClass = MovImm32ShifterOperand; 2222} 2223def movimm64_shift : Operand<i32> { 2224 let PrintMethod = "printShifter"; 2225 let ParserMatchClass = MovImm64ShifterOperand; 2226} 2227 2228let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2229class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2230 string asm> 2231 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2232 asm, "\t$Rd, $imm$shift", "", []>, 2233 Sched<[WriteImm]> { 2234 bits<5> Rd; 2235 bits<16> imm; 2236 bits<6> shift; 2237 let Inst{30-29} = opc; 2238 let Inst{28-23} = 0b100101; 2239 let Inst{22-21} = shift{5-4}; 2240 let Inst{20-5} = imm; 2241 let Inst{4-0} = Rd; 2242 2243 let DecoderMethod = "DecodeMoveImmInstruction"; 2244} 2245 2246multiclass MoveImmediate<bits<2> opc, string asm> { 2247 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2248 let Inst{31} = 0; 2249 } 2250 2251 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2252 let Inst{31} = 1; 2253 } 2254} 2255 2256let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2257class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2258 string asm> 2259 : I<(outs regtype:$Rd), 2260 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2261 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2262 Sched<[WriteI, ReadI]> { 2263 bits<5> Rd; 2264 bits<16> imm; 2265 bits<6> shift; 2266 let Inst{30-29} = opc; 2267 let Inst{28-23} = 0b100101; 2268 let Inst{22-21} = shift{5-4}; 2269 let Inst{20-5} = imm; 2270 let Inst{4-0} = Rd; 2271 2272 let DecoderMethod = "DecodeMoveImmInstruction"; 2273} 2274 2275multiclass InsertImmediate<bits<2> opc, string asm> { 2276 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2277 let Inst{31} = 0; 2278 } 2279 2280 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2281 let Inst{31} = 1; 2282 } 2283} 2284 2285//--- 2286// Add/Subtract 2287//--- 2288 2289class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2290 string asm_inst, string asm_ops, 2291 dag inputs, dag pattern> 2292 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2293 Sched<[WriteI, ReadI]> { 2294 bits<5> Rd; 2295 bits<5> Rn; 2296 let Inst{30} = isSub; 2297 let Inst{29} = setFlags; 2298 let Inst{28-24} = 0b10001; 2299 let Inst{9-5} = Rn; 2300 let Inst{4-0} = Rd; 2301} 2302 2303class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2304 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2305 string asm_inst, SDPatternOperator OpNode> 2306 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2307 (ins srcRegtype:$Rn, immtype:$imm), 2308 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2309 bits<14> imm; 2310 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2311 let Inst{21-10} = imm{11-0}; 2312 let DecoderMethod = "DecodeAddSubImmShift"; 2313} 2314 2315class BaseAddSubRegPseudo<RegisterClass regtype, 2316 SDPatternOperator OpNode> 2317 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2318 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2319 Sched<[WriteI, ReadI, ReadI]>; 2320 2321class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2322 arith_shifted_reg shifted_regtype, string asm, 2323 SDPatternOperator OpNode> 2324 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2325 asm, "\t$Rd, $Rn, $Rm", "", 2326 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2327 Sched<[WriteISReg, ReadI, ReadISReg]> { 2328 // The operands are in order to match the 'addr' MI operands, so we 2329 // don't need an encoder method and by-name matching. Just use the default 2330 // in-order handling. Since we're using by-order, make sure the names 2331 // do not match. 2332 bits<5> dst; 2333 bits<5> src1; 2334 bits<5> src2; 2335 bits<8> shift; 2336 let Inst{30} = isSub; 2337 let Inst{29} = setFlags; 2338 let Inst{28-24} = 0b01011; 2339 let Inst{23-22} = shift{7-6}; 2340 let Inst{21} = 0; 2341 let Inst{20-16} = src2; 2342 let Inst{15-10} = shift{5-0}; 2343 let Inst{9-5} = src1; 2344 let Inst{4-0} = dst; 2345 2346 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2347} 2348 2349class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2350 RegisterClass src1Regtype, Operand src2Regtype, 2351 string asm, SDPatternOperator OpNode> 2352 : I<(outs dstRegtype:$R1), 2353 (ins src1Regtype:$R2, src2Regtype:$R3), 2354 asm, "\t$R1, $R2, $R3", "", 2355 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2356 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2357 bits<5> Rd; 2358 bits<5> Rn; 2359 bits<5> Rm; 2360 bits<6> ext; 2361 let Inst{30} = isSub; 2362 let Inst{29} = setFlags; 2363 let Inst{28-24} = 0b01011; 2364 let Inst{23-21} = 0b001; 2365 let Inst{20-16} = Rm; 2366 let Inst{15-13} = ext{5-3}; 2367 let Inst{12-10} = ext{2-0}; 2368 let Inst{9-5} = Rn; 2369 let Inst{4-0} = Rd; 2370 2371 let DecoderMethod = "DecodeAddSubERegInstruction"; 2372} 2373 2374let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2375class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2376 RegisterClass src1Regtype, RegisterClass src2Regtype, 2377 Operand ext_op, string asm> 2378 : I<(outs dstRegtype:$Rd), 2379 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2380 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2381 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2382 bits<5> Rd; 2383 bits<5> Rn; 2384 bits<5> Rm; 2385 bits<6> ext; 2386 let Inst{30} = isSub; 2387 let Inst{29} = setFlags; 2388 let Inst{28-24} = 0b01011; 2389 let Inst{23-21} = 0b001; 2390 let Inst{20-16} = Rm; 2391 let Inst{15} = ext{5}; 2392 let Inst{12-10} = ext{2-0}; 2393 let Inst{9-5} = Rn; 2394 let Inst{4-0} = Rd; 2395 2396 let DecoderMethod = "DecodeAddSubERegInstruction"; 2397} 2398 2399// Aliases for register+register add/subtract. 2400class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2401 RegisterClass src1Regtype, RegisterClass src2Regtype, 2402 int shiftExt> 2403 : InstAlias<asm#"\t$dst, $src1, $src2", 2404 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2405 shiftExt)>; 2406 2407multiclass AddSub<bit isSub, string mnemonic, string alias, 2408 SDPatternOperator OpNode = null_frag> { 2409 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2410 // Add/Subtract immediate 2411 // Increase the weight of the immediate variant to try to match it before 2412 // the extended register variant. 2413 // We used to match the register variant before the immediate when the 2414 // register argument could be implicitly zero-extended. 2415 let AddedComplexity = 6 in 2416 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2417 mnemonic, OpNode> { 2418 let Inst{31} = 0; 2419 } 2420 let AddedComplexity = 6 in 2421 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2422 mnemonic, OpNode> { 2423 let Inst{31} = 1; 2424 } 2425 2426 // Add/Subtract register - Only used for CodeGen 2427 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2428 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2429 2430 // Add/Subtract shifted register 2431 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2432 OpNode> { 2433 let Inst{31} = 0; 2434 } 2435 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2436 OpNode> { 2437 let Inst{31} = 1; 2438 } 2439 } 2440 2441 // Add/Subtract extended register 2442 let AddedComplexity = 1, hasSideEffects = 0 in { 2443 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2444 arith_extended_reg32_i32, mnemonic, OpNode> { 2445 let Inst{31} = 0; 2446 } 2447 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2448 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2449 let Inst{31} = 1; 2450 } 2451 } 2452 2453 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2454 arith_extendlsl64, mnemonic> { 2455 // UXTX and SXTX only. 2456 let Inst{14-13} = 0b11; 2457 let Inst{31} = 1; 2458 } 2459 2460 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2461 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2462 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2463 addsub_shifted_imm32_neg:$imm), 0>; 2464 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2465 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2466 addsub_shifted_imm64_neg:$imm), 0>; 2467 2468 // Register/register aliases with no shift when SP is not used. 2469 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2470 GPR32, GPR32, GPR32, 0>; 2471 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2472 GPR64, GPR64, GPR64, 0>; 2473 2474 // Register/register aliases with no shift when either the destination or 2475 // first source register is SP. 2476 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2477 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2478 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2479 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2480 def : AddSubRegAlias<mnemonic, 2481 !cast<Instruction>(NAME#"Xrx64"), 2482 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2483 def : AddSubRegAlias<mnemonic, 2484 !cast<Instruction>(NAME#"Xrx64"), 2485 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2486} 2487 2488multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2489 string alias, string cmpAlias> { 2490 let isCompare = 1, Defs = [NZCV] in { 2491 // Add/Subtract immediate 2492 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2493 mnemonic, OpNode> { 2494 let Inst{31} = 0; 2495 } 2496 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2497 mnemonic, OpNode> { 2498 let Inst{31} = 1; 2499 } 2500 2501 // Add/Subtract register 2502 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2503 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2504 2505 // Add/Subtract shifted register 2506 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2507 OpNode> { 2508 let Inst{31} = 0; 2509 } 2510 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2511 OpNode> { 2512 let Inst{31} = 1; 2513 } 2514 2515 // Add/Subtract extended register 2516 let AddedComplexity = 1 in { 2517 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2518 arith_extended_reg32_i32, mnemonic, OpNode> { 2519 let Inst{31} = 0; 2520 } 2521 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2522 arith_extended_reg32_i64, mnemonic, OpNode> { 2523 let Inst{31} = 1; 2524 } 2525 } 2526 2527 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2528 arith_extendlsl64, mnemonic> { 2529 // UXTX and SXTX only. 2530 let Inst{14-13} = 0b11; 2531 let Inst{31} = 1; 2532 } 2533 } // Defs = [NZCV] 2534 2535 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2536 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2537 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2538 addsub_shifted_imm32_neg:$imm), 0>; 2539 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2540 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2541 addsub_shifted_imm64_neg:$imm), 0>; 2542 2543 // Compare aliases 2544 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2545 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2546 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2547 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2548 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2549 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2550 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2551 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2552 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2553 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2554 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2555 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2556 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2557 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2558 2559 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2560 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2561 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2562 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2563 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2564 2565 // Compare shorthands 2566 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2567 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2568 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2569 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2570 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2571 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2572 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2573 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2574 2575 // Register/register aliases with no shift when SP is not used. 2576 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2577 GPR32, GPR32, GPR32, 0>; 2578 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2579 GPR64, GPR64, GPR64, 0>; 2580 2581 // Register/register aliases with no shift when the first source register 2582 // is SP. 2583 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2584 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2585 def : AddSubRegAlias<mnemonic, 2586 !cast<Instruction>(NAME#"Xrx64"), 2587 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2588} 2589 2590class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2591 : BaseAddSubImm< 2592 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2593 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2594 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2595 bits<6> imm6; 2596 bits<4> imm4; 2597 let Inst{31} = 1; 2598 let Inst{23-22} = 0b10; 2599 let Inst{21-16} = imm6; 2600 let Inst{15-14} = 0b00; 2601 let Inst{13-10} = imm4; 2602 let Unpredictable{15-14} = 0b11; 2603} 2604 2605class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2606 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2607 let Inst{31} = 1; 2608 let Inst{29} = setsFlags; 2609} 2610 2611//--- 2612// Extract 2613//--- 2614def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2615 SDTCisPtrTy<3>]>; 2616def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2617 2618class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2619 list<dag> patterns> 2620 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2621 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2622 Sched<[WriteExtr, ReadExtrHi]> { 2623 bits<5> Rd; 2624 bits<5> Rn; 2625 bits<5> Rm; 2626 bits<6> imm; 2627 2628 let Inst{30-23} = 0b00100111; 2629 let Inst{21} = 0; 2630 let Inst{20-16} = Rm; 2631 let Inst{15-10} = imm; 2632 let Inst{9-5} = Rn; 2633 let Inst{4-0} = Rd; 2634} 2635 2636multiclass ExtractImm<string asm> { 2637 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2638 [(set GPR32:$Rd, 2639 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2640 let Inst{31} = 0; 2641 let Inst{22} = 0; 2642 // imm<5> must be zero. 2643 let imm{5} = 0; 2644 } 2645 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2646 [(set GPR64:$Rd, 2647 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2648 2649 let Inst{31} = 1; 2650 let Inst{22} = 1; 2651 } 2652} 2653 2654//--- 2655// Bitfield 2656//--- 2657 2658let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2659class BaseBitfieldImm<bits<2> opc, 2660 RegisterClass regtype, Operand imm_type, string asm> 2661 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2662 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2663 Sched<[WriteIS, ReadI]> { 2664 bits<5> Rd; 2665 bits<5> Rn; 2666 bits<6> immr; 2667 bits<6> imms; 2668 2669 let Inst{30-29} = opc; 2670 let Inst{28-23} = 0b100110; 2671 let Inst{21-16} = immr; 2672 let Inst{15-10} = imms; 2673 let Inst{9-5} = Rn; 2674 let Inst{4-0} = Rd; 2675} 2676 2677multiclass BitfieldImm<bits<2> opc, string asm> { 2678 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2679 let Inst{31} = 0; 2680 let Inst{22} = 0; 2681 // imms<5> and immr<5> must be zero, else ReservedValue(). 2682 let Inst{21} = 0; 2683 let Inst{15} = 0; 2684 } 2685 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2686 let Inst{31} = 1; 2687 let Inst{22} = 1; 2688 } 2689} 2690 2691let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2692class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2693 RegisterClass regtype, Operand imm_type, string asm> 2694 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2695 imm_type:$imms), 2696 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2697 Sched<[WriteIS, ReadI]> { 2698 bits<5> Rd; 2699 bits<5> Rn; 2700 bits<6> immr; 2701 bits<6> imms; 2702 2703 let Inst{30-29} = opc; 2704 let Inst{28-23} = 0b100110; 2705 let Inst{21-16} = immr; 2706 let Inst{15-10} = imms; 2707 let Inst{9-5} = Rn; 2708 let Inst{4-0} = Rd; 2709} 2710 2711multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2712 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2713 let Inst{31} = 0; 2714 let Inst{22} = 0; 2715 // imms<5> and immr<5> must be zero, else ReservedValue(). 2716 let Inst{21} = 0; 2717 let Inst{15} = 0; 2718 } 2719 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2720 let Inst{31} = 1; 2721 let Inst{22} = 1; 2722 } 2723} 2724 2725//--- 2726// Logical 2727//--- 2728 2729// Logical (immediate) 2730class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2731 RegisterClass sregtype, Operand imm_type, string asm, 2732 list<dag> pattern> 2733 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2734 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2735 Sched<[WriteI, ReadI]> { 2736 bits<5> Rd; 2737 bits<5> Rn; 2738 bits<13> imm; 2739 let Inst{30-29} = opc; 2740 let Inst{28-23} = 0b100100; 2741 let Inst{22} = imm{12}; 2742 let Inst{21-16} = imm{11-6}; 2743 let Inst{15-10} = imm{5-0}; 2744 let Inst{9-5} = Rn; 2745 let Inst{4-0} = Rd; 2746 2747 let DecoderMethod = "DecodeLogicalImmInstruction"; 2748} 2749 2750// Logical (shifted register) 2751class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2752 logical_shifted_reg shifted_regtype, string asm, 2753 list<dag> pattern> 2754 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2755 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2756 Sched<[WriteISReg, ReadI, ReadISReg]> { 2757 // The operands are in order to match the 'addr' MI operands, so we 2758 // don't need an encoder method and by-name matching. Just use the default 2759 // in-order handling. Since we're using by-order, make sure the names 2760 // do not match. 2761 bits<5> dst; 2762 bits<5> src1; 2763 bits<5> src2; 2764 bits<8> shift; 2765 let Inst{30-29} = opc; 2766 let Inst{28-24} = 0b01010; 2767 let Inst{23-22} = shift{7-6}; 2768 let Inst{21} = N; 2769 let Inst{20-16} = src2; 2770 let Inst{15-10} = shift{5-0}; 2771 let Inst{9-5} = src1; 2772 let Inst{4-0} = dst; 2773 2774 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2775} 2776 2777// Aliases for register+register logical instructions. 2778class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2779 : InstAlias<asm#"\t$dst, $src1, $src2", 2780 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2781 2782multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2783 string Alias> { 2784 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2785 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2786 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2787 logical_imm32:$imm))]> { 2788 let Inst{31} = 0; 2789 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2790 } 2791 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2792 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2793 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2794 logical_imm64:$imm))]> { 2795 let Inst{31} = 1; 2796 } 2797 2798 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2799 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2800 logical_imm32_not:$imm), 0>; 2801 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2802 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2803 logical_imm64_not:$imm), 0>; 2804} 2805 2806multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2807 string Alias> { 2808 let isCompare = 1, Defs = [NZCV] in { 2809 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2810 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2811 let Inst{31} = 0; 2812 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2813 } 2814 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2815 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2816 let Inst{31} = 1; 2817 } 2818 } // end Defs = [NZCV] 2819 2820 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2821 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2822 logical_imm32_not:$imm), 0>; 2823 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2824 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2825 logical_imm64_not:$imm), 0>; 2826} 2827 2828class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2829 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2830 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2831 Sched<[WriteI, ReadI, ReadI]>; 2832 2833// Split from LogicalImm as not all instructions have both. 2834multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2835 SDPatternOperator OpNode> { 2836 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2837 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2838 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2839 } 2840 2841 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2842 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2843 logical_shifted_reg32:$Rm))]> { 2844 let Inst{31} = 0; 2845 } 2846 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2847 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2848 logical_shifted_reg64:$Rm))]> { 2849 let Inst{31} = 1; 2850 } 2851 2852 def : LogicalRegAlias<mnemonic, 2853 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2854 def : LogicalRegAlias<mnemonic, 2855 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2856} 2857 2858// Split from LogicalReg to allow setting NZCV Defs 2859multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2860 SDPatternOperator OpNode = null_frag> { 2861 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2862 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2863 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2864 2865 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2866 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2867 let Inst{31} = 0; 2868 } 2869 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2870 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2871 let Inst{31} = 1; 2872 } 2873 } // Defs = [NZCV] 2874 2875 def : LogicalRegAlias<mnemonic, 2876 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2877 def : LogicalRegAlias<mnemonic, 2878 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2879} 2880 2881//--- 2882// Conditionally set flags 2883//--- 2884 2885let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2886class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2887 string mnemonic, SDNode OpNode> 2888 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2889 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2890 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2891 (i32 imm:$cond), NZCV))]>, 2892 Sched<[WriteI, ReadI]> { 2893 let Uses = [NZCV]; 2894 let Defs = [NZCV]; 2895 2896 bits<5> Rn; 2897 bits<5> imm; 2898 bits<4> nzcv; 2899 bits<4> cond; 2900 2901 let Inst{30} = op; 2902 let Inst{29-21} = 0b111010010; 2903 let Inst{20-16} = imm; 2904 let Inst{15-12} = cond; 2905 let Inst{11-10} = 0b10; 2906 let Inst{9-5} = Rn; 2907 let Inst{4} = 0b0; 2908 let Inst{3-0} = nzcv; 2909} 2910 2911let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2912class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2913 SDNode OpNode> 2914 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2915 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2916 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2917 (i32 imm:$cond), NZCV))]>, 2918 Sched<[WriteI, ReadI, ReadI]> { 2919 let Uses = [NZCV]; 2920 let Defs = [NZCV]; 2921 2922 bits<5> Rn; 2923 bits<5> Rm; 2924 bits<4> nzcv; 2925 bits<4> cond; 2926 2927 let Inst{30} = op; 2928 let Inst{29-21} = 0b111010010; 2929 let Inst{20-16} = Rm; 2930 let Inst{15-12} = cond; 2931 let Inst{11-10} = 0b00; 2932 let Inst{9-5} = Rn; 2933 let Inst{4} = 0b0; 2934 let Inst{3-0} = nzcv; 2935} 2936 2937multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2938 // immediate operand variants 2939 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2940 let Inst{31} = 0; 2941 } 2942 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2943 let Inst{31} = 1; 2944 } 2945 // register operand variants 2946 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2947 let Inst{31} = 0; 2948 } 2949 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2950 let Inst{31} = 1; 2951 } 2952} 2953 2954//--- 2955// Conditional select 2956//--- 2957 2958class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2959 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2960 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2961 [(set regtype:$Rd, 2962 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2963 Sched<[WriteI, ReadI, ReadI]> { 2964 let Uses = [NZCV]; 2965 2966 bits<5> Rd; 2967 bits<5> Rn; 2968 bits<5> Rm; 2969 bits<4> cond; 2970 2971 let Inst{30} = op; 2972 let Inst{29-21} = 0b011010100; 2973 let Inst{20-16} = Rm; 2974 let Inst{15-12} = cond; 2975 let Inst{11-10} = op2; 2976 let Inst{9-5} = Rn; 2977 let Inst{4-0} = Rd; 2978} 2979 2980multiclass CondSelect<bit op, bits<2> op2, string asm> { 2981 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2982 let Inst{31} = 0; 2983 } 2984 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 2985 let Inst{31} = 1; 2986 } 2987} 2988 2989class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 2990 PatFrag frag> 2991 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2992 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2993 [(set regtype:$Rd, 2994 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 2995 (i32 imm:$cond), NZCV))]>, 2996 Sched<[WriteI, ReadI, ReadI]> { 2997 let Uses = [NZCV]; 2998 2999 bits<5> Rd; 3000 bits<5> Rn; 3001 bits<5> Rm; 3002 bits<4> cond; 3003 3004 let Inst{30} = op; 3005 let Inst{29-21} = 0b011010100; 3006 let Inst{20-16} = Rm; 3007 let Inst{15-12} = cond; 3008 let Inst{11-10} = op2; 3009 let Inst{9-5} = Rn; 3010 let Inst{4-0} = Rd; 3011} 3012 3013def inv_cond_XFORM : SDNodeXForm<imm, [{ 3014 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3015 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3016 MVT::i32); 3017}]>; 3018 3019multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3020 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3021 let Inst{31} = 0; 3022 } 3023 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3024 let Inst{31} = 1; 3025 } 3026 3027 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3028 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3029 (inv_cond_XFORM imm:$cond))>; 3030 3031 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3032 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3033 (inv_cond_XFORM imm:$cond))>; 3034} 3035 3036//--- 3037// Special Mask Value 3038//--- 3039def maski8_or_more : Operand<i32>, 3040 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3041} 3042def maski16_or_more : Operand<i32>, 3043 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3044} 3045 3046 3047//--- 3048// Load/store 3049//--- 3050 3051// (unsigned immediate) 3052// Indexed for 8-bit registers. offset is in range [0,4095]. 3053def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 3054def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 3055def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 3056def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 3057def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 3058 3059def gi_am_indexed8 : 3060 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3061 GIComplexPatternEquiv<am_indexed8>; 3062def gi_am_indexed16 : 3063 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3064 GIComplexPatternEquiv<am_indexed16>; 3065def gi_am_indexed32 : 3066 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3067 GIComplexPatternEquiv<am_indexed32>; 3068def gi_am_indexed64 : 3069 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3070 GIComplexPatternEquiv<am_indexed64>; 3071def gi_am_indexed128 : 3072 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3073 GIComplexPatternEquiv<am_indexed128>; 3074 3075class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3076 let Name = "UImm12Offset" # Scale; 3077 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3078 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3079 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3080} 3081 3082def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3083def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3084def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3085def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3086def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3087 3088class uimm12_scaled<int Scale> : Operand<i64> { 3089 let ParserMatchClass 3090 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3091 let EncoderMethod 3092 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3093 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3094} 3095 3096def uimm12s1 : uimm12_scaled<1>; 3097def uimm12s2 : uimm12_scaled<2>; 3098def uimm12s4 : uimm12_scaled<4>; 3099def uimm12s8 : uimm12_scaled<8>; 3100def uimm12s16 : uimm12_scaled<16>; 3101 3102class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3103 string asm, list<dag> pattern> 3104 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3105 bits<5> Rt; 3106 3107 bits<5> Rn; 3108 bits<12> offset; 3109 3110 let Inst{31-30} = sz; 3111 let Inst{29-27} = 0b111; 3112 let Inst{26} = V; 3113 let Inst{25-24} = 0b01; 3114 let Inst{23-22} = opc; 3115 let Inst{21-10} = offset; 3116 let Inst{9-5} = Rn; 3117 let Inst{4-0} = Rt; 3118 3119 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3120} 3121 3122multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3123 Operand indextype, string asm, list<dag> pattern> { 3124 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3125 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3126 (ins GPR64sp:$Rn, indextype:$offset), 3127 asm, pattern>, 3128 Sched<[WriteLD]>; 3129 3130 def : InstAlias<asm # "\t$Rt, [$Rn]", 3131 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3132} 3133 3134multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3135 Operand indextype, string asm, list<dag> pattern> { 3136 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3137 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3138 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3139 asm, pattern>, 3140 Sched<[WriteST]>; 3141 3142 def : InstAlias<asm # "\t$Rt, [$Rn]", 3143 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3144} 3145 3146// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3147// substitute zero-registers automatically. 3148// 3149// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3150// into StoreUI. 3151multiclass StoreUIz<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 3163def PrefetchOperand : AsmOperandClass { 3164 let Name = "Prefetch"; 3165 let ParserMethod = "tryParsePrefetch"; 3166} 3167def prfop : Operand<i32> { 3168 let PrintMethod = "printPrefetchOp"; 3169 let ParserMatchClass = PrefetchOperand; 3170} 3171 3172let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3173class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3174 : BaseLoadStoreUI<sz, V, opc, 3175 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3176 asm, pat>, 3177 Sched<[WriteLD]>; 3178 3179//--- 3180// Load literal 3181//--- 3182 3183// Load literal address: 19-bit immediate. The low two bits of the target 3184// offset are implied zero and so are not part of the immediate. 3185def am_ldrlit : Operand<iPTR> { 3186 let EncoderMethod = "getLoadLiteralOpValue"; 3187 let DecoderMethod = "DecodePCRelLabel19"; 3188 let PrintMethod = "printAlignedLabel"; 3189 let ParserMatchClass = PCRelLabel19Operand; 3190 let OperandType = "OPERAND_PCREL"; 3191} 3192 3193let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3194class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3195 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3196 asm, "\t$Rt, $label", "", pat>, 3197 Sched<[WriteLD]> { 3198 bits<5> Rt; 3199 bits<19> label; 3200 let Inst{31-30} = opc; 3201 let Inst{29-27} = 0b011; 3202 let Inst{26} = V; 3203 let Inst{25-24} = 0b00; 3204 let Inst{23-5} = label; 3205 let Inst{4-0} = Rt; 3206} 3207 3208let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3209class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3210 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3211 asm, "\t$Rt, $label", "", pat>, 3212 Sched<[WriteLD]> { 3213 bits<5> Rt; 3214 bits<19> label; 3215 let Inst{31-30} = opc; 3216 let Inst{29-27} = 0b011; 3217 let Inst{26} = V; 3218 let Inst{25-24} = 0b00; 3219 let Inst{23-5} = label; 3220 let Inst{4-0} = Rt; 3221} 3222 3223//--- 3224// Load/store register offset 3225//--- 3226 3227def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3228def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3229def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3230def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3231def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3232 3233def gi_ro_Xindexed8 : 3234 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3235 GIComplexPatternEquiv<ro_Xindexed8>; 3236def gi_ro_Xindexed16 : 3237 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3238 GIComplexPatternEquiv<ro_Xindexed16>; 3239def gi_ro_Xindexed32 : 3240 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3241 GIComplexPatternEquiv<ro_Xindexed32>; 3242def gi_ro_Xindexed64 : 3243 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3244 GIComplexPatternEquiv<ro_Xindexed64>; 3245def gi_ro_Xindexed128 : 3246 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3247 GIComplexPatternEquiv<ro_Xindexed128>; 3248 3249def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3250def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3251def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3252def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3253def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3254 3255def gi_ro_Windexed8 : 3256 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3257 GIComplexPatternEquiv<ro_Windexed8>; 3258def gi_ro_Windexed16 : 3259 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3260 GIComplexPatternEquiv<ro_Windexed16>; 3261def gi_ro_Windexed32 : 3262 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3263 GIComplexPatternEquiv<ro_Windexed32>; 3264def gi_ro_Windexed64 : 3265 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3266 GIComplexPatternEquiv<ro_Windexed64>; 3267def gi_ro_Windexed128 : 3268 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3269 GIComplexPatternEquiv<ro_Windexed128>; 3270 3271class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3272 let Name = "Mem" # Reg # "Extend" # Width; 3273 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3274 let RenderMethod = "addMemExtendOperands"; 3275 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3276} 3277 3278def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3279 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3280 // the trivial shift. 3281 let RenderMethod = "addMemExtend8Operands"; 3282} 3283def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3284def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3285def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3286def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3287 3288def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3289 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3290 // the trivial shift. 3291 let RenderMethod = "addMemExtend8Operands"; 3292} 3293def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3294def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3295def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3296def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3297 3298class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3299 : Operand<i32> { 3300 let ParserMatchClass = ParserClass; 3301 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3302 let DecoderMethod = "DecodeMemExtend"; 3303 let EncoderMethod = "getMemExtendOpValue"; 3304 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3305} 3306 3307def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3308def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3309def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3310def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3311def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3312 3313def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3314def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3315def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3316def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3317def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3318 3319class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3320 Operand wextend, Operand xextend> { 3321 // CodeGen-level pattern covering the entire addressing mode. 3322 ComplexPattern Wpat = windex; 3323 ComplexPattern Xpat = xindex; 3324 3325 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3326 Operand Wext = wextend; 3327 Operand Xext = xextend; 3328} 3329 3330def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3331def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3332def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3333def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3334def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3335 ro_Xextend128>; 3336 3337class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3338 string asm, dag ins, dag outs, list<dag> pat> 3339 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3340 bits<5> Rt; 3341 bits<5> Rn; 3342 bits<5> Rm; 3343 bits<2> extend; 3344 let Inst{31-30} = sz; 3345 let Inst{29-27} = 0b111; 3346 let Inst{26} = V; 3347 let Inst{25-24} = 0b00; 3348 let Inst{23-22} = opc; 3349 let Inst{21} = 1; 3350 let Inst{20-16} = Rm; 3351 let Inst{15} = extend{1}; // sign extend Rm? 3352 let Inst{14} = 1; 3353 let Inst{12} = extend{0}; // do shift? 3354 let Inst{11-10} = 0b10; 3355 let Inst{9-5} = Rn; 3356 let Inst{4-0} = Rt; 3357} 3358 3359class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST> 3360 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3361 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3362 3363multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3364 string asm, ValueType Ty, SDPatternOperator loadop> { 3365 let AddedComplexity = 10 in 3366 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3367 (outs regtype:$Rt), 3368 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3369 [(set (Ty regtype:$Rt), 3370 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3371 ro_Wextend8:$extend)))]>, 3372 Sched<[WriteLDIdx, ReadAdrBase]> { 3373 let Inst{13} = 0b0; 3374 } 3375 3376 let AddedComplexity = 10 in 3377 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3378 (outs regtype:$Rt), 3379 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3380 [(set (Ty regtype:$Rt), 3381 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3382 ro_Xextend8:$extend)))]>, 3383 Sched<[WriteLDIdx, ReadAdrBase]> { 3384 let Inst{13} = 0b1; 3385 } 3386 3387 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3388} 3389 3390multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3391 string asm, ValueType Ty, SDPatternOperator storeop> { 3392 let AddedComplexity = 10 in 3393 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3394 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3395 [(storeop (Ty regtype:$Rt), 3396 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3397 ro_Wextend8:$extend))]>, 3398 Sched<[WriteSTIdx, ReadAdrBase]> { 3399 let Inst{13} = 0b0; 3400 } 3401 3402 let AddedComplexity = 10 in 3403 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3404 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3405 [(storeop (Ty regtype:$Rt), 3406 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3407 ro_Xextend8:$extend))]>, 3408 Sched<[WriteSTIdx, ReadAdrBase]> { 3409 let Inst{13} = 0b1; 3410 } 3411 3412 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3413} 3414 3415class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3416 string asm, dag ins, dag outs, list<dag> pat> 3417 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3418 bits<5> Rt; 3419 bits<5> Rn; 3420 bits<5> Rm; 3421 bits<2> extend; 3422 let Inst{31-30} = sz; 3423 let Inst{29-27} = 0b111; 3424 let Inst{26} = V; 3425 let Inst{25-24} = 0b00; 3426 let Inst{23-22} = opc; 3427 let Inst{21} = 1; 3428 let Inst{20-16} = Rm; 3429 let Inst{15} = extend{1}; // sign extend Rm? 3430 let Inst{14} = 1; 3431 let Inst{12} = extend{0}; // do shift? 3432 let Inst{11-10} = 0b10; 3433 let Inst{9-5} = Rn; 3434 let Inst{4-0} = Rt; 3435} 3436 3437multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3438 string asm, ValueType Ty, SDPatternOperator loadop> { 3439 let AddedComplexity = 10 in 3440 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3441 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3442 [(set (Ty regtype:$Rt), 3443 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3444 ro_Wextend16:$extend)))]>, 3445 Sched<[WriteLDIdx, ReadAdrBase]> { 3446 let Inst{13} = 0b0; 3447 } 3448 3449 let AddedComplexity = 10 in 3450 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3451 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3452 [(set (Ty regtype:$Rt), 3453 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3454 ro_Xextend16:$extend)))]>, 3455 Sched<[WriteLDIdx, ReadAdrBase]> { 3456 let Inst{13} = 0b1; 3457 } 3458 3459 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3460} 3461 3462multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3463 string asm, ValueType Ty, SDPatternOperator storeop> { 3464 let AddedComplexity = 10 in 3465 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3466 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3467 [(storeop (Ty regtype:$Rt), 3468 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3469 ro_Wextend16:$extend))]>, 3470 Sched<[WriteSTIdx, ReadAdrBase]> { 3471 let Inst{13} = 0b0; 3472 } 3473 3474 let AddedComplexity = 10 in 3475 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3476 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3477 [(storeop (Ty regtype:$Rt), 3478 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3479 ro_Xextend16:$extend))]>, 3480 Sched<[WriteSTIdx, ReadAdrBase]> { 3481 let Inst{13} = 0b1; 3482 } 3483 3484 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3485} 3486 3487class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3488 string asm, dag ins, dag outs, list<dag> pat> 3489 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3490 bits<5> Rt; 3491 bits<5> Rn; 3492 bits<5> Rm; 3493 bits<2> extend; 3494 let Inst{31-30} = sz; 3495 let Inst{29-27} = 0b111; 3496 let Inst{26} = V; 3497 let Inst{25-24} = 0b00; 3498 let Inst{23-22} = opc; 3499 let Inst{21} = 1; 3500 let Inst{20-16} = Rm; 3501 let Inst{15} = extend{1}; // sign extend Rm? 3502 let Inst{14} = 1; 3503 let Inst{12} = extend{0}; // do shift? 3504 let Inst{11-10} = 0b10; 3505 let Inst{9-5} = Rn; 3506 let Inst{4-0} = Rt; 3507} 3508 3509multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3510 string asm, ValueType Ty, SDPatternOperator loadop> { 3511 let AddedComplexity = 10 in 3512 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3513 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3514 [(set (Ty regtype:$Rt), 3515 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3516 ro_Wextend32:$extend)))]>, 3517 Sched<[WriteLDIdx, ReadAdrBase]> { 3518 let Inst{13} = 0b0; 3519 } 3520 3521 let AddedComplexity = 10 in 3522 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3523 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3524 [(set (Ty regtype:$Rt), 3525 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3526 ro_Xextend32:$extend)))]>, 3527 Sched<[WriteLDIdx, ReadAdrBase]> { 3528 let Inst{13} = 0b1; 3529 } 3530 3531 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3532} 3533 3534multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3535 string asm, ValueType Ty, SDPatternOperator storeop> { 3536 let AddedComplexity = 10 in 3537 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3538 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3539 [(storeop (Ty regtype:$Rt), 3540 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3541 ro_Wextend32:$extend))]>, 3542 Sched<[WriteSTIdx, ReadAdrBase]> { 3543 let Inst{13} = 0b0; 3544 } 3545 3546 let AddedComplexity = 10 in 3547 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3548 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3549 [(storeop (Ty regtype:$Rt), 3550 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3551 ro_Xextend32:$extend))]>, 3552 Sched<[WriteSTIdx, ReadAdrBase]> { 3553 let Inst{13} = 0b1; 3554 } 3555 3556 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3557} 3558 3559class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3560 string asm, dag ins, dag outs, list<dag> pat> 3561 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3562 bits<5> Rt; 3563 bits<5> Rn; 3564 bits<5> Rm; 3565 bits<2> extend; 3566 let Inst{31-30} = sz; 3567 let Inst{29-27} = 0b111; 3568 let Inst{26} = V; 3569 let Inst{25-24} = 0b00; 3570 let Inst{23-22} = opc; 3571 let Inst{21} = 1; 3572 let Inst{20-16} = Rm; 3573 let Inst{15} = extend{1}; // sign extend Rm? 3574 let Inst{14} = 1; 3575 let Inst{12} = extend{0}; // do shift? 3576 let Inst{11-10} = 0b10; 3577 let Inst{9-5} = Rn; 3578 let Inst{4-0} = Rt; 3579} 3580 3581multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3582 string asm, ValueType Ty, SDPatternOperator loadop> { 3583 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3584 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3585 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3586 [(set (Ty regtype:$Rt), 3587 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3588 ro_Wextend64:$extend)))]>, 3589 Sched<[WriteLDIdx, ReadAdrBase]> { 3590 let Inst{13} = 0b0; 3591 } 3592 3593 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3594 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3595 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3596 [(set (Ty regtype:$Rt), 3597 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3598 ro_Xextend64:$extend)))]>, 3599 Sched<[WriteLDIdx, ReadAdrBase]> { 3600 let Inst{13} = 0b1; 3601 } 3602 3603 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3604} 3605 3606multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3607 string asm, ValueType Ty, SDPatternOperator storeop> { 3608 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3609 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3610 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3611 [(storeop (Ty regtype:$Rt), 3612 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3613 ro_Wextend64:$extend))]>, 3614 Sched<[WriteSTIdx, ReadAdrBase]> { 3615 let Inst{13} = 0b0; 3616 } 3617 3618 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3619 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3620 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3621 [(storeop (Ty regtype:$Rt), 3622 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3623 ro_Xextend64:$extend))]>, 3624 Sched<[WriteSTIdx, ReadAdrBase]> { 3625 let Inst{13} = 0b1; 3626 } 3627 3628 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3629} 3630 3631class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3632 string asm, dag ins, dag outs, list<dag> pat> 3633 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3634 bits<5> Rt; 3635 bits<5> Rn; 3636 bits<5> Rm; 3637 bits<2> extend; 3638 let Inst{31-30} = sz; 3639 let Inst{29-27} = 0b111; 3640 let Inst{26} = V; 3641 let Inst{25-24} = 0b00; 3642 let Inst{23-22} = opc; 3643 let Inst{21} = 1; 3644 let Inst{20-16} = Rm; 3645 let Inst{15} = extend{1}; // sign extend Rm? 3646 let Inst{14} = 1; 3647 let Inst{12} = extend{0}; // do shift? 3648 let Inst{11-10} = 0b10; 3649 let Inst{9-5} = Rn; 3650 let Inst{4-0} = Rt; 3651} 3652 3653multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3654 string asm, ValueType Ty, SDPatternOperator loadop> { 3655 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3656 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3657 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3658 [(set (Ty regtype:$Rt), 3659 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3660 ro_Wextend128:$extend)))]>, 3661 Sched<[WriteLDIdx, ReadAdrBase]> { 3662 let Inst{13} = 0b0; 3663 } 3664 3665 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3666 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3667 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3668 [(set (Ty regtype:$Rt), 3669 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3670 ro_Xextend128:$extend)))]>, 3671 Sched<[WriteLDIdx, ReadAdrBase]> { 3672 let Inst{13} = 0b1; 3673 } 3674 3675 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3676} 3677 3678multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3679 string asm, ValueType Ty, SDPatternOperator storeop> { 3680 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3681 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3682 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3683 []>, 3684 Sched<[WriteSTIdx, ReadAdrBase]> { 3685 let Inst{13} = 0b0; 3686 } 3687 3688 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3689 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3690 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3691 []>, 3692 Sched<[WriteSTIdx, ReadAdrBase]> { 3693 let Inst{13} = 0b1; 3694 } 3695 3696 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3697} 3698 3699let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3700class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3701 string asm, list<dag> pat> 3702 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3703 Sched<[WriteLD]> { 3704 bits<5> Rt; 3705 bits<5> Rn; 3706 bits<5> Rm; 3707 bits<2> extend; 3708 let Inst{31-30} = sz; 3709 let Inst{29-27} = 0b111; 3710 let Inst{26} = V; 3711 let Inst{25-24} = 0b00; 3712 let Inst{23-22} = opc; 3713 let Inst{21} = 1; 3714 let Inst{20-16} = Rm; 3715 let Inst{15} = extend{1}; // sign extend Rm? 3716 let Inst{14} = 1; 3717 let Inst{12} = extend{0}; // do shift? 3718 let Inst{11-10} = 0b10; 3719 let Inst{9-5} = Rn; 3720 let Inst{4-0} = Rt; 3721} 3722 3723multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3724 def roW : BasePrefetchRO<sz, V, opc, (outs), 3725 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3726 asm, [(AArch64Prefetch imm:$Rt, 3727 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3728 ro_Wextend64:$extend))]> { 3729 let Inst{13} = 0b0; 3730 } 3731 3732 def roX : BasePrefetchRO<sz, V, opc, (outs), 3733 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3734 asm, [(AArch64Prefetch imm:$Rt, 3735 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3736 ro_Xextend64:$extend))]> { 3737 let Inst{13} = 0b1; 3738 } 3739 3740 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3741 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3742 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3743} 3744 3745//--- 3746// Load/store unscaled immediate 3747//--- 3748 3749def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3750def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3751def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3752def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3753def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3754 3755def gi_am_unscaled8 : 3756 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3757 GIComplexPatternEquiv<am_unscaled8>; 3758def gi_am_unscaled16 : 3759 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3760 GIComplexPatternEquiv<am_unscaled16>; 3761def gi_am_unscaled32 : 3762 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3763 GIComplexPatternEquiv<am_unscaled32>; 3764def gi_am_unscaled64 : 3765 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3766 GIComplexPatternEquiv<am_unscaled64>; 3767def gi_am_unscaled128 : 3768 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3769 GIComplexPatternEquiv<am_unscaled128>; 3770 3771 3772class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3773 string asm, list<dag> pattern> 3774 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3775 bits<5> Rt; 3776 bits<5> Rn; 3777 bits<9> offset; 3778 let Inst{31-30} = sz; 3779 let Inst{29-27} = 0b111; 3780 let Inst{26} = V; 3781 let Inst{25-24} = 0b00; 3782 let Inst{23-22} = opc; 3783 let Inst{21} = 0; 3784 let Inst{20-12} = offset; 3785 let Inst{11-10} = 0b00; 3786 let Inst{9-5} = Rn; 3787 let Inst{4-0} = Rt; 3788 3789 let DecoderMethod = "DecodeSignedLdStInstruction"; 3790} 3791 3792// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3793multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3794 RegisterOperand regtype > { 3795 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3796 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3797 Sched<[WriteST]> { 3798 let Inst{29} = 0; 3799 let Inst{24} = 1; 3800 } 3801 def : InstAlias<asm # "\t$Rt, [$Rn]", 3802 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3803} 3804 3805multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3806 RegisterOperand regtype > { 3807 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3808 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3809 asm, []>, 3810 Sched<[WriteST]> { 3811 let Inst{29} = 0; 3812 let Inst{24} = 1; 3813 } 3814 def : InstAlias<asm # "\t$Rt, [$Rn]", 3815 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3816} 3817 3818multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3819 string asm, list<dag> pattern> { 3820 let AddedComplexity = 1 in // try this before LoadUI 3821 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3822 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3823 Sched<[WriteLD]>; 3824 3825 def : InstAlias<asm # "\t$Rt, [$Rn]", 3826 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3827} 3828 3829multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3830 string asm, list<dag> pattern> { 3831 let AddedComplexity = 1 in // try this before StoreUI 3832 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3833 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3834 asm, pattern>, 3835 Sched<[WriteST]>; 3836 3837 def : InstAlias<asm # "\t$Rt, [$Rn]", 3838 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3839} 3840 3841multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3842 list<dag> pat> { 3843 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3844 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3845 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3846 asm, pat>, 3847 Sched<[WriteLD]>; 3848 3849 def : InstAlias<asm # "\t$Rt, [$Rn]", 3850 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3851} 3852 3853//--- 3854// Load/store unscaled immediate, unprivileged 3855//--- 3856 3857class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3858 dag oops, dag iops, string asm> 3859 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3860 bits<5> Rt; 3861 bits<5> Rn; 3862 bits<9> offset; 3863 let Inst{31-30} = sz; 3864 let Inst{29-27} = 0b111; 3865 let Inst{26} = V; 3866 let Inst{25-24} = 0b00; 3867 let Inst{23-22} = opc; 3868 let Inst{21} = 0; 3869 let Inst{20-12} = offset; 3870 let Inst{11-10} = 0b10; 3871 let Inst{9-5} = Rn; 3872 let Inst{4-0} = Rt; 3873 3874 let DecoderMethod = "DecodeSignedLdStInstruction"; 3875} 3876 3877multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3878 RegisterClass regtype, string asm> { 3879 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3880 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3881 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3882 Sched<[WriteLD]>; 3883 3884 def : InstAlias<asm # "\t$Rt, [$Rn]", 3885 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3886} 3887 3888multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3889 RegisterClass regtype, string asm> { 3890 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3891 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3892 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3893 asm>, 3894 Sched<[WriteST]>; 3895 3896 def : InstAlias<asm # "\t$Rt, [$Rn]", 3897 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3898} 3899 3900//--- 3901// Load/store pre-indexed 3902//--- 3903 3904class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3905 string asm, string cstr, list<dag> pat> 3906 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3907 bits<5> Rt; 3908 bits<5> Rn; 3909 bits<9> offset; 3910 let Inst{31-30} = sz; 3911 let Inst{29-27} = 0b111; 3912 let Inst{26} = V; 3913 let Inst{25-24} = 0; 3914 let Inst{23-22} = opc; 3915 let Inst{21} = 0; 3916 let Inst{20-12} = offset; 3917 let Inst{11-10} = 0b11; 3918 let Inst{9-5} = Rn; 3919 let Inst{4-0} = Rt; 3920 3921 let DecoderMethod = "DecodeSignedLdStInstruction"; 3922} 3923 3924let hasSideEffects = 0 in { 3925let mayStore = 0, mayLoad = 1 in 3926class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3927 string asm> 3928 : BaseLoadStorePreIdx<sz, V, opc, 3929 (outs GPR64sp:$wback, regtype:$Rt), 3930 (ins GPR64sp:$Rn, simm9:$offset), asm, 3931 "$Rn = $wback,@earlyclobber $wback", []>, 3932 Sched<[WriteLD, WriteAdr]>; 3933 3934let mayStore = 1, mayLoad = 0 in 3935class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3936 string asm, SDPatternOperator storeop, ValueType Ty> 3937 : BaseLoadStorePreIdx<sz, V, opc, 3938 (outs GPR64sp:$wback), 3939 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3940 asm, "$Rn = $wback,@earlyclobber $wback", 3941 [(set GPR64sp:$wback, 3942 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3943 Sched<[WriteAdr, WriteST]>; 3944} // hasSideEffects = 0 3945 3946//--- 3947// Load/store post-indexed 3948//--- 3949 3950class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3951 string asm, string cstr, list<dag> pat> 3952 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3953 bits<5> Rt; 3954 bits<5> Rn; 3955 bits<9> offset; 3956 let Inst{31-30} = sz; 3957 let Inst{29-27} = 0b111; 3958 let Inst{26} = V; 3959 let Inst{25-24} = 0b00; 3960 let Inst{23-22} = opc; 3961 let Inst{21} = 0b0; 3962 let Inst{20-12} = offset; 3963 let Inst{11-10} = 0b01; 3964 let Inst{9-5} = Rn; 3965 let Inst{4-0} = Rt; 3966 3967 let DecoderMethod = "DecodeSignedLdStInstruction"; 3968} 3969 3970let hasSideEffects = 0 in { 3971let mayStore = 0, mayLoad = 1 in 3972class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3973 string asm> 3974 : BaseLoadStorePostIdx<sz, V, opc, 3975 (outs GPR64sp:$wback, regtype:$Rt), 3976 (ins GPR64sp:$Rn, simm9:$offset), 3977 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3978 Sched<[WriteLD, WriteAdr]>; 3979 3980let mayStore = 1, mayLoad = 0 in 3981class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3982 string asm, SDPatternOperator storeop, ValueType Ty> 3983 : BaseLoadStorePostIdx<sz, V, opc, 3984 (outs GPR64sp:$wback), 3985 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3986 asm, "$Rn = $wback,@earlyclobber $wback", 3987 [(set GPR64sp:$wback, 3988 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3989 Sched<[WriteAdr, WriteST]>; 3990} // hasSideEffects = 0 3991 3992 3993//--- 3994// Load/store pair 3995//--- 3996 3997// (indexed, offset) 3998 3999class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4000 string asm> 4001 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4002 bits<5> Rt; 4003 bits<5> Rt2; 4004 bits<5> Rn; 4005 bits<7> offset; 4006 let Inst{31-30} = opc; 4007 let Inst{29-27} = 0b101; 4008 let Inst{26} = V; 4009 let Inst{25-23} = 0b010; 4010 let Inst{22} = L; 4011 let Inst{21-15} = offset; 4012 let Inst{14-10} = Rt2; 4013 let Inst{9-5} = Rn; 4014 let Inst{4-0} = Rt; 4015 4016 let DecoderMethod = "DecodePairLdStInstruction"; 4017} 4018 4019multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4020 Operand indextype, string asm> { 4021 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4022 def i : BaseLoadStorePairOffset<opc, V, 1, 4023 (outs regtype:$Rt, regtype:$Rt2), 4024 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4025 Sched<[WriteLD, WriteLDHi]>; 4026 4027 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4028 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4029 GPR64sp:$Rn, 0)>; 4030} 4031 4032 4033multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4034 Operand indextype, string asm> { 4035 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4036 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4037 (ins regtype:$Rt, regtype:$Rt2, 4038 GPR64sp:$Rn, indextype:$offset), 4039 asm>, 4040 Sched<[WriteSTP]>; 4041 4042 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4043 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4044 GPR64sp:$Rn, 0)>; 4045} 4046 4047// (pre-indexed) 4048class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4049 string asm> 4050 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4051 bits<5> Rt; 4052 bits<5> Rt2; 4053 bits<5> Rn; 4054 bits<7> offset; 4055 let Inst{31-30} = opc; 4056 let Inst{29-27} = 0b101; 4057 let Inst{26} = V; 4058 let Inst{25-23} = 0b011; 4059 let Inst{22} = L; 4060 let Inst{21-15} = offset; 4061 let Inst{14-10} = Rt2; 4062 let Inst{9-5} = Rn; 4063 let Inst{4-0} = Rt; 4064 4065 let DecoderMethod = "DecodePairLdStInstruction"; 4066} 4067 4068let hasSideEffects = 0 in { 4069let mayStore = 0, mayLoad = 1 in 4070class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4071 Operand indextype, string asm> 4072 : BaseLoadStorePairPreIdx<opc, V, 1, 4073 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4074 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4075 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 4076 4077let mayStore = 1, mayLoad = 0 in 4078class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4079 Operand indextype, string asm> 4080 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4081 (ins regtype:$Rt, regtype:$Rt2, 4082 GPR64sp:$Rn, indextype:$offset), 4083 asm>, 4084 Sched<[WriteAdr, WriteSTP]>; 4085} // hasSideEffects = 0 4086 4087// (post-indexed) 4088 4089class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4090 string asm> 4091 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4092 bits<5> Rt; 4093 bits<5> Rt2; 4094 bits<5> Rn; 4095 bits<7> offset; 4096 let Inst{31-30} = opc; 4097 let Inst{29-27} = 0b101; 4098 let Inst{26} = V; 4099 let Inst{25-23} = 0b001; 4100 let Inst{22} = L; 4101 let Inst{21-15} = offset; 4102 let Inst{14-10} = Rt2; 4103 let Inst{9-5} = Rn; 4104 let Inst{4-0} = Rt; 4105 4106 let DecoderMethod = "DecodePairLdStInstruction"; 4107} 4108 4109let hasSideEffects = 0 in { 4110let mayStore = 0, mayLoad = 1 in 4111class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4112 Operand idxtype, string asm> 4113 : BaseLoadStorePairPostIdx<opc, V, 1, 4114 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4115 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4116 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 4117 4118let mayStore = 1, mayLoad = 0 in 4119class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4120 Operand idxtype, string asm> 4121 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4122 (ins regtype:$Rt, regtype:$Rt2, 4123 GPR64sp:$Rn, idxtype:$offset), 4124 asm>, 4125 Sched<[WriteAdr, WriteSTP]>; 4126} // hasSideEffects = 0 4127 4128// (no-allocate) 4129 4130class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4131 string asm> 4132 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4133 bits<5> Rt; 4134 bits<5> Rt2; 4135 bits<5> Rn; 4136 bits<7> offset; 4137 let Inst{31-30} = opc; 4138 let Inst{29-27} = 0b101; 4139 let Inst{26} = V; 4140 let Inst{25-23} = 0b000; 4141 let Inst{22} = L; 4142 let Inst{21-15} = offset; 4143 let Inst{14-10} = Rt2; 4144 let Inst{9-5} = Rn; 4145 let Inst{4-0} = Rt; 4146 4147 let DecoderMethod = "DecodePairLdStInstruction"; 4148} 4149 4150multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4151 Operand indextype, string asm> { 4152 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4153 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4154 (outs regtype:$Rt, regtype:$Rt2), 4155 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4156 Sched<[WriteLD, WriteLDHi]>; 4157 4158 4159 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4160 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4161 GPR64sp:$Rn, 0)>; 4162} 4163 4164multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 4165 Operand indextype, string asm> { 4166 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4167 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4168 (ins regtype:$Rt, regtype:$Rt2, 4169 GPR64sp:$Rn, indextype:$offset), 4170 asm>, 4171 Sched<[WriteSTP]>; 4172 4173 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4174 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4175 GPR64sp:$Rn, 0)>; 4176} 4177 4178//--- 4179// Load/store exclusive 4180//--- 4181 4182// True exclusive operations write to and/or read from the system's exclusive 4183// monitors, which as far as a compiler is concerned can be modelled as a 4184// random shared memory address. Hence LoadExclusive mayStore. 4185// 4186// Since these instructions have the undefined register bits set to 1 in 4187// their canonical form, we need a post encoder method to set those bits 4188// to 1 when encoding these instructions. We do this using the 4189// fixLoadStoreExclusive function. This function has template parameters: 4190// 4191// fixLoadStoreExclusive<int hasRs, int hasRt2> 4192// 4193// hasRs indicates that the instruction uses the Rs field, so we won't set 4194// it to 1 (and the same for Rt2). We don't need template parameters for 4195// the other register fields since Rt and Rn are always used. 4196// 4197let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4198class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4199 dag oops, dag iops, string asm, string operands> 4200 : I<oops, iops, asm, operands, "", []> { 4201 let Inst{31-30} = sz; 4202 let Inst{29-24} = 0b001000; 4203 let Inst{23} = o2; 4204 let Inst{22} = L; 4205 let Inst{21} = o1; 4206 let Inst{15} = o0; 4207 4208 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4209} 4210 4211// Neither Rs nor Rt2 operands. 4212class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4213 dag oops, dag iops, string asm, string operands> 4214 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4215 bits<5> Rt; 4216 bits<5> Rn; 4217 let Inst{20-16} = 0b11111; 4218 let Unpredictable{20-16} = 0b11111; 4219 let Inst{14-10} = 0b11111; 4220 let Unpredictable{14-10} = 0b11111; 4221 let Inst{9-5} = Rn; 4222 let Inst{4-0} = Rt; 4223 4224 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4225} 4226 4227// Simple load acquires don't set the exclusive monitor 4228let mayLoad = 1, mayStore = 0 in 4229class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4230 RegisterClass regtype, string asm> 4231 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4232 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4233 Sched<[WriteLD]>; 4234 4235class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4236 RegisterClass regtype, string asm> 4237 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4238 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4239 Sched<[WriteLD]>; 4240 4241class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4242 RegisterClass regtype, string asm> 4243 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4244 (outs regtype:$Rt, regtype:$Rt2), 4245 (ins GPR64sp0:$Rn), asm, 4246 "\t$Rt, $Rt2, [$Rn]">, 4247 Sched<[WriteLD, WriteLDHi]> { 4248 bits<5> Rt; 4249 bits<5> Rt2; 4250 bits<5> Rn; 4251 let Inst{14-10} = Rt2; 4252 let Inst{9-5} = Rn; 4253 let Inst{4-0} = Rt; 4254 4255 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4256} 4257 4258// Simple store release operations do not check the exclusive monitor. 4259let mayLoad = 0, mayStore = 1 in 4260class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4261 RegisterClass regtype, string asm> 4262 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4263 (ins regtype:$Rt, GPR64sp0:$Rn), 4264 asm, "\t$Rt, [$Rn]">, 4265 Sched<[WriteST]>; 4266 4267let mayLoad = 1, mayStore = 1 in 4268class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4269 RegisterClass regtype, string asm> 4270 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4271 (ins regtype:$Rt, GPR64sp0:$Rn), 4272 asm, "\t$Ws, $Rt, [$Rn]">, 4273 Sched<[WriteSTX]> { 4274 bits<5> Ws; 4275 bits<5> Rt; 4276 bits<5> Rn; 4277 let Inst{20-16} = Ws; 4278 let Inst{9-5} = Rn; 4279 let Inst{4-0} = Rt; 4280 4281 let Constraints = "@earlyclobber $Ws"; 4282 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4283} 4284 4285class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4286 RegisterClass regtype, string asm> 4287 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4288 (outs GPR32:$Ws), 4289 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4290 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4291 Sched<[WriteSTX]> { 4292 bits<5> Ws; 4293 bits<5> Rt; 4294 bits<5> Rt2; 4295 bits<5> Rn; 4296 let Inst{20-16} = Ws; 4297 let Inst{14-10} = Rt2; 4298 let Inst{9-5} = Rn; 4299 let Inst{4-0} = Rt; 4300 4301 let Constraints = "@earlyclobber $Ws"; 4302} 4303 4304// Armv8.5-A Memory Tagging Extension 4305class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4306 string asm_opnds, string cstr, dag oops, dag iops> 4307 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4308 Sched<[]> { 4309 bits<5> Rn; 4310 4311 let Inst{31-24} = 0b11011001; 4312 let Inst{23-22} = opc1; 4313 let Inst{21} = 1; 4314 // Inst{20-12} defined by subclass 4315 let Inst{11-10} = opc2; 4316 let Inst{9-5} = Rn; 4317 // Inst{4-0} defined by subclass 4318} 4319 4320class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4321 dag oops, dag iops> 4322 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4323 "", oops, iops> { 4324 bits<5> Rt; 4325 4326 let Inst{20-12} = 0b000000000; 4327 let Inst{4-0} = Rt; 4328 4329 let mayLoad = Load; 4330} 4331 4332class MemTagLoad<string asm_insn, string asm_opnds> 4333 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4334 (outs GPR64:$wback), 4335 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4336 bits<5> Rt; 4337 bits<9> offset; 4338 4339 let Inst{20-12} = offset; 4340 let Inst{4-0} = Rt; 4341 4342 let mayLoad = 1; 4343} 4344 4345class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4346 string asm_opnds, string cstr, dag oops, dag iops> 4347 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4348 bits<5> Rt; 4349 bits<9> offset; 4350 4351 let Inst{20-12} = offset; 4352 let Inst{4-0} = Rt; 4353 4354 let mayStore = 1; 4355} 4356 4357multiclass MemTagStore<bits<2> opc1, string insn> { 4358 def Offset : 4359 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4360 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4361 def PreIndex : 4362 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4363 "$Rn = $wback", 4364 (outs GPR64sp:$wback), 4365 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4366 def PostIndex : 4367 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4368 "$Rn = $wback", 4369 (outs GPR64sp:$wback), 4370 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4371 4372 def : InstAlias<insn # "\t$Rt, [$Rn]", 4373 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4374} 4375 4376//--- 4377// Exception generation 4378//--- 4379 4380let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4381class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4382 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4383 Sched<[WriteSys]> { 4384 bits<16> imm; 4385 let Inst{31-24} = 0b11010100; 4386 let Inst{23-21} = op1; 4387 let Inst{20-5} = imm; 4388 let Inst{4-2} = 0b000; 4389 let Inst{1-0} = ll; 4390} 4391 4392//--- 4393// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4394//-- 4395let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4396class UDFType<bits<16> opc, string asm> 4397 : I<(outs), (ins uimm16:$imm), 4398 asm, "\t$imm", "", []>, 4399 Sched<[]> { 4400 bits<16> imm; 4401 let Inst{31-16} = opc; 4402 let Inst{15-0} = imm; 4403} 4404} 4405let Predicates = [HasFPARMv8] in { 4406 4407//--- 4408// Floating point to integer conversion 4409//--- 4410 4411class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4412 RegisterClass srcType, RegisterClass dstType, 4413 string asm, list<dag> pattern> 4414 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4415 asm, "\t$Rd, $Rn", "", pattern>, 4416 Sched<[WriteFCvt]> { 4417 bits<5> Rd; 4418 bits<5> Rn; 4419 let Inst{30-29} = 0b00; 4420 let Inst{28-24} = 0b11110; 4421 let Inst{23-22} = type; 4422 let Inst{21} = 1; 4423 let Inst{20-19} = rmode; 4424 let Inst{18-16} = opcode; 4425 let Inst{15-10} = 0; 4426 let Inst{9-5} = Rn; 4427 let Inst{4-0} = Rd; 4428} 4429 4430let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4431class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4432 RegisterClass srcType, RegisterClass dstType, 4433 Operand immType, string asm, list<dag> pattern> 4434 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4435 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4436 Sched<[WriteFCvt]> { 4437 bits<5> Rd; 4438 bits<5> Rn; 4439 bits<6> scale; 4440 let Inst{30-29} = 0b00; 4441 let Inst{28-24} = 0b11110; 4442 let Inst{23-22} = type; 4443 let Inst{21} = 0; 4444 let Inst{20-19} = rmode; 4445 let Inst{18-16} = opcode; 4446 let Inst{15-10} = scale; 4447 let Inst{9-5} = Rn; 4448 let Inst{4-0} = Rd; 4449} 4450 4451multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4452 SDPatternOperator OpN> { 4453 // Unscaled half-precision to 32-bit 4454 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4455 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4456 let Inst{31} = 0; // 32-bit GPR flag 4457 let Predicates = [HasFullFP16]; 4458 } 4459 4460 // Unscaled half-precision to 64-bit 4461 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4462 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4463 let Inst{31} = 1; // 64-bit GPR flag 4464 let Predicates = [HasFullFP16]; 4465 } 4466 4467 // Unscaled single-precision to 32-bit 4468 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4469 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4470 let Inst{31} = 0; // 32-bit GPR flag 4471 } 4472 4473 // Unscaled single-precision to 64-bit 4474 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4475 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4476 let Inst{31} = 1; // 64-bit GPR flag 4477 } 4478 4479 // Unscaled double-precision to 32-bit 4480 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4481 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4482 let Inst{31} = 0; // 32-bit GPR flag 4483 } 4484 4485 // Unscaled double-precision to 64-bit 4486 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4487 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4488 let Inst{31} = 1; // 64-bit GPR flag 4489 } 4490} 4491 4492multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4493 SDPatternOperator OpN> { 4494 // Scaled half-precision to 32-bit 4495 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4496 fixedpoint_f16_i32, asm, 4497 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4498 fixedpoint_f16_i32:$scale)))]> { 4499 let Inst{31} = 0; // 32-bit GPR flag 4500 let scale{5} = 1; 4501 let Predicates = [HasFullFP16]; 4502 } 4503 4504 // Scaled half-precision to 64-bit 4505 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4506 fixedpoint_f16_i64, asm, 4507 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4508 fixedpoint_f16_i64:$scale)))]> { 4509 let Inst{31} = 1; // 64-bit GPR flag 4510 let Predicates = [HasFullFP16]; 4511 } 4512 4513 // Scaled single-precision to 32-bit 4514 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4515 fixedpoint_f32_i32, asm, 4516 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4517 fixedpoint_f32_i32:$scale)))]> { 4518 let Inst{31} = 0; // 32-bit GPR flag 4519 let scale{5} = 1; 4520 } 4521 4522 // Scaled single-precision to 64-bit 4523 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4524 fixedpoint_f32_i64, asm, 4525 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4526 fixedpoint_f32_i64:$scale)))]> { 4527 let Inst{31} = 1; // 64-bit GPR flag 4528 } 4529 4530 // Scaled double-precision to 32-bit 4531 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4532 fixedpoint_f64_i32, asm, 4533 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4534 fixedpoint_f64_i32:$scale)))]> { 4535 let Inst{31} = 0; // 32-bit GPR flag 4536 let scale{5} = 1; 4537 } 4538 4539 // Scaled double-precision to 64-bit 4540 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4541 fixedpoint_f64_i64, asm, 4542 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4543 fixedpoint_f64_i64:$scale)))]> { 4544 let Inst{31} = 1; // 64-bit GPR flag 4545 } 4546} 4547 4548//--- 4549// Integer to floating point conversion 4550//--- 4551 4552let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4553class BaseIntegerToFP<bit isUnsigned, 4554 RegisterClass srcType, RegisterClass dstType, 4555 Operand immType, string asm, list<dag> pattern> 4556 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4557 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4558 Sched<[WriteFCvt]> { 4559 bits<5> Rd; 4560 bits<5> Rn; 4561 bits<6> scale; 4562 let Inst{30-24} = 0b0011110; 4563 let Inst{21-17} = 0b00001; 4564 let Inst{16} = isUnsigned; 4565 let Inst{15-10} = scale; 4566 let Inst{9-5} = Rn; 4567 let Inst{4-0} = Rd; 4568} 4569 4570class BaseIntegerToFPUnscaled<bit isUnsigned, 4571 RegisterClass srcType, RegisterClass dstType, 4572 ValueType dvt, string asm, SDNode node> 4573 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4574 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 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} = 0b10001; 4581 let Inst{16} = isUnsigned; 4582 let Inst{15-10} = 0b000000; 4583 let Inst{9-5} = Rn; 4584 let Inst{4-0} = Rd; 4585} 4586 4587multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 4588 // Unscaled 4589 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4590 let Inst{31} = 0; // 32-bit GPR flag 4591 let Inst{23-22} = 0b11; // 16-bit FPR flag 4592 let Predicates = [HasFullFP16]; 4593 } 4594 4595 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4596 let Inst{31} = 0; // 32-bit GPR flag 4597 let Inst{23-22} = 0b00; // 32-bit FPR flag 4598 } 4599 4600 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4601 let Inst{31} = 0; // 32-bit GPR flag 4602 let Inst{23-22} = 0b01; // 64-bit FPR flag 4603 } 4604 4605 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4606 let Inst{31} = 1; // 64-bit GPR flag 4607 let Inst{23-22} = 0b11; // 16-bit FPR flag 4608 let Predicates = [HasFullFP16]; 4609 } 4610 4611 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4612 let Inst{31} = 1; // 64-bit GPR flag 4613 let Inst{23-22} = 0b00; // 32-bit FPR flag 4614 } 4615 4616 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4617 let Inst{31} = 1; // 64-bit GPR flag 4618 let Inst{23-22} = 0b01; // 64-bit FPR flag 4619 } 4620 4621 // Scaled 4622 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4623 [(set (f16 FPR16:$Rd), 4624 (fdiv (node GPR32:$Rn), 4625 fixedpoint_f16_i32:$scale))]> { 4626 let Inst{31} = 0; // 32-bit GPR flag 4627 let Inst{23-22} = 0b11; // 16-bit FPR flag 4628 let scale{5} = 1; 4629 let Predicates = [HasFullFP16]; 4630 } 4631 4632 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4633 [(set FPR32:$Rd, 4634 (fdiv (node GPR32:$Rn), 4635 fixedpoint_f32_i32:$scale))]> { 4636 let Inst{31} = 0; // 32-bit GPR flag 4637 let Inst{23-22} = 0b00; // 32-bit FPR flag 4638 let scale{5} = 1; 4639 } 4640 4641 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4642 [(set FPR64:$Rd, 4643 (fdiv (node GPR32:$Rn), 4644 fixedpoint_f64_i32:$scale))]> { 4645 let Inst{31} = 0; // 32-bit GPR flag 4646 let Inst{23-22} = 0b01; // 64-bit FPR flag 4647 let scale{5} = 1; 4648 } 4649 4650 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4651 [(set (f16 FPR16:$Rd), 4652 (fdiv (node GPR64:$Rn), 4653 fixedpoint_f16_i64:$scale))]> { 4654 let Inst{31} = 1; // 64-bit GPR flag 4655 let Inst{23-22} = 0b11; // 16-bit FPR flag 4656 let Predicates = [HasFullFP16]; 4657 } 4658 4659 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4660 [(set FPR32:$Rd, 4661 (fdiv (node GPR64:$Rn), 4662 fixedpoint_f32_i64:$scale))]> { 4663 let Inst{31} = 1; // 64-bit GPR flag 4664 let Inst{23-22} = 0b00; // 32-bit FPR flag 4665 } 4666 4667 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4668 [(set FPR64:$Rd, 4669 (fdiv (node GPR64:$Rn), 4670 fixedpoint_f64_i64:$scale))]> { 4671 let Inst{31} = 1; // 64-bit GPR flag 4672 let Inst{23-22} = 0b01; // 64-bit FPR flag 4673 } 4674} 4675 4676//--- 4677// Unscaled integer <-> floating point conversion (i.e. FMOV) 4678//--- 4679 4680let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4681class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4682 RegisterClass srcType, RegisterClass dstType, 4683 string asm> 4684 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4685 // We use COPY_TO_REGCLASS for these bitconvert operations. 4686 // copyPhysReg() expands the resultant COPY instructions after 4687 // regalloc is done. This gives greater freedom for the allocator 4688 // and related passes (coalescing, copy propagation, et. al.) to 4689 // be more effective. 4690 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4691 Sched<[WriteFCopy]> { 4692 bits<5> Rd; 4693 bits<5> Rn; 4694 let Inst{30-24} = 0b0011110; 4695 let Inst{21} = 1; 4696 let Inst{20-19} = rmode; 4697 let Inst{18-16} = opcode; 4698 let Inst{15-10} = 0b000000; 4699 let Inst{9-5} = Rn; 4700 let Inst{4-0} = Rd; 4701} 4702 4703let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4704class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4705 RegisterClass srcType, RegisterOperand dstType, string asm, 4706 string kind> 4707 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4708 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4709 Sched<[WriteFCopy]> { 4710 bits<5> Rd; 4711 bits<5> Rn; 4712 let Inst{30-23} = 0b00111101; 4713 let Inst{21} = 1; 4714 let Inst{20-19} = rmode; 4715 let Inst{18-16} = opcode; 4716 let Inst{15-10} = 0b000000; 4717 let Inst{9-5} = Rn; 4718 let Inst{4-0} = Rd; 4719 4720 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4721} 4722 4723let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4724class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4725 RegisterOperand srcType, RegisterClass dstType, string asm, 4726 string kind> 4727 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4728 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4729 Sched<[WriteFCopy]> { 4730 bits<5> Rd; 4731 bits<5> Rn; 4732 let Inst{30-23} = 0b00111101; 4733 let Inst{21} = 1; 4734 let Inst{20-19} = rmode; 4735 let Inst{18-16} = opcode; 4736 let Inst{15-10} = 0b000000; 4737 let Inst{9-5} = Rn; 4738 let Inst{4-0} = Rd; 4739 4740 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4741} 4742 4743 4744multiclass UnscaledConversion<string asm> { 4745 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4746 let Inst{31} = 0; // 32-bit GPR flag 4747 let Inst{23-22} = 0b11; // 16-bit FPR flag 4748 let Predicates = [HasFullFP16]; 4749 } 4750 4751 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4752 let Inst{31} = 1; // 64-bit GPR flag 4753 let Inst{23-22} = 0b11; // 16-bit FPR flag 4754 let Predicates = [HasFullFP16]; 4755 } 4756 4757 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4758 let Inst{31} = 0; // 32-bit GPR flag 4759 let Inst{23-22} = 0b00; // 32-bit FPR flag 4760 } 4761 4762 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4763 let Inst{31} = 1; // 64-bit GPR flag 4764 let Inst{23-22} = 0b01; // 64-bit FPR flag 4765 } 4766 4767 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4768 let Inst{31} = 0; // 32-bit GPR flag 4769 let Inst{23-22} = 0b11; // 16-bit FPR flag 4770 let Predicates = [HasFullFP16]; 4771 } 4772 4773 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4774 let Inst{31} = 1; // 64-bit GPR flag 4775 let Inst{23-22} = 0b11; // 16-bit FPR flag 4776 let Predicates = [HasFullFP16]; 4777 } 4778 4779 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4780 let Inst{31} = 0; // 32-bit GPR flag 4781 let Inst{23-22} = 0b00; // 32-bit FPR flag 4782 } 4783 4784 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4785 let Inst{31} = 1; // 64-bit GPR flag 4786 let Inst{23-22} = 0b01; // 64-bit FPR flag 4787 } 4788 4789 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4790 asm, ".d"> { 4791 let Inst{31} = 1; 4792 let Inst{22} = 0; 4793 } 4794 4795 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4796 asm, ".d"> { 4797 let Inst{31} = 1; 4798 let Inst{22} = 0; 4799 } 4800} 4801 4802//--- 4803// Floating point conversion 4804//--- 4805 4806class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4807 RegisterClass srcType, string asm, list<dag> pattern> 4808 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4809 Sched<[WriteFCvt]> { 4810 bits<5> Rd; 4811 bits<5> Rn; 4812 let Inst{31-24} = 0b00011110; 4813 let Inst{23-22} = type; 4814 let Inst{21-17} = 0b10001; 4815 let Inst{16-15} = opcode; 4816 let Inst{14-10} = 0b10000; 4817 let Inst{9-5} = Rn; 4818 let Inst{4-0} = Rd; 4819} 4820 4821multiclass FPConversion<string asm> { 4822 // Double-precision to Half-precision 4823 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4824 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 4825 4826 // Double-precision to Single-precision 4827 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4828 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 4829 4830 // Half-precision to Double-precision 4831 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4832 [(set FPR64:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4833 4834 // Half-precision to Single-precision 4835 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4836 [(set FPR32:$Rd, (fpextend (f16 FPR16:$Rn)))]>; 4837 4838 // Single-precision to Double-precision 4839 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4840 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4841 4842 // Single-precision to Half-precision 4843 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4844 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 4845} 4846 4847//--- 4848// Single operand floating point data processing 4849//--- 4850 4851let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4852class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4853 ValueType vt, string asm, SDPatternOperator node> 4854 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4855 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4856 Sched<[WriteF]> { 4857 bits<5> Rd; 4858 bits<5> Rn; 4859 let Inst{31-24} = 0b00011110; 4860 let Inst{21} = 0b1; 4861 let Inst{20-15} = opcode; 4862 let Inst{14-10} = 0b10000; 4863 let Inst{9-5} = Rn; 4864 let Inst{4-0} = Rd; 4865} 4866 4867multiclass SingleOperandFPData<bits<4> opcode, string asm, 4868 SDPatternOperator node = null_frag> { 4869 4870 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4871 let Inst{23-22} = 0b11; // 16-bit size flag 4872 let Predicates = [HasFullFP16]; 4873 } 4874 4875 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4876 let Inst{23-22} = 0b00; // 32-bit size flag 4877 } 4878 4879 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4880 let Inst{23-22} = 0b01; // 64-bit size flag 4881 } 4882} 4883 4884multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4885 SDPatternOperator node = null_frag>{ 4886 4887 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4888 let Inst{23-22} = 0b00; // 32-bit registers 4889 } 4890 4891 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4892 let Inst{23-22} = 0b01; // 64-bit registers 4893 } 4894} 4895 4896// FRInt[32|64][Z|N] instructions 4897multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4898 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4899 4900//--- 4901// Two operand floating point data processing 4902//--- 4903 4904let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4905class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4906 string asm, list<dag> pat> 4907 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4908 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4909 Sched<[WriteF]> { 4910 bits<5> Rd; 4911 bits<5> Rn; 4912 bits<5> Rm; 4913 let Inst{31-24} = 0b00011110; 4914 let Inst{21} = 1; 4915 let Inst{20-16} = Rm; 4916 let Inst{15-12} = opcode; 4917 let Inst{11-10} = 0b10; 4918 let Inst{9-5} = Rn; 4919 let Inst{4-0} = Rd; 4920} 4921 4922multiclass TwoOperandFPData<bits<4> opcode, string asm, 4923 SDPatternOperator node = null_frag> { 4924 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4925 [(set (f16 FPR16:$Rd), 4926 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4927 let Inst{23-22} = 0b11; // 16-bit size flag 4928 let Predicates = [HasFullFP16]; 4929 } 4930 4931 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4932 [(set (f32 FPR32:$Rd), 4933 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4934 let Inst{23-22} = 0b00; // 32-bit size flag 4935 } 4936 4937 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4938 [(set (f64 FPR64:$Rd), 4939 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4940 let Inst{23-22} = 0b01; // 64-bit size flag 4941 } 4942} 4943 4944multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4945 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4946 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 4947 let Inst{23-22} = 0b11; // 16-bit size flag 4948 let Predicates = [HasFullFP16]; 4949 } 4950 4951 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4952 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4953 let Inst{23-22} = 0b00; // 32-bit size flag 4954 } 4955 4956 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4957 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 4958 let Inst{23-22} = 0b01; // 64-bit size flag 4959 } 4960} 4961 4962 4963//--- 4964// Three operand floating point data processing 4965//--- 4966 4967class BaseThreeOperandFPData<bit isNegated, bit isSub, 4968 RegisterClass regtype, string asm, list<dag> pat> 4969 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 4970 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 4971 Sched<[WriteFMul]> { 4972 bits<5> Rd; 4973 bits<5> Rn; 4974 bits<5> Rm; 4975 bits<5> Ra; 4976 let Inst{31-24} = 0b00011111; 4977 let Inst{21} = isNegated; 4978 let Inst{20-16} = Rm; 4979 let Inst{15} = isSub; 4980 let Inst{14-10} = Ra; 4981 let Inst{9-5} = Rn; 4982 let Inst{4-0} = Rd; 4983} 4984 4985multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 4986 SDPatternOperator node> { 4987 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 4988 [(set (f16 FPR16:$Rd), 4989 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 4990 let Inst{23-22} = 0b11; // 16-bit size flag 4991 let Predicates = [HasFullFP16]; 4992 } 4993 4994 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 4995 [(set FPR32:$Rd, 4996 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 4997 let Inst{23-22} = 0b00; // 32-bit size flag 4998 } 4999 5000 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5001 [(set FPR64:$Rd, 5002 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5003 let Inst{23-22} = 0b01; // 64-bit size flag 5004 } 5005} 5006 5007//--- 5008// Floating point data comparisons 5009//--- 5010 5011let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5012class BaseOneOperandFPComparison<bit signalAllNans, 5013 RegisterClass regtype, string asm, 5014 list<dag> pat> 5015 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5016 Sched<[WriteFCmp]> { 5017 bits<5> Rn; 5018 let Inst{31-24} = 0b00011110; 5019 let Inst{21} = 1; 5020 5021 let Inst{15-10} = 0b001000; 5022 let Inst{9-5} = Rn; 5023 let Inst{4} = signalAllNans; 5024 let Inst{3-0} = 0b1000; 5025 5026 // Rm should be 0b00000 canonically, but we need to accept any value. 5027 let PostEncoderMethod = "fixOneOperandFPComparison"; 5028} 5029 5030let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5031class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5032 string asm, list<dag> pat> 5033 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5034 Sched<[WriteFCmp]> { 5035 bits<5> Rm; 5036 bits<5> Rn; 5037 let Inst{31-24} = 0b00011110; 5038 let Inst{21} = 1; 5039 let Inst{20-16} = Rm; 5040 let Inst{15-10} = 0b001000; 5041 let Inst{9-5} = Rn; 5042 let Inst{4} = signalAllNans; 5043 let Inst{3-0} = 0b0000; 5044} 5045 5046multiclass FPComparison<bit signalAllNans, string asm, 5047 SDPatternOperator OpNode = null_frag> { 5048 let Defs = [NZCV] in { 5049 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5050 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5051 let Inst{23-22} = 0b11; 5052 let Predicates = [HasFullFP16]; 5053 } 5054 5055 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5056 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5057 let Inst{23-22} = 0b11; 5058 let Predicates = [HasFullFP16]; 5059 } 5060 5061 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5062 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5063 let Inst{23-22} = 0b00; 5064 } 5065 5066 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5067 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5068 let Inst{23-22} = 0b00; 5069 } 5070 5071 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5072 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5073 let Inst{23-22} = 0b01; 5074 } 5075 5076 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5077 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5078 let Inst{23-22} = 0b01; 5079 } 5080 } // Defs = [NZCV] 5081} 5082 5083//--- 5084// Floating point conditional comparisons 5085//--- 5086 5087let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5088class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5089 string mnemonic, list<dag> pat> 5090 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5091 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5092 Sched<[WriteFCmp]> { 5093 let Uses = [NZCV]; 5094 let Defs = [NZCV]; 5095 5096 bits<5> Rn; 5097 bits<5> Rm; 5098 bits<4> nzcv; 5099 bits<4> cond; 5100 5101 let Inst{31-24} = 0b00011110; 5102 let Inst{21} = 1; 5103 let Inst{20-16} = Rm; 5104 let Inst{15-12} = cond; 5105 let Inst{11-10} = 0b01; 5106 let Inst{9-5} = Rn; 5107 let Inst{4} = signalAllNans; 5108 let Inst{3-0} = nzcv; 5109} 5110 5111multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5112 SDPatternOperator OpNode = null_frag> { 5113 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5114 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5115 (i32 imm:$cond), NZCV))]> { 5116 let Inst{23-22} = 0b11; 5117 let Predicates = [HasFullFP16]; 5118 } 5119 5120 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5121 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5122 (i32 imm:$cond), NZCV))]> { 5123 let Inst{23-22} = 0b00; 5124 } 5125 5126 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5127 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5128 (i32 imm:$cond), NZCV))]> { 5129 let Inst{23-22} = 0b01; 5130 } 5131} 5132 5133//--- 5134// Floating point conditional select 5135//--- 5136 5137class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5138 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5139 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5140 [(set regtype:$Rd, 5141 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5142 (i32 imm:$cond), NZCV))]>, 5143 Sched<[WriteF]> { 5144 bits<5> Rd; 5145 bits<5> Rn; 5146 bits<5> Rm; 5147 bits<4> cond; 5148 5149 let Inst{31-24} = 0b00011110; 5150 let Inst{21} = 1; 5151 let Inst{20-16} = Rm; 5152 let Inst{15-12} = cond; 5153 let Inst{11-10} = 0b11; 5154 let Inst{9-5} = Rn; 5155 let Inst{4-0} = Rd; 5156} 5157 5158multiclass FPCondSelect<string asm> { 5159 let Uses = [NZCV] in { 5160 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5161 let Inst{23-22} = 0b11; 5162 let Predicates = [HasFullFP16]; 5163 } 5164 5165 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5166 let Inst{23-22} = 0b00; 5167 } 5168 5169 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5170 let Inst{23-22} = 0b01; 5171 } 5172 } // Uses = [NZCV] 5173} 5174 5175//--- 5176// Floating move immediate 5177//--- 5178 5179class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5180 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5181 [(set regtype:$Rd, fpimmtype:$imm)]>, 5182 Sched<[WriteFImm]> { 5183 bits<5> Rd; 5184 bits<8> imm; 5185 let Inst{31-24} = 0b00011110; 5186 let Inst{21} = 1; 5187 let Inst{20-13} = imm; 5188 let Inst{12-5} = 0b10000000; 5189 let Inst{4-0} = Rd; 5190} 5191 5192multiclass FPMoveImmediate<string asm> { 5193 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5194 let Inst{23-22} = 0b11; 5195 let Predicates = [HasFullFP16]; 5196 } 5197 5198 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5199 let Inst{23-22} = 0b00; 5200 } 5201 5202 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5203 let Inst{23-22} = 0b01; 5204 } 5205} 5206} // end of 'let Predicates = [HasFPARMv8]' 5207 5208//---------------------------------------------------------------------------- 5209// AdvSIMD 5210//---------------------------------------------------------------------------- 5211 5212let Predicates = [HasNEON] in { 5213 5214//---------------------------------------------------------------------------- 5215// AdvSIMD three register vector instructions 5216//---------------------------------------------------------------------------- 5217 5218let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5219class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5220 RegisterOperand regtype, string asm, string kind, 5221 list<dag> pattern> 5222 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5223 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5224 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5225 Sched<[WriteV]> { 5226 bits<5> Rd; 5227 bits<5> Rn; 5228 bits<5> Rm; 5229 let Inst{31} = 0; 5230 let Inst{30} = Q; 5231 let Inst{29} = U; 5232 let Inst{28-24} = 0b01110; 5233 let Inst{23-21} = size; 5234 let Inst{20-16} = Rm; 5235 let Inst{15-11} = opcode; 5236 let Inst{10} = 1; 5237 let Inst{9-5} = Rn; 5238 let Inst{4-0} = Rd; 5239} 5240 5241let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5242class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5243 RegisterOperand regtype, string asm, string kind, 5244 list<dag> pattern> 5245 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5246 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5247 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5248 Sched<[WriteV]> { 5249 bits<5> Rd; 5250 bits<5> Rn; 5251 bits<5> Rm; 5252 let Inst{31} = 0; 5253 let Inst{30} = Q; 5254 let Inst{29} = U; 5255 let Inst{28-24} = 0b01110; 5256 let Inst{23-21} = size; 5257 let Inst{20-16} = Rm; 5258 let Inst{15-11} = opcode; 5259 let Inst{10} = 1; 5260 let Inst{9-5} = Rn; 5261 let Inst{4-0} = Rd; 5262} 5263 5264let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5265class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5266 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5267 Sched<[WriteV]>; 5268 5269multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5270 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5271 [(set (v8i8 V64:$dst), 5272 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5273 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5274 [(set (v16i8 V128:$dst), 5275 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5276 (v16i8 V128:$Rm)))]>; 5277 5278 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5279 (v4i16 V64:$RHS))), 5280 (!cast<Instruction>(NAME#"v8i8") 5281 V64:$LHS, V64:$MHS, V64:$RHS)>; 5282 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5283 (v2i32 V64:$RHS))), 5284 (!cast<Instruction>(NAME#"v8i8") 5285 V64:$LHS, V64:$MHS, V64:$RHS)>; 5286 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5287 (v1i64 V64:$RHS))), 5288 (!cast<Instruction>(NAME#"v8i8") 5289 V64:$LHS, V64:$MHS, V64:$RHS)>; 5290 5291 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5292 (v8i16 V128:$RHS))), 5293 (!cast<Instruction>(NAME#"v16i8") 5294 V128:$LHS, V128:$MHS, V128:$RHS)>; 5295 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5296 (v4i32 V128:$RHS))), 5297 (!cast<Instruction>(NAME#"v16i8") 5298 V128:$LHS, V128:$MHS, V128:$RHS)>; 5299 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5300 (v2i64 V128:$RHS))), 5301 (!cast<Instruction>(NAME#"v16i8") 5302 V128:$LHS, V128:$MHS, V128:$RHS)>; 5303} 5304 5305// All operand sizes distinguished in the encoding. 5306multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5307 SDPatternOperator OpNode> { 5308 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5309 asm, ".8b", 5310 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5311 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5312 asm, ".16b", 5313 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5314 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5315 asm, ".4h", 5316 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5317 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5318 asm, ".8h", 5319 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5320 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5321 asm, ".2s", 5322 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5323 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5324 asm, ".4s", 5325 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5326 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5327 asm, ".2d", 5328 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5329} 5330 5331multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5332 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5333 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5334 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5335 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5336 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5337 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5338 5339 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5340 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5341 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5342 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5343 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5344 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5345 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5346 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5347} 5348 5349// As above, but D sized elements unsupported. 5350multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5351 SDPatternOperator OpNode> { 5352 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5353 asm, ".8b", 5354 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5355 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5356 asm, ".16b", 5357 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5358 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5359 asm, ".4h", 5360 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5361 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5362 asm, ".8h", 5363 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5364 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5365 asm, ".2s", 5366 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5367 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5368 asm, ".4s", 5369 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5370} 5371 5372multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5373 SDPatternOperator OpNode> { 5374 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5375 asm, ".8b", 5376 [(set (v8i8 V64:$dst), 5377 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5378 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5379 asm, ".16b", 5380 [(set (v16i8 V128:$dst), 5381 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5382 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5383 asm, ".4h", 5384 [(set (v4i16 V64:$dst), 5385 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5386 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5387 asm, ".8h", 5388 [(set (v8i16 V128:$dst), 5389 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5390 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5391 asm, ".2s", 5392 [(set (v2i32 V64:$dst), 5393 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5394 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5395 asm, ".4s", 5396 [(set (v4i32 V128:$dst), 5397 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5398} 5399 5400// As above, but only B sized elements supported. 5401multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5402 SDPatternOperator OpNode> { 5403 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5404 asm, ".8b", 5405 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5406 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5407 asm, ".16b", 5408 [(set (v16i8 V128:$Rd), 5409 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5410} 5411 5412// As above, but only floating point elements supported. 5413multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5414 string asm, SDPatternOperator OpNode> { 5415 let Predicates = [HasNEON, HasFullFP16] in { 5416 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5417 asm, ".4h", 5418 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5419 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5420 asm, ".8h", 5421 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5422 } // Predicates = [HasNEON, HasFullFP16] 5423 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5424 asm, ".2s", 5425 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5426 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5427 asm, ".4s", 5428 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5429 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5430 asm, ".2d", 5431 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5432} 5433 5434multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5435 string asm, 5436 SDPatternOperator OpNode> { 5437 let Predicates = [HasNEON, HasFullFP16] in { 5438 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5439 asm, ".4h", 5440 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5441 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5442 asm, ".8h", 5443 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5444 } // Predicates = [HasNEON, HasFullFP16] 5445 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5446 asm, ".2s", 5447 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5448 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5449 asm, ".4s", 5450 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5451 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5452 asm, ".2d", 5453 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5454} 5455 5456multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5457 string asm, SDPatternOperator OpNode> { 5458 let Predicates = [HasNEON, HasFullFP16] in { 5459 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5460 asm, ".4h", 5461 [(set (v4f16 V64:$dst), 5462 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5463 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5464 asm, ".8h", 5465 [(set (v8f16 V128:$dst), 5466 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5467 } // Predicates = [HasNEON, HasFullFP16] 5468 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5469 asm, ".2s", 5470 [(set (v2f32 V64:$dst), 5471 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5472 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5473 asm, ".4s", 5474 [(set (v4f32 V128:$dst), 5475 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5476 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5477 asm, ".2d", 5478 [(set (v2f64 V128:$dst), 5479 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5480} 5481 5482// As above, but D and B sized elements unsupported. 5483multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5484 SDPatternOperator OpNode> { 5485 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5486 asm, ".4h", 5487 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5488 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5489 asm, ".8h", 5490 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5491 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5492 asm, ".2s", 5493 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5494 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5495 asm, ".4s", 5496 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5497} 5498 5499// Logical three vector ops share opcode bits, and only use B sized elements. 5500multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5501 SDPatternOperator OpNode = null_frag> { 5502 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5503 asm, ".8b", 5504 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5505 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5506 asm, ".16b", 5507 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5508 5509 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5510 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5511 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5512 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5513 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5514 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5515 5516 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5517 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5518 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5519 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5520 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5521 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5522} 5523 5524multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5525 string asm, SDPatternOperator OpNode = null_frag> { 5526 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5527 asm, ".8b", 5528 [(set (v8i8 V64:$dst), 5529 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5530 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5531 asm, ".16b", 5532 [(set (v16i8 V128:$dst), 5533 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5534 (v16i8 V128:$Rm)))]>; 5535 5536 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5537 (v4i16 V64:$RHS))), 5538 (!cast<Instruction>(NAME#"v8i8") 5539 V64:$LHS, V64:$MHS, V64:$RHS)>; 5540 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5541 (v2i32 V64:$RHS))), 5542 (!cast<Instruction>(NAME#"v8i8") 5543 V64:$LHS, V64:$MHS, V64:$RHS)>; 5544 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5545 (v1i64 V64:$RHS))), 5546 (!cast<Instruction>(NAME#"v8i8") 5547 V64:$LHS, V64:$MHS, V64:$RHS)>; 5548 5549 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5550 (v8i16 V128:$RHS))), 5551 (!cast<Instruction>(NAME#"v16i8") 5552 V128:$LHS, V128:$MHS, V128:$RHS)>; 5553 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5554 (v4i32 V128:$RHS))), 5555 (!cast<Instruction>(NAME#"v16i8") 5556 V128:$LHS, V128:$MHS, V128:$RHS)>; 5557 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5558 (v2i64 V128:$RHS))), 5559 (!cast<Instruction>(NAME#"v16i8") 5560 V128:$LHS, V128:$MHS, V128:$RHS)>; 5561} 5562 5563// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5564// bytes from S-sized elements. 5565class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5566 string kind2, RegisterOperand RegType, 5567 ValueType AccumType, ValueType InputType, 5568 SDPatternOperator OpNode> : 5569 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5570 [(set (AccumType RegType:$dst), 5571 (OpNode (AccumType RegType:$Rd), 5572 (InputType RegType:$Rn), 5573 (InputType RegType:$Rm)))]> { 5574 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5575} 5576 5577multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5578 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5579 v2i32, v8i8, OpNode>; 5580 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5581 v4i32, v16i8, OpNode>; 5582} 5583 5584// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5585// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5586// 8H to 4S, when Q=1). 5587class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5588 string kind2, RegisterOperand RegType, 5589 ValueType AccumType, ValueType InputType, 5590 SDPatternOperator OpNode> : 5591 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5592 [(set (AccumType RegType:$dst), 5593 (OpNode (AccumType RegType:$Rd), 5594 (InputType RegType:$Rn), 5595 (InputType RegType:$Rm)))]> { 5596 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5597 let Inst{13} = b13; 5598} 5599 5600multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5601 SDPatternOperator OpNode> { 5602 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5603 v2f32, v4f16, OpNode>; 5604 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5605 v4f32, v8f16, OpNode>; 5606} 5607 5608 5609//---------------------------------------------------------------------------- 5610// AdvSIMD two register vector instructions. 5611//---------------------------------------------------------------------------- 5612 5613let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5614class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5615 bits<2> size2, RegisterOperand regtype, string asm, 5616 string dstkind, string srckind, list<dag> pattern> 5617 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5618 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5619 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5620 Sched<[WriteV]> { 5621 bits<5> Rd; 5622 bits<5> Rn; 5623 let Inst{31} = 0; 5624 let Inst{30} = Q; 5625 let Inst{29} = U; 5626 let Inst{28-24} = 0b01110; 5627 let Inst{23-22} = size; 5628 let Inst{21} = 0b1; 5629 let Inst{20-19} = size2; 5630 let Inst{18-17} = 0b00; 5631 let Inst{16-12} = opcode; 5632 let Inst{11-10} = 0b10; 5633 let Inst{9-5} = Rn; 5634 let Inst{4-0} = Rd; 5635} 5636 5637let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5638class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5639 bits<2> size2, RegisterOperand regtype, 5640 string asm, string dstkind, string srckind, 5641 list<dag> pattern> 5642 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5643 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5644 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5645 Sched<[WriteV]> { 5646 bits<5> Rd; 5647 bits<5> Rn; 5648 let Inst{31} = 0; 5649 let Inst{30} = Q; 5650 let Inst{29} = U; 5651 let Inst{28-24} = 0b01110; 5652 let Inst{23-22} = size; 5653 let Inst{21} = 0b1; 5654 let Inst{20-19} = size2; 5655 let Inst{18-17} = 0b00; 5656 let Inst{16-12} = opcode; 5657 let Inst{11-10} = 0b10; 5658 let Inst{9-5} = Rn; 5659 let Inst{4-0} = Rd; 5660} 5661 5662// Supports B, H, and S element sizes. 5663multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5664 SDPatternOperator OpNode> { 5665 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5666 asm, ".8b", ".8b", 5667 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5668 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5669 asm, ".16b", ".16b", 5670 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5671 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5672 asm, ".4h", ".4h", 5673 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5674 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5675 asm, ".8h", ".8h", 5676 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5677 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5678 asm, ".2s", ".2s", 5679 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5680 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5681 asm, ".4s", ".4s", 5682 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5683} 5684 5685class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5686 RegisterOperand regtype, string asm, string dstkind, 5687 string srckind, string amount> 5688 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5689 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5690 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5691 Sched<[WriteV]> { 5692 bits<5> Rd; 5693 bits<5> Rn; 5694 let Inst{31} = 0; 5695 let Inst{30} = Q; 5696 let Inst{29-24} = 0b101110; 5697 let Inst{23-22} = size; 5698 let Inst{21-10} = 0b100001001110; 5699 let Inst{9-5} = Rn; 5700 let Inst{4-0} = Rd; 5701} 5702 5703multiclass SIMDVectorLShiftLongBySizeBHS { 5704 let hasSideEffects = 0 in { 5705 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5706 "shll", ".8h", ".8b", "8">; 5707 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5708 "shll2", ".8h", ".16b", "8">; 5709 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5710 "shll", ".4s", ".4h", "16">; 5711 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5712 "shll2", ".4s", ".8h", "16">; 5713 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5714 "shll", ".2d", ".2s", "32">; 5715 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5716 "shll2", ".2d", ".4s", "32">; 5717 } 5718} 5719 5720// Supports all element sizes. 5721multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5722 SDPatternOperator OpNode> { 5723 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5724 asm, ".4h", ".8b", 5725 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5726 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5727 asm, ".8h", ".16b", 5728 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5729 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5730 asm, ".2s", ".4h", 5731 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5732 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5733 asm, ".4s", ".8h", 5734 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5735 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5736 asm, ".1d", ".2s", 5737 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5738 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5739 asm, ".2d", ".4s", 5740 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5741} 5742 5743multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5744 SDPatternOperator OpNode> { 5745 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5746 asm, ".4h", ".8b", 5747 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5748 (v8i8 V64:$Rn)))]>; 5749 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5750 asm, ".8h", ".16b", 5751 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5752 (v16i8 V128:$Rn)))]>; 5753 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5754 asm, ".2s", ".4h", 5755 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5756 (v4i16 V64:$Rn)))]>; 5757 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5758 asm, ".4s", ".8h", 5759 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5760 (v8i16 V128:$Rn)))]>; 5761 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5762 asm, ".1d", ".2s", 5763 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5764 (v2i32 V64:$Rn)))]>; 5765 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5766 asm, ".2d", ".4s", 5767 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5768 (v4i32 V128:$Rn)))]>; 5769} 5770 5771// Supports all element sizes, except 1xD. 5772multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5773 SDPatternOperator OpNode> { 5774 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5775 asm, ".8b", ".8b", 5776 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5777 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5778 asm, ".16b", ".16b", 5779 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5780 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5781 asm, ".4h", ".4h", 5782 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5783 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5784 asm, ".8h", ".8h", 5785 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5786 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5787 asm, ".2s", ".2s", 5788 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5789 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5790 asm, ".4s", ".4s", 5791 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5792 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5793 asm, ".2d", ".2d", 5794 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5795} 5796 5797multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5798 SDPatternOperator OpNode = null_frag> { 5799 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5800 asm, ".8b", ".8b", 5801 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5802 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5803 asm, ".16b", ".16b", 5804 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5805 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5806 asm, ".4h", ".4h", 5807 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5808 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5809 asm, ".8h", ".8h", 5810 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5811 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5812 asm, ".2s", ".2s", 5813 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5814 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5815 asm, ".4s", ".4s", 5816 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5817 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5818 asm, ".2d", ".2d", 5819 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5820} 5821 5822 5823// Supports only B element sizes. 5824multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5825 SDPatternOperator OpNode> { 5826 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5827 asm, ".8b", ".8b", 5828 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5829 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5830 asm, ".16b", ".16b", 5831 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5832 5833} 5834 5835// Supports only B and H element sizes. 5836multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5837 SDPatternOperator OpNode> { 5838 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5839 asm, ".8b", ".8b", 5840 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5841 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5842 asm, ".16b", ".16b", 5843 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5844 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5845 asm, ".4h", ".4h", 5846 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5847 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5848 asm, ".8h", ".8h", 5849 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5850} 5851 5852// Supports H, S and D element sizes, uses high bit of the size field 5853// as an extra opcode bit. 5854multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5855 SDPatternOperator OpNode> { 5856 let Predicates = [HasNEON, HasFullFP16] in { 5857 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5858 asm, ".4h", ".4h", 5859 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5860 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5861 asm, ".8h", ".8h", 5862 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5863 } // Predicates = [HasNEON, HasFullFP16] 5864 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5865 asm, ".2s", ".2s", 5866 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5867 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5868 asm, ".4s", ".4s", 5869 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5870 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5871 asm, ".2d", ".2d", 5872 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5873} 5874 5875// Supports only S and D element sizes 5876multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5877 SDPatternOperator OpNode = null_frag> { 5878 5879 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5880 asm, ".2s", ".2s", 5881 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5882 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5883 asm, ".4s", ".4s", 5884 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5885 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5886 asm, ".2d", ".2d", 5887 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5888} 5889 5890multiclass FRIntNNTVector<bit U, bit op, string asm, 5891 SDPatternOperator OpNode = null_frag> : 5892 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5893 5894// Supports only S element size. 5895multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5896 SDPatternOperator OpNode> { 5897 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5898 asm, ".2s", ".2s", 5899 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5900 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5901 asm, ".4s", ".4s", 5902 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5903} 5904 5905 5906multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5907 SDPatternOperator OpNode> { 5908 let Predicates = [HasNEON, HasFullFP16] in { 5909 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5910 asm, ".4h", ".4h", 5911 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5912 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5913 asm, ".8h", ".8h", 5914 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5915 } // Predicates = [HasNEON, HasFullFP16] 5916 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5917 asm, ".2s", ".2s", 5918 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5919 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5920 asm, ".4s", ".4s", 5921 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5922 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5923 asm, ".2d", ".2d", 5924 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5925} 5926 5927multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 5928 SDPatternOperator OpNode> { 5929 let Predicates = [HasNEON, HasFullFP16] in { 5930 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5931 asm, ".4h", ".4h", 5932 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5933 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5934 asm, ".8h", ".8h", 5935 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5936 } // Predicates = [HasNEON, HasFullFP16] 5937 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5938 asm, ".2s", ".2s", 5939 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5940 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5941 asm, ".4s", ".4s", 5942 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5943 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5944 asm, ".2d", ".2d", 5945 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5946} 5947 5948 5949class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5950 RegisterOperand inreg, RegisterOperand outreg, 5951 string asm, string outkind, string inkind, 5952 list<dag> pattern> 5953 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 5954 "{\t$Rd" # outkind # ", $Rn" # inkind # 5955 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 5956 Sched<[WriteV]> { 5957 bits<5> Rd; 5958 bits<5> Rn; 5959 let Inst{31} = 0; 5960 let Inst{30} = Q; 5961 let Inst{29} = U; 5962 let Inst{28-24} = 0b01110; 5963 let Inst{23-22} = size; 5964 let Inst{21-17} = 0b10000; 5965 let Inst{16-12} = opcode; 5966 let Inst{11-10} = 0b10; 5967 let Inst{9-5} = Rn; 5968 let Inst{4-0} = Rd; 5969} 5970 5971class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5972 RegisterOperand inreg, RegisterOperand outreg, 5973 string asm, string outkind, string inkind, 5974 list<dag> pattern> 5975 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 5976 "{\t$Rd" # outkind # ", $Rn" # inkind # 5977 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5978 Sched<[WriteV]> { 5979 bits<5> Rd; 5980 bits<5> Rn; 5981 let Inst{31} = 0; 5982 let Inst{30} = Q; 5983 let Inst{29} = U; 5984 let Inst{28-24} = 0b01110; 5985 let Inst{23-22} = size; 5986 let Inst{21-17} = 0b10000; 5987 let Inst{16-12} = opcode; 5988 let Inst{11-10} = 0b10; 5989 let Inst{9-5} = Rn; 5990 let Inst{4-0} = Rd; 5991} 5992 5993multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 5994 SDPatternOperator OpNode> { 5995 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 5996 asm, ".8b", ".8h", 5997 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5998 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 5999 asm#"2", ".16b", ".8h", []>; 6000 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6001 asm, ".4h", ".4s", 6002 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6003 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6004 asm#"2", ".8h", ".4s", []>; 6005 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6006 asm, ".2s", ".2d", 6007 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6008 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6009 asm#"2", ".4s", ".2d", []>; 6010 6011 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6012 (!cast<Instruction>(NAME # "v16i8") 6013 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6014 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6015 (!cast<Instruction>(NAME # "v8i16") 6016 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6017 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6018 (!cast<Instruction>(NAME # "v4i32") 6019 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6020} 6021 6022class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6023 bits<5> opcode, RegisterOperand regtype, string asm, 6024 string kind, string zero, ValueType dty, 6025 ValueType sty, SDNode OpNode> 6026 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6027 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6028 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6029 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6030 Sched<[WriteV]> { 6031 bits<5> Rd; 6032 bits<5> Rn; 6033 let Inst{31} = 0; 6034 let Inst{30} = Q; 6035 let Inst{29} = U; 6036 let Inst{28-24} = 0b01110; 6037 let Inst{23-22} = size; 6038 let Inst{21} = 0b1; 6039 let Inst{20-19} = size2; 6040 let Inst{18-17} = 0b00; 6041 let Inst{16-12} = opcode; 6042 let Inst{11-10} = 0b10; 6043 let Inst{9-5} = Rn; 6044 let Inst{4-0} = Rd; 6045} 6046 6047// Comparisons support all element sizes, except 1xD. 6048multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6049 SDNode OpNode> { 6050 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6051 asm, ".8b", "0", 6052 v8i8, v8i8, OpNode>; 6053 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6054 asm, ".16b", "0", 6055 v16i8, v16i8, OpNode>; 6056 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6057 asm, ".4h", "0", 6058 v4i16, v4i16, OpNode>; 6059 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6060 asm, ".8h", "0", 6061 v8i16, v8i16, OpNode>; 6062 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6063 asm, ".2s", "0", 6064 v2i32, v2i32, OpNode>; 6065 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6066 asm, ".4s", "0", 6067 v4i32, v4i32, OpNode>; 6068 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6069 asm, ".2d", "0", 6070 v2i64, v2i64, OpNode>; 6071} 6072 6073// FP Comparisons support only S and D element sizes (and H for v8.2a). 6074multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6075 string asm, SDNode OpNode> { 6076 6077 let Predicates = [HasNEON, HasFullFP16] in { 6078 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6079 asm, ".4h", "0.0", 6080 v4i16, v4f16, OpNode>; 6081 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6082 asm, ".8h", "0.0", 6083 v8i16, v8f16, OpNode>; 6084 } // Predicates = [HasNEON, HasFullFP16] 6085 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6086 asm, ".2s", "0.0", 6087 v2i32, v2f32, OpNode>; 6088 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6089 asm, ".4s", "0.0", 6090 v4i32, v4f32, OpNode>; 6091 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6092 asm, ".2d", "0.0", 6093 v2i64, v2f64, OpNode>; 6094 6095 let Predicates = [HasNEON, HasFullFP16] in { 6096 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6097 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6098 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6099 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6100 } 6101 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6102 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6103 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6104 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6105 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6106 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6107 let Predicates = [HasNEON, HasFullFP16] in { 6108 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6109 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6110 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6111 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6112 } 6113 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6114 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6115 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6116 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6117 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6118 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6119} 6120 6121let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6122class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6123 RegisterOperand outtype, RegisterOperand intype, 6124 string asm, string VdTy, string VnTy, 6125 list<dag> pattern> 6126 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6127 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6128 Sched<[WriteV]> { 6129 bits<5> Rd; 6130 bits<5> Rn; 6131 let Inst{31} = 0; 6132 let Inst{30} = Q; 6133 let Inst{29} = U; 6134 let Inst{28-24} = 0b01110; 6135 let Inst{23-22} = size; 6136 let Inst{21-17} = 0b10000; 6137 let Inst{16-12} = opcode; 6138 let Inst{11-10} = 0b10; 6139 let Inst{9-5} = Rn; 6140 let Inst{4-0} = Rd; 6141} 6142 6143class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6144 RegisterOperand outtype, RegisterOperand intype, 6145 string asm, string VdTy, string VnTy, 6146 list<dag> pattern> 6147 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6148 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6149 Sched<[WriteV]> { 6150 bits<5> Rd; 6151 bits<5> Rn; 6152 let Inst{31} = 0; 6153 let Inst{30} = Q; 6154 let Inst{29} = U; 6155 let Inst{28-24} = 0b01110; 6156 let Inst{23-22} = size; 6157 let Inst{21-17} = 0b10000; 6158 let Inst{16-12} = opcode; 6159 let Inst{11-10} = 0b10; 6160 let Inst{9-5} = Rn; 6161 let Inst{4-0} = Rd; 6162} 6163 6164multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6165 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6166 asm, ".4s", ".4h", []>; 6167 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6168 asm#"2", ".4s", ".8h", []>; 6169 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6170 asm, ".2d", ".2s", []>; 6171 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6172 asm#"2", ".2d", ".4s", []>; 6173} 6174 6175multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6176 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6177 asm, ".4h", ".4s", []>; 6178 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6179 asm#"2", ".8h", ".4s", []>; 6180 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6181 asm, ".2s", ".2d", []>; 6182 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6183 asm#"2", ".4s", ".2d", []>; 6184} 6185 6186multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6187 Intrinsic OpNode> { 6188 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6189 asm, ".2s", ".2d", 6190 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6191 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6192 asm#"2", ".4s", ".2d", []>; 6193 6194 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6195 (!cast<Instruction>(NAME # "v4f32") 6196 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6197} 6198 6199//---------------------------------------------------------------------------- 6200// AdvSIMD three register different-size vector instructions. 6201//---------------------------------------------------------------------------- 6202 6203let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6204class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6205 RegisterOperand outtype, RegisterOperand intype1, 6206 RegisterOperand intype2, string asm, 6207 string outkind, string inkind1, string inkind2, 6208 list<dag> pattern> 6209 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6210 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6211 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6212 Sched<[WriteV]> { 6213 bits<5> Rd; 6214 bits<5> Rn; 6215 bits<5> Rm; 6216 let Inst{31} = 0; 6217 let Inst{30} = size{0}; 6218 let Inst{29} = U; 6219 let Inst{28-24} = 0b01110; 6220 let Inst{23-22} = size{2-1}; 6221 let Inst{21} = 1; 6222 let Inst{20-16} = Rm; 6223 let Inst{15-12} = opcode; 6224 let Inst{11-10} = 0b00; 6225 let Inst{9-5} = Rn; 6226 let Inst{4-0} = Rd; 6227} 6228 6229let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6230class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6231 RegisterOperand outtype, RegisterOperand intype1, 6232 RegisterOperand intype2, string asm, 6233 string outkind, string inkind1, string inkind2, 6234 list<dag> pattern> 6235 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6236 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6237 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6238 Sched<[WriteV]> { 6239 bits<5> Rd; 6240 bits<5> Rn; 6241 bits<5> Rm; 6242 let Inst{31} = 0; 6243 let Inst{30} = size{0}; 6244 let Inst{29} = U; 6245 let Inst{28-24} = 0b01110; 6246 let Inst{23-22} = size{2-1}; 6247 let Inst{21} = 1; 6248 let Inst{20-16} = Rm; 6249 let Inst{15-12} = opcode; 6250 let Inst{11-10} = 0b00; 6251 let Inst{9-5} = Rn; 6252 let Inst{4-0} = Rd; 6253} 6254 6255// FIXME: TableGen doesn't know how to deal with expanded types that also 6256// change the element count (in this case, placing the results in 6257// the high elements of the result register rather than the low 6258// elements). Until that's fixed, we can't code-gen those. 6259multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6260 Intrinsic IntOp> { 6261 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6262 V64, V128, V128, 6263 asm, ".8b", ".8h", ".8h", 6264 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6265 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6266 V128, V128, V128, 6267 asm#"2", ".16b", ".8h", ".8h", 6268 []>; 6269 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6270 V64, V128, V128, 6271 asm, ".4h", ".4s", ".4s", 6272 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6273 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6274 V128, V128, V128, 6275 asm#"2", ".8h", ".4s", ".4s", 6276 []>; 6277 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6278 V64, V128, V128, 6279 asm, ".2s", ".2d", ".2d", 6280 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6281 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6282 V128, V128, V128, 6283 asm#"2", ".4s", ".2d", ".2d", 6284 []>; 6285 6286 6287 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6288 // a version attached to an instruction. 6289 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6290 (v8i16 V128:$Rm))), 6291 (!cast<Instruction>(NAME # "v8i16_v16i8") 6292 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6293 V128:$Rn, V128:$Rm)>; 6294 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6295 (v4i32 V128:$Rm))), 6296 (!cast<Instruction>(NAME # "v4i32_v8i16") 6297 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6298 V128:$Rn, V128:$Rm)>; 6299 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6300 (v2i64 V128:$Rm))), 6301 (!cast<Instruction>(NAME # "v2i64_v4i32") 6302 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6303 V128:$Rn, V128:$Rm)>; 6304} 6305 6306multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6307 Intrinsic IntOp> { 6308 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6309 V128, V64, V64, 6310 asm, ".8h", ".8b", ".8b", 6311 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6312 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6313 V128, V128, V128, 6314 asm#"2", ".8h", ".16b", ".16b", []>; 6315 let Predicates = [HasAES] in { 6316 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6317 V128, V64, V64, 6318 asm, ".1q", ".1d", ".1d", []>; 6319 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6320 V128, V128, V128, 6321 asm#"2", ".1q", ".2d", ".2d", []>; 6322 } 6323 6324 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6325 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6326 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6327} 6328 6329multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6330 SDPatternOperator OpNode> { 6331 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6332 V128, V64, V64, 6333 asm, ".4s", ".4h", ".4h", 6334 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6335 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6336 V128, V128, V128, 6337 asm#"2", ".4s", ".8h", ".8h", 6338 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6339 (extract_high_v8i16 V128:$Rm)))]>; 6340 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6341 V128, V64, V64, 6342 asm, ".2d", ".2s", ".2s", 6343 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6344 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6345 V128, V128, V128, 6346 asm#"2", ".2d", ".4s", ".4s", 6347 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6348 (extract_high_v4i32 V128:$Rm)))]>; 6349} 6350 6351multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6352 SDPatternOperator OpNode = null_frag> { 6353 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6354 V128, V64, V64, 6355 asm, ".8h", ".8b", ".8b", 6356 [(set (v8i16 V128:$Rd), 6357 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6358 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6359 V128, V128, V128, 6360 asm#"2", ".8h", ".16b", ".16b", 6361 [(set (v8i16 V128:$Rd), 6362 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6363 (extract_high_v16i8 V128:$Rm)))))]>; 6364 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6365 V128, V64, V64, 6366 asm, ".4s", ".4h", ".4h", 6367 [(set (v4i32 V128:$Rd), 6368 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6369 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6370 V128, V128, V128, 6371 asm#"2", ".4s", ".8h", ".8h", 6372 [(set (v4i32 V128:$Rd), 6373 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6374 (extract_high_v8i16 V128:$Rm)))))]>; 6375 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6376 V128, V64, V64, 6377 asm, ".2d", ".2s", ".2s", 6378 [(set (v2i64 V128:$Rd), 6379 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6380 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6381 V128, V128, V128, 6382 asm#"2", ".2d", ".4s", ".4s", 6383 [(set (v2i64 V128:$Rd), 6384 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6385 (extract_high_v4i32 V128:$Rm)))))]>; 6386} 6387 6388multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6389 string asm, 6390 SDPatternOperator OpNode> { 6391 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6392 V128, V64, V64, 6393 asm, ".8h", ".8b", ".8b", 6394 [(set (v8i16 V128:$dst), 6395 (add (v8i16 V128:$Rd), 6396 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6397 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6398 V128, V128, V128, 6399 asm#"2", ".8h", ".16b", ".16b", 6400 [(set (v8i16 V128:$dst), 6401 (add (v8i16 V128:$Rd), 6402 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6403 (extract_high_v16i8 V128:$Rm))))))]>; 6404 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6405 V128, V64, V64, 6406 asm, ".4s", ".4h", ".4h", 6407 [(set (v4i32 V128:$dst), 6408 (add (v4i32 V128:$Rd), 6409 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6410 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6411 V128, V128, V128, 6412 asm#"2", ".4s", ".8h", ".8h", 6413 [(set (v4i32 V128:$dst), 6414 (add (v4i32 V128:$Rd), 6415 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6416 (extract_high_v8i16 V128:$Rm))))))]>; 6417 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6418 V128, V64, V64, 6419 asm, ".2d", ".2s", ".2s", 6420 [(set (v2i64 V128:$dst), 6421 (add (v2i64 V128:$Rd), 6422 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6423 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6424 V128, V128, V128, 6425 asm#"2", ".2d", ".4s", ".4s", 6426 [(set (v2i64 V128:$dst), 6427 (add (v2i64 V128:$Rd), 6428 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6429 (extract_high_v4i32 V128:$Rm))))))]>; 6430} 6431 6432multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6433 SDPatternOperator OpNode = null_frag> { 6434 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6435 V128, V64, V64, 6436 asm, ".8h", ".8b", ".8b", 6437 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6438 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6439 V128, V128, V128, 6440 asm#"2", ".8h", ".16b", ".16b", 6441 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6442 (extract_high_v16i8 V128:$Rm)))]>; 6443 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6444 V128, V64, V64, 6445 asm, ".4s", ".4h", ".4h", 6446 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6447 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6448 V128, V128, V128, 6449 asm#"2", ".4s", ".8h", ".8h", 6450 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6451 (extract_high_v8i16 V128:$Rm)))]>; 6452 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6453 V128, V64, V64, 6454 asm, ".2d", ".2s", ".2s", 6455 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6456 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6457 V128, V128, V128, 6458 asm#"2", ".2d", ".4s", ".4s", 6459 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6460 (extract_high_v4i32 V128:$Rm)))]>; 6461} 6462 6463multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6464 string asm, 6465 SDPatternOperator OpNode> { 6466 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6467 V128, V64, V64, 6468 asm, ".8h", ".8b", ".8b", 6469 [(set (v8i16 V128:$dst), 6470 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6471 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6472 V128, V128, V128, 6473 asm#"2", ".8h", ".16b", ".16b", 6474 [(set (v8i16 V128:$dst), 6475 (OpNode (v8i16 V128:$Rd), 6476 (extract_high_v16i8 V128:$Rn), 6477 (extract_high_v16i8 V128:$Rm)))]>; 6478 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6479 V128, V64, V64, 6480 asm, ".4s", ".4h", ".4h", 6481 [(set (v4i32 V128:$dst), 6482 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6483 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6484 V128, V128, V128, 6485 asm#"2", ".4s", ".8h", ".8h", 6486 [(set (v4i32 V128:$dst), 6487 (OpNode (v4i32 V128:$Rd), 6488 (extract_high_v8i16 V128:$Rn), 6489 (extract_high_v8i16 V128:$Rm)))]>; 6490 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6491 V128, V64, V64, 6492 asm, ".2d", ".2s", ".2s", 6493 [(set (v2i64 V128:$dst), 6494 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6495 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6496 V128, V128, V128, 6497 asm#"2", ".2d", ".4s", ".4s", 6498 [(set (v2i64 V128:$dst), 6499 (OpNode (v2i64 V128:$Rd), 6500 (extract_high_v4i32 V128:$Rn), 6501 (extract_high_v4i32 V128:$Rm)))]>; 6502} 6503 6504multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6505 SDPatternOperator Accum> { 6506 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6507 V128, V64, V64, 6508 asm, ".4s", ".4h", ".4h", 6509 [(set (v4i32 V128:$dst), 6510 (Accum (v4i32 V128:$Rd), 6511 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6512 (v4i16 V64:$Rm)))))]>; 6513 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6514 V128, V128, V128, 6515 asm#"2", ".4s", ".8h", ".8h", 6516 [(set (v4i32 V128:$dst), 6517 (Accum (v4i32 V128:$Rd), 6518 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6519 (extract_high_v8i16 V128:$Rm)))))]>; 6520 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6521 V128, V64, V64, 6522 asm, ".2d", ".2s", ".2s", 6523 [(set (v2i64 V128:$dst), 6524 (Accum (v2i64 V128:$Rd), 6525 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6526 (v2i32 V64:$Rm)))))]>; 6527 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6528 V128, V128, V128, 6529 asm#"2", ".2d", ".4s", ".4s", 6530 [(set (v2i64 V128:$dst), 6531 (Accum (v2i64 V128:$Rd), 6532 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6533 (extract_high_v4i32 V128:$Rm)))))]>; 6534} 6535 6536multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6537 SDPatternOperator OpNode> { 6538 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6539 V128, V128, V64, 6540 asm, ".8h", ".8h", ".8b", 6541 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6542 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6543 V128, V128, V128, 6544 asm#"2", ".8h", ".8h", ".16b", 6545 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6546 (extract_high_v16i8 V128:$Rm)))]>; 6547 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6548 V128, V128, V64, 6549 asm, ".4s", ".4s", ".4h", 6550 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6551 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6552 V128, V128, V128, 6553 asm#"2", ".4s", ".4s", ".8h", 6554 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6555 (extract_high_v8i16 V128:$Rm)))]>; 6556 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6557 V128, V128, V64, 6558 asm, ".2d", ".2d", ".2s", 6559 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6560 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6561 V128, V128, V128, 6562 asm#"2", ".2d", ".2d", ".4s", 6563 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6564 (extract_high_v4i32 V128:$Rm)))]>; 6565} 6566 6567//---------------------------------------------------------------------------- 6568// AdvSIMD bitwise extract from vector 6569//---------------------------------------------------------------------------- 6570 6571class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6572 string asm, string kind> 6573 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6574 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6575 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6576 [(set (vty regtype:$Rd), 6577 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6578 Sched<[WriteV]> { 6579 bits<5> Rd; 6580 bits<5> Rn; 6581 bits<5> Rm; 6582 bits<4> imm; 6583 let Inst{31} = 0; 6584 let Inst{30} = size; 6585 let Inst{29-21} = 0b101110000; 6586 let Inst{20-16} = Rm; 6587 let Inst{15} = 0; 6588 let Inst{14-11} = imm; 6589 let Inst{10} = 0; 6590 let Inst{9-5} = Rn; 6591 let Inst{4-0} = Rd; 6592} 6593 6594 6595multiclass SIMDBitwiseExtract<string asm> { 6596 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6597 let imm{3} = 0; 6598 } 6599 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6600} 6601 6602//---------------------------------------------------------------------------- 6603// AdvSIMD zip vector 6604//---------------------------------------------------------------------------- 6605 6606class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6607 string asm, string kind, SDNode OpNode, ValueType valty> 6608 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6609 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6610 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6611 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6612 Sched<[WriteV]> { 6613 bits<5> Rd; 6614 bits<5> Rn; 6615 bits<5> Rm; 6616 let Inst{31} = 0; 6617 let Inst{30} = size{0}; 6618 let Inst{29-24} = 0b001110; 6619 let Inst{23-22} = size{2-1}; 6620 let Inst{21} = 0; 6621 let Inst{20-16} = Rm; 6622 let Inst{15} = 0; 6623 let Inst{14-12} = opc; 6624 let Inst{11-10} = 0b10; 6625 let Inst{9-5} = Rn; 6626 let Inst{4-0} = Rd; 6627} 6628 6629multiclass SIMDZipVector<bits<3>opc, string asm, 6630 SDNode OpNode> { 6631 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6632 asm, ".8b", OpNode, v8i8>; 6633 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6634 asm, ".16b", OpNode, v16i8>; 6635 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6636 asm, ".4h", OpNode, v4i16>; 6637 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6638 asm, ".8h", OpNode, v8i16>; 6639 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6640 asm, ".2s", OpNode, v2i32>; 6641 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6642 asm, ".4s", OpNode, v4i32>; 6643 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6644 asm, ".2d", OpNode, v2i64>; 6645 6646 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6647 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6648 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6649 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6650 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6651 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6652 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6653 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6654 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6655 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6656} 6657 6658//---------------------------------------------------------------------------- 6659// AdvSIMD three register scalar instructions 6660//---------------------------------------------------------------------------- 6661 6662let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6663class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6664 RegisterClass regtype, string asm, 6665 list<dag> pattern> 6666 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6667 "\t$Rd, $Rn, $Rm", "", pattern>, 6668 Sched<[WriteV]> { 6669 bits<5> Rd; 6670 bits<5> Rn; 6671 bits<5> Rm; 6672 let Inst{31-30} = 0b01; 6673 let Inst{29} = U; 6674 let Inst{28-24} = 0b11110; 6675 let Inst{23-21} = size; 6676 let Inst{20-16} = Rm; 6677 let Inst{15-11} = opcode; 6678 let Inst{10} = 1; 6679 let Inst{9-5} = Rn; 6680 let Inst{4-0} = Rd; 6681} 6682 6683let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6684class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6685 dag oops, dag iops, string asm, 6686 list<dag> pattern> 6687 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6688 Sched<[WriteV]> { 6689 bits<5> Rd; 6690 bits<5> Rn; 6691 bits<5> Rm; 6692 let Inst{31-30} = 0b01; 6693 let Inst{29} = U; 6694 let Inst{28-24} = 0b11110; 6695 let Inst{23-22} = size; 6696 let Inst{21} = R; 6697 let Inst{20-16} = Rm; 6698 let Inst{15-11} = opcode; 6699 let Inst{10} = 1; 6700 let Inst{9-5} = Rn; 6701 let Inst{4-0} = Rd; 6702} 6703 6704multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6705 SDPatternOperator OpNode> { 6706 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6707 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6708} 6709 6710multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6711 SDPatternOperator OpNode> { 6712 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6713 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6714 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6715 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6716 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6717 6718 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6719 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6720 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6721 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6722} 6723 6724multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6725 SDPatternOperator OpNode> { 6726 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6727 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6728 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6729} 6730 6731multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6732 SDPatternOperator OpNode = null_frag> { 6733 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6734 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6735 asm, []>; 6736 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6737 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6738 asm, []>; 6739} 6740 6741multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6742 SDPatternOperator OpNode = null_frag> { 6743 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6744 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6745 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6746 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6747 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6748 let Predicates = [HasNEON, HasFullFP16] in { 6749 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6750 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 6751 } // Predicates = [HasNEON, HasFullFP16] 6752 } 6753 6754 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6755 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6756} 6757 6758multiclass SIMDThreeScalarFPCmp<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 (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6763 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6764 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6765 let Predicates = [HasNEON, HasFullFP16] in { 6766 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6767 []>; 6768 } // Predicates = [HasNEON, HasFullFP16] 6769 } 6770 6771 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6772 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6773} 6774 6775class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6776 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6777 : I<oops, iops, asm, 6778 "\t$Rd, $Rn, $Rm", cstr, pat>, 6779 Sched<[WriteV]> { 6780 bits<5> Rd; 6781 bits<5> Rn; 6782 bits<5> Rm; 6783 let Inst{31-30} = 0b01; 6784 let Inst{29} = U; 6785 let Inst{28-24} = 0b11110; 6786 let Inst{23-22} = size; 6787 let Inst{21} = 1; 6788 let Inst{20-16} = Rm; 6789 let Inst{15-11} = opcode; 6790 let Inst{10} = 0; 6791 let Inst{9-5} = Rn; 6792 let Inst{4-0} = Rd; 6793} 6794 6795let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6796multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6797 SDPatternOperator OpNode = null_frag> { 6798 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6799 (outs FPR32:$Rd), 6800 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6801 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6802 (outs FPR64:$Rd), 6803 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6804 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6805} 6806 6807let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6808multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6809 SDPatternOperator OpNode = null_frag> { 6810 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6811 (outs FPR32:$dst), 6812 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6813 asm, "$Rd = $dst", []>; 6814 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6815 (outs FPR64:$dst), 6816 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6817 asm, "$Rd = $dst", 6818 [(set (i64 FPR64:$dst), 6819 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6820} 6821 6822//---------------------------------------------------------------------------- 6823// AdvSIMD two register scalar instructions 6824//---------------------------------------------------------------------------- 6825 6826let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6827class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6828 RegisterClass regtype, RegisterClass regtype2, 6829 string asm, list<dag> pat> 6830 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6831 "\t$Rd, $Rn", "", pat>, 6832 Sched<[WriteV]> { 6833 bits<5> Rd; 6834 bits<5> Rn; 6835 let Inst{31-30} = 0b01; 6836 let Inst{29} = U; 6837 let Inst{28-24} = 0b11110; 6838 let Inst{23-22} = size; 6839 let Inst{21} = 0b1; 6840 let Inst{20-19} = size2; 6841 let Inst{18-17} = 0b00; 6842 let Inst{16-12} = opcode; 6843 let Inst{11-10} = 0b10; 6844 let Inst{9-5} = Rn; 6845 let Inst{4-0} = Rd; 6846} 6847 6848let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6849class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6850 RegisterClass regtype, RegisterClass regtype2, 6851 string asm, list<dag> pat> 6852 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6853 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6854 Sched<[WriteV]> { 6855 bits<5> Rd; 6856 bits<5> Rn; 6857 let Inst{31-30} = 0b01; 6858 let Inst{29} = U; 6859 let Inst{28-24} = 0b11110; 6860 let Inst{23-22} = size; 6861 let Inst{21-17} = 0b10000; 6862 let Inst{16-12} = opcode; 6863 let Inst{11-10} = 0b10; 6864 let Inst{9-5} = Rn; 6865 let Inst{4-0} = Rd; 6866} 6867 6868 6869let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6870class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6871 RegisterClass regtype, string asm, string zero> 6872 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6873 "\t$Rd, $Rn, #" # zero, "", []>, 6874 Sched<[WriteV]> { 6875 bits<5> Rd; 6876 bits<5> Rn; 6877 let Inst{31-30} = 0b01; 6878 let Inst{29} = U; 6879 let Inst{28-24} = 0b11110; 6880 let Inst{23-22} = size; 6881 let Inst{21} = 0b1; 6882 let Inst{20-19} = size2; 6883 let Inst{18-17} = 0b00; 6884 let Inst{16-12} = opcode; 6885 let Inst{11-10} = 0b10; 6886 let Inst{9-5} = Rn; 6887 let Inst{4-0} = Rd; 6888} 6889 6890class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6891 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6892 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6893 Sched<[WriteV]> { 6894 bits<5> Rd; 6895 bits<5> Rn; 6896 let Inst{31-17} = 0b011111100110000; 6897 let Inst{16-12} = opcode; 6898 let Inst{11-10} = 0b10; 6899 let Inst{9-5} = Rn; 6900 let Inst{4-0} = Rd; 6901} 6902 6903multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6904 SDPatternOperator OpNode> { 6905 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6906 6907 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6908 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6909} 6910 6911multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6912 SDPatternOperator OpNode> { 6913 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 6914 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 6915 let Predicates = [HasNEON, HasFullFP16] in { 6916 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 6917 } 6918 6919 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6920 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 6921 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6922 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 6923 let Predicates = [HasNEON, HasFullFP16] in { 6924 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6925 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 6926 } 6927 6928 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 6929 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6930} 6931 6932multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 6933 SDPatternOperator OpNode = null_frag> { 6934 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6935 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 6936 6937 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 6938 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 6939} 6940 6941multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 6942 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 6943 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 6944 let Predicates = [HasNEON, HasFullFP16] in { 6945 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 6946 } 6947} 6948 6949multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 6950 SDPatternOperator OpNode> { 6951 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 6952 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 6953 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 6954 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 6955 let Predicates = [HasNEON, HasFullFP16] in { 6956 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 6957 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 6958 } 6959} 6960 6961multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 6962 SDPatternOperator OpNode = null_frag> { 6963 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6964 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6965 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6966 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 6967 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 6968 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 6969 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 6970 } 6971 6972 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 6973 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 6974} 6975 6976multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 6977 Intrinsic OpNode> { 6978 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6979 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 6980 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 6981 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 6982 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 6983 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 6984 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 6985 } 6986 6987 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 6988 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 6989} 6990 6991 6992 6993let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6994multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 6995 SDPatternOperator OpNode = null_frag> { 6996 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 6997 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6998 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 6999 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7000} 7001 7002//---------------------------------------------------------------------------- 7003// AdvSIMD scalar pairwise instructions 7004//---------------------------------------------------------------------------- 7005 7006let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7007class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7008 RegisterOperand regtype, RegisterOperand vectype, 7009 string asm, string kind> 7010 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7011 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7012 Sched<[WriteV]> { 7013 bits<5> Rd; 7014 bits<5> Rn; 7015 let Inst{31-30} = 0b01; 7016 let Inst{29} = U; 7017 let Inst{28-24} = 0b11110; 7018 let Inst{23-22} = size; 7019 let Inst{21-17} = 0b11000; 7020 let Inst{16-12} = opcode; 7021 let Inst{11-10} = 0b10; 7022 let Inst{9-5} = Rn; 7023 let Inst{4-0} = Rd; 7024} 7025 7026multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7027 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7028 asm, ".2d">; 7029} 7030 7031multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7032 let Predicates = [HasNEON, HasFullFP16] in { 7033 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7034 asm, ".2h">; 7035 } 7036 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7037 asm, ".2s">; 7038 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7039 asm, ".2d">; 7040} 7041 7042//---------------------------------------------------------------------------- 7043// AdvSIMD across lanes instructions 7044//---------------------------------------------------------------------------- 7045 7046let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7047class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7048 RegisterClass regtype, RegisterOperand vectype, 7049 string asm, string kind, list<dag> pattern> 7050 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7051 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7052 Sched<[WriteV]> { 7053 bits<5> Rd; 7054 bits<5> Rn; 7055 let Inst{31} = 0; 7056 let Inst{30} = Q; 7057 let Inst{29} = U; 7058 let Inst{28-24} = 0b01110; 7059 let Inst{23-22} = size; 7060 let Inst{21-17} = 0b11000; 7061 let Inst{16-12} = opcode; 7062 let Inst{11-10} = 0b10; 7063 let Inst{9-5} = Rn; 7064 let Inst{4-0} = Rd; 7065} 7066 7067multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7068 string asm> { 7069 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7070 asm, ".8b", []>; 7071 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7072 asm, ".16b", []>; 7073 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7074 asm, ".4h", []>; 7075 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7076 asm, ".8h", []>; 7077 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7078 asm, ".4s", []>; 7079} 7080 7081multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7082 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7083 asm, ".8b", []>; 7084 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7085 asm, ".16b", []>; 7086 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7087 asm, ".4h", []>; 7088 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7089 asm, ".8h", []>; 7090 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7091 asm, ".4s", []>; 7092} 7093 7094multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7095 Intrinsic intOp> { 7096 let Predicates = [HasNEON, HasFullFP16] in { 7097 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7098 asm, ".4h", 7099 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7100 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7101 asm, ".8h", 7102 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7103 } // Predicates = [HasNEON, HasFullFP16] 7104 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7105 asm, ".4s", 7106 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7107} 7108 7109//---------------------------------------------------------------------------- 7110// AdvSIMD INS/DUP instructions 7111//---------------------------------------------------------------------------- 7112 7113// FIXME: There has got to be a better way to factor these. ugh. 7114 7115class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7116 string operands, string constraints, list<dag> pattern> 7117 : I<outs, ins, asm, operands, constraints, pattern>, 7118 Sched<[WriteV]> { 7119 bits<5> Rd; 7120 bits<5> Rn; 7121 let Inst{31} = 0; 7122 let Inst{30} = Q; 7123 let Inst{29} = op; 7124 let Inst{28-21} = 0b01110000; 7125 let Inst{15} = 0; 7126 let Inst{10} = 1; 7127 let Inst{9-5} = Rn; 7128 let Inst{4-0} = Rd; 7129} 7130 7131class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7132 RegisterOperand vecreg, RegisterClass regtype> 7133 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7134 "{\t$Rd" # size # ", $Rn" # 7135 "|" # size # "\t$Rd, $Rn}", "", 7136 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7137 let Inst{20-16} = imm5; 7138 let Inst{14-11} = 0b0001; 7139} 7140 7141class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7142 ValueType vectype, ValueType insreg, 7143 RegisterOperand vecreg, Operand idxtype, 7144 ValueType elttype, SDNode OpNode> 7145 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7146 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7147 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7148 [(set (vectype vecreg:$Rd), 7149 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7150 let Inst{14-11} = 0b0000; 7151} 7152 7153class SIMDDup64FromElement 7154 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7155 VectorIndexD, i64, AArch64duplane64> { 7156 bits<1> idx; 7157 let Inst{20} = idx; 7158 let Inst{19-16} = 0b1000; 7159} 7160 7161class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7162 RegisterOperand vecreg> 7163 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7164 VectorIndexS, i64, AArch64duplane32> { 7165 bits<2> idx; 7166 let Inst{20-19} = idx; 7167 let Inst{18-16} = 0b100; 7168} 7169 7170class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7171 RegisterOperand vecreg> 7172 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7173 VectorIndexH, i64, AArch64duplane16> { 7174 bits<3> idx; 7175 let Inst{20-18} = idx; 7176 let Inst{17-16} = 0b10; 7177} 7178 7179class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7180 RegisterOperand vecreg> 7181 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7182 VectorIndexB, i64, AArch64duplane8> { 7183 bits<4> idx; 7184 let Inst{20-17} = idx; 7185 let Inst{16} = 1; 7186} 7187 7188class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7189 Operand idxtype, string asm, list<dag> pattern> 7190 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7191 "{\t$Rd, $Rn" # size # "$idx" # 7192 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7193 let Inst{14-11} = imm4; 7194} 7195 7196class SIMDSMov<bit Q, string size, RegisterClass regtype, 7197 Operand idxtype> 7198 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7199class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7200 Operand idxtype> 7201 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7202 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7203 7204class SIMDMovAlias<string asm, string size, Instruction inst, 7205 RegisterClass regtype, Operand idxtype> 7206 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7207 "|" # size # "\t$dst, $src$idx}", 7208 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7209 7210multiclass SMov { 7211 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7212 bits<4> idx; 7213 let Inst{20-17} = idx; 7214 let Inst{16} = 1; 7215 } 7216 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7217 bits<4> idx; 7218 let Inst{20-17} = idx; 7219 let Inst{16} = 1; 7220 } 7221 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7222 bits<3> idx; 7223 let Inst{20-18} = idx; 7224 let Inst{17-16} = 0b10; 7225 } 7226 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7227 bits<3> idx; 7228 let Inst{20-18} = idx; 7229 let Inst{17-16} = 0b10; 7230 } 7231 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7232 bits<2> idx; 7233 let Inst{20-19} = idx; 7234 let Inst{18-16} = 0b100; 7235 } 7236} 7237 7238multiclass UMov { 7239 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7240 bits<4> idx; 7241 let Inst{20-17} = idx; 7242 let Inst{16} = 1; 7243 } 7244 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7245 bits<3> idx; 7246 let Inst{20-18} = idx; 7247 let Inst{17-16} = 0b10; 7248 } 7249 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7250 bits<2> idx; 7251 let Inst{20-19} = idx; 7252 let Inst{18-16} = 0b100; 7253 } 7254 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7255 bits<1> idx; 7256 let Inst{20} = idx; 7257 let Inst{19-16} = 0b1000; 7258 } 7259 def : SIMDMovAlias<"mov", ".s", 7260 !cast<Instruction>(NAME#"vi32"), 7261 GPR32, VectorIndexS>; 7262 def : SIMDMovAlias<"mov", ".d", 7263 !cast<Instruction>(NAME#"vi64"), 7264 GPR64, VectorIndexD>; 7265} 7266 7267class SIMDInsFromMain<string size, ValueType vectype, 7268 RegisterClass regtype, Operand idxtype> 7269 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7270 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7271 "{\t$Rd" # size # "$idx, $Rn" # 7272 "|" # size # "\t$Rd$idx, $Rn}", 7273 "$Rd = $dst", 7274 [(set V128:$dst, 7275 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7276 let Inst{14-11} = 0b0011; 7277} 7278 7279class SIMDInsFromElement<string size, ValueType vectype, 7280 ValueType elttype, Operand idxtype> 7281 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7282 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7283 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7284 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7285 "$Rd = $dst", 7286 [(set V128:$dst, 7287 (vector_insert 7288 (vectype V128:$Rd), 7289 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7290 idxtype:$idx))]>; 7291 7292class SIMDInsMainMovAlias<string size, Instruction inst, 7293 RegisterClass regtype, Operand idxtype> 7294 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7295 "|" # size #"\t$dst$idx, $src}", 7296 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7297class SIMDInsElementMovAlias<string size, Instruction inst, 7298 Operand idxtype> 7299 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7300 # "|" # size #"\t$dst$idx, $src$idx2}", 7301 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7302 7303 7304multiclass SIMDIns { 7305 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7306 bits<4> idx; 7307 let Inst{20-17} = idx; 7308 let Inst{16} = 1; 7309 } 7310 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7311 bits<3> idx; 7312 let Inst{20-18} = idx; 7313 let Inst{17-16} = 0b10; 7314 } 7315 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7316 bits<2> idx; 7317 let Inst{20-19} = idx; 7318 let Inst{18-16} = 0b100; 7319 } 7320 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7321 bits<1> idx; 7322 let Inst{20} = idx; 7323 let Inst{19-16} = 0b1000; 7324 } 7325 7326 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7327 bits<4> idx; 7328 bits<4> idx2; 7329 let Inst{20-17} = idx; 7330 let Inst{16} = 1; 7331 let Inst{14-11} = idx2; 7332 } 7333 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7334 bits<3> idx; 7335 bits<3> idx2; 7336 let Inst{20-18} = idx; 7337 let Inst{17-16} = 0b10; 7338 let Inst{14-12} = idx2; 7339 let Inst{11} = {?}; 7340 } 7341 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7342 bits<2> idx; 7343 bits<2> idx2; 7344 let Inst{20-19} = idx; 7345 let Inst{18-16} = 0b100; 7346 let Inst{14-13} = idx2; 7347 let Inst{12-11} = {?,?}; 7348 } 7349 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7350 bits<1> idx; 7351 bits<1> idx2; 7352 let Inst{20} = idx; 7353 let Inst{19-16} = 0b1000; 7354 let Inst{14} = idx2; 7355 let Inst{13-11} = {?,?,?}; 7356 } 7357 7358 // For all forms of the INS instruction, the "mov" mnemonic is the 7359 // preferred alias. Why they didn't just call the instruction "mov" in 7360 // the first place is a very good question indeed... 7361 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7362 GPR32, VectorIndexB>; 7363 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7364 GPR32, VectorIndexH>; 7365 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7366 GPR32, VectorIndexS>; 7367 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7368 GPR64, VectorIndexD>; 7369 7370 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7371 VectorIndexB>; 7372 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7373 VectorIndexH>; 7374 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7375 VectorIndexS>; 7376 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7377 VectorIndexD>; 7378} 7379 7380//---------------------------------------------------------------------------- 7381// AdvSIMD TBL/TBX 7382//---------------------------------------------------------------------------- 7383 7384let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7385class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7386 RegisterOperand listtype, string asm, string kind> 7387 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7388 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7389 Sched<[WriteV]> { 7390 bits<5> Vd; 7391 bits<5> Vn; 7392 bits<5> Vm; 7393 let Inst{31} = 0; 7394 let Inst{30} = Q; 7395 let Inst{29-21} = 0b001110000; 7396 let Inst{20-16} = Vm; 7397 let Inst{15} = 0; 7398 let Inst{14-13} = len; 7399 let Inst{12} = op; 7400 let Inst{11-10} = 0b00; 7401 let Inst{9-5} = Vn; 7402 let Inst{4-0} = Vd; 7403} 7404 7405let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7406class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7407 RegisterOperand listtype, string asm, string kind> 7408 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7409 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7410 Sched<[WriteV]> { 7411 bits<5> Vd; 7412 bits<5> Vn; 7413 bits<5> Vm; 7414 let Inst{31} = 0; 7415 let Inst{30} = Q; 7416 let Inst{29-21} = 0b001110000; 7417 let Inst{20-16} = Vm; 7418 let Inst{15} = 0; 7419 let Inst{14-13} = len; 7420 let Inst{12} = op; 7421 let Inst{11-10} = 0b00; 7422 let Inst{9-5} = Vn; 7423 let Inst{4-0} = Vd; 7424} 7425 7426class SIMDTableLookupAlias<string asm, Instruction inst, 7427 RegisterOperand vectype, RegisterOperand listtype> 7428 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7429 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7430 7431multiclass SIMDTableLookup<bit op, string asm> { 7432 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7433 asm, ".8b">; 7434 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7435 asm, ".8b">; 7436 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7437 asm, ".8b">; 7438 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7439 asm, ".8b">; 7440 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7441 asm, ".16b">; 7442 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7443 asm, ".16b">; 7444 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7445 asm, ".16b">; 7446 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7447 asm, ".16b">; 7448 7449 def : SIMDTableLookupAlias<asm # ".8b", 7450 !cast<Instruction>(NAME#"v8i8One"), 7451 V64, VecListOne128>; 7452 def : SIMDTableLookupAlias<asm # ".8b", 7453 !cast<Instruction>(NAME#"v8i8Two"), 7454 V64, VecListTwo128>; 7455 def : SIMDTableLookupAlias<asm # ".8b", 7456 !cast<Instruction>(NAME#"v8i8Three"), 7457 V64, VecListThree128>; 7458 def : SIMDTableLookupAlias<asm # ".8b", 7459 !cast<Instruction>(NAME#"v8i8Four"), 7460 V64, VecListFour128>; 7461 def : SIMDTableLookupAlias<asm # ".16b", 7462 !cast<Instruction>(NAME#"v16i8One"), 7463 V128, VecListOne128>; 7464 def : SIMDTableLookupAlias<asm # ".16b", 7465 !cast<Instruction>(NAME#"v16i8Two"), 7466 V128, VecListTwo128>; 7467 def : SIMDTableLookupAlias<asm # ".16b", 7468 !cast<Instruction>(NAME#"v16i8Three"), 7469 V128, VecListThree128>; 7470 def : SIMDTableLookupAlias<asm # ".16b", 7471 !cast<Instruction>(NAME#"v16i8Four"), 7472 V128, VecListFour128>; 7473} 7474 7475multiclass SIMDTableLookupTied<bit op, string asm> { 7476 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7477 asm, ".8b">; 7478 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7479 asm, ".8b">; 7480 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7481 asm, ".8b">; 7482 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7483 asm, ".8b">; 7484 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7485 asm, ".16b">; 7486 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7487 asm, ".16b">; 7488 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7489 asm, ".16b">; 7490 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7491 asm, ".16b">; 7492 7493 def : SIMDTableLookupAlias<asm # ".8b", 7494 !cast<Instruction>(NAME#"v8i8One"), 7495 V64, VecListOne128>; 7496 def : SIMDTableLookupAlias<asm # ".8b", 7497 !cast<Instruction>(NAME#"v8i8Two"), 7498 V64, VecListTwo128>; 7499 def : SIMDTableLookupAlias<asm # ".8b", 7500 !cast<Instruction>(NAME#"v8i8Three"), 7501 V64, VecListThree128>; 7502 def : SIMDTableLookupAlias<asm # ".8b", 7503 !cast<Instruction>(NAME#"v8i8Four"), 7504 V64, VecListFour128>; 7505 def : SIMDTableLookupAlias<asm # ".16b", 7506 !cast<Instruction>(NAME#"v16i8One"), 7507 V128, VecListOne128>; 7508 def : SIMDTableLookupAlias<asm # ".16b", 7509 !cast<Instruction>(NAME#"v16i8Two"), 7510 V128, VecListTwo128>; 7511 def : SIMDTableLookupAlias<asm # ".16b", 7512 !cast<Instruction>(NAME#"v16i8Three"), 7513 V128, VecListThree128>; 7514 def : SIMDTableLookupAlias<asm # ".16b", 7515 !cast<Instruction>(NAME#"v16i8Four"), 7516 V128, VecListFour128>; 7517} 7518 7519 7520//---------------------------------------------------------------------------- 7521// AdvSIMD scalar CPY 7522//---------------------------------------------------------------------------- 7523let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7524class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7525 string kind, Operand idxtype> 7526 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7527 "{\t$dst, $src" # kind # "$idx" # 7528 "|\t$dst, $src$idx}", "", []>, 7529 Sched<[WriteV]> { 7530 bits<5> dst; 7531 bits<5> src; 7532 let Inst{31-21} = 0b01011110000; 7533 let Inst{15-10} = 0b000001; 7534 let Inst{9-5} = src; 7535 let Inst{4-0} = dst; 7536} 7537 7538class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7539 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7540 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7541 # "|\t$dst, $src$index}", 7542 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7543 7544 7545multiclass SIMDScalarCPY<string asm> { 7546 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7547 bits<4> idx; 7548 let Inst{20-17} = idx; 7549 let Inst{16} = 1; 7550 } 7551 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7552 bits<3> idx; 7553 let Inst{20-18} = idx; 7554 let Inst{17-16} = 0b10; 7555 } 7556 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7557 bits<2> idx; 7558 let Inst{20-19} = idx; 7559 let Inst{18-16} = 0b100; 7560 } 7561 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7562 bits<1> idx; 7563 let Inst{20} = idx; 7564 let Inst{19-16} = 0b1000; 7565 } 7566 7567 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7568 VectorIndexD:$idx)))), 7569 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7570 7571 // 'DUP' mnemonic aliases. 7572 def : SIMDScalarCPYAlias<"dup", ".b", 7573 !cast<Instruction>(NAME#"i8"), 7574 FPR8, V128, VectorIndexB>; 7575 def : SIMDScalarCPYAlias<"dup", ".h", 7576 !cast<Instruction>(NAME#"i16"), 7577 FPR16, V128, VectorIndexH>; 7578 def : SIMDScalarCPYAlias<"dup", ".s", 7579 !cast<Instruction>(NAME#"i32"), 7580 FPR32, V128, VectorIndexS>; 7581 def : SIMDScalarCPYAlias<"dup", ".d", 7582 !cast<Instruction>(NAME#"i64"), 7583 FPR64, V128, VectorIndexD>; 7584} 7585 7586//---------------------------------------------------------------------------- 7587// AdvSIMD modified immediate instructions 7588//---------------------------------------------------------------------------- 7589 7590class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7591 string asm, string op_string, 7592 string cstr, list<dag> pattern> 7593 : I<oops, iops, asm, op_string, cstr, pattern>, 7594 Sched<[WriteV]> { 7595 bits<5> Rd; 7596 bits<8> imm8; 7597 let Inst{31} = 0; 7598 let Inst{30} = Q; 7599 let Inst{29} = op; 7600 let Inst{28-19} = 0b0111100000; 7601 let Inst{18-16} = imm8{7-5}; 7602 let Inst{11} = op2; 7603 let Inst{10} = 1; 7604 let Inst{9-5} = imm8{4-0}; 7605 let Inst{4-0} = Rd; 7606} 7607 7608class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7609 Operand immtype, dag opt_shift_iop, 7610 string opt_shift, string asm, string kind, 7611 list<dag> pattern> 7612 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7613 !con((ins immtype:$imm8), opt_shift_iop), asm, 7614 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7615 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7616 "", pattern> { 7617 let DecoderMethod = "DecodeModImmInstruction"; 7618} 7619 7620class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7621 Operand immtype, dag opt_shift_iop, 7622 string opt_shift, string asm, string kind, 7623 list<dag> pattern> 7624 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7625 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7626 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7627 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7628 "$Rd = $dst", pattern> { 7629 let DecoderMethod = "DecodeModImmTiedInstruction"; 7630} 7631 7632class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7633 RegisterOperand vectype, string asm, 7634 string kind, list<dag> pattern> 7635 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7636 (ins logical_vec_shift:$shift), 7637 "$shift", asm, kind, pattern> { 7638 bits<2> shift; 7639 let Inst{15} = b15_b12{1}; 7640 let Inst{14-13} = shift; 7641 let Inst{12} = b15_b12{0}; 7642} 7643 7644class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7645 RegisterOperand vectype, string asm, 7646 string kind, list<dag> pattern> 7647 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7648 (ins logical_vec_shift:$shift), 7649 "$shift", asm, kind, pattern> { 7650 bits<2> shift; 7651 let Inst{15} = b15_b12{1}; 7652 let Inst{14-13} = shift; 7653 let Inst{12} = b15_b12{0}; 7654} 7655 7656 7657class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7658 RegisterOperand vectype, string asm, 7659 string kind, list<dag> pattern> 7660 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7661 (ins logical_vec_hw_shift:$shift), 7662 "$shift", asm, kind, pattern> { 7663 bits<2> shift; 7664 let Inst{15} = b15_b12{1}; 7665 let Inst{14} = 0; 7666 let Inst{13} = shift{0}; 7667 let Inst{12} = b15_b12{0}; 7668} 7669 7670class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7671 RegisterOperand vectype, string asm, 7672 string kind, list<dag> pattern> 7673 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7674 (ins logical_vec_hw_shift:$shift), 7675 "$shift", asm, kind, pattern> { 7676 bits<2> shift; 7677 let Inst{15} = b15_b12{1}; 7678 let Inst{14} = 0; 7679 let Inst{13} = shift{0}; 7680 let Inst{12} = b15_b12{0}; 7681} 7682 7683multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7684 string asm> { 7685 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7686 asm, ".4h", []>; 7687 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7688 asm, ".8h", []>; 7689 7690 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7691 asm, ".2s", []>; 7692 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7693 asm, ".4s", []>; 7694} 7695 7696multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7697 bits<2> w_cmode, string asm, 7698 SDNode OpNode> { 7699 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7700 asm, ".4h", 7701 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7702 imm0_255:$imm8, 7703 (i32 imm:$shift)))]>; 7704 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7705 asm, ".8h", 7706 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7707 imm0_255:$imm8, 7708 (i32 imm:$shift)))]>; 7709 7710 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7711 asm, ".2s", 7712 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7713 imm0_255:$imm8, 7714 (i32 imm:$shift)))]>; 7715 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7716 asm, ".4s", 7717 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7718 imm0_255:$imm8, 7719 (i32 imm:$shift)))]>; 7720} 7721 7722class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7723 RegisterOperand vectype, string asm, 7724 string kind, list<dag> pattern> 7725 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7726 (ins move_vec_shift:$shift), 7727 "$shift", asm, kind, pattern> { 7728 bits<1> shift; 7729 let Inst{15-13} = cmode{3-1}; 7730 let Inst{12} = shift; 7731} 7732 7733class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7734 RegisterOperand vectype, 7735 Operand imm_type, string asm, 7736 string kind, list<dag> pattern> 7737 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7738 asm, kind, pattern> { 7739 let Inst{15-12} = cmode; 7740} 7741 7742class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7743 list<dag> pattern> 7744 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7745 "\t$Rd, $imm8", "", pattern> { 7746 let Inst{15-12} = cmode; 7747 let DecoderMethod = "DecodeModImmInstruction"; 7748} 7749 7750//---------------------------------------------------------------------------- 7751// AdvSIMD indexed element 7752//---------------------------------------------------------------------------- 7753 7754let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7755class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7756 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7757 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7758 string apple_kind, string dst_kind, string lhs_kind, 7759 string rhs_kind, list<dag> pattern> 7760 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7761 asm, 7762 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7763 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7764 Sched<[WriteV]> { 7765 bits<5> Rd; 7766 bits<5> Rn; 7767 bits<5> Rm; 7768 7769 let Inst{31} = 0; 7770 let Inst{30} = Q; 7771 let Inst{29} = U; 7772 let Inst{28} = Scalar; 7773 let Inst{27-24} = 0b1111; 7774 let Inst{23-22} = size; 7775 // Bit 21 must be set by the derived class. 7776 let Inst{20-16} = Rm; 7777 let Inst{15-12} = opc; 7778 // Bit 11 must be set by the derived class. 7779 let Inst{10} = 0; 7780 let Inst{9-5} = Rn; 7781 let Inst{4-0} = Rd; 7782} 7783 7784let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7785class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7786 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7787 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7788 string apple_kind, string dst_kind, string lhs_kind, 7789 string rhs_kind, list<dag> pattern> 7790 : I<(outs dst_reg:$dst), 7791 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7792 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7793 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7794 Sched<[WriteV]> { 7795 bits<5> Rd; 7796 bits<5> Rn; 7797 bits<5> Rm; 7798 7799 let Inst{31} = 0; 7800 let Inst{30} = Q; 7801 let Inst{29} = U; 7802 let Inst{28} = Scalar; 7803 let Inst{27-24} = 0b1111; 7804 let Inst{23-22} = size; 7805 // Bit 21 must be set by the derived class. 7806 let Inst{20-16} = Rm; 7807 let Inst{15-12} = opc; 7808 // Bit 11 must be set by the derived class. 7809 let Inst{10} = 0; 7810 let Inst{9-5} = Rn; 7811 let Inst{4-0} = Rd; 7812} 7813 7814 7815//---------------------------------------------------------------------------- 7816// Armv8.6 BFloat16 Extension 7817//---------------------------------------------------------------------------- 7818let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 7819 7820class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 7821 string kind2, RegisterOperand RegType, 7822 ValueType AccumType, ValueType InputType> 7823 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 7824 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 7825 (InputType RegType:$Rn), 7826 (InputType RegType:$Rm)))]> { 7827 let AsmString = !strconcat(asm, 7828 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 7829 ", $Rm" # kind2 # "}"); 7830} 7831 7832multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 7833 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 7834 v2f32, v8i8>; 7835 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 7836 v4f32, v16i8>; 7837} 7838 7839class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 7840 string dst_kind, string lhs_kind, 7841 string rhs_kind, 7842 RegisterOperand RegType, 7843 ValueType AccumType, 7844 ValueType InputType> 7845 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 7846 RegType, RegType, V128, VectorIndexS, 7847 asm, "", dst_kind, lhs_kind, rhs_kind, 7848 [(set (AccumType RegType:$dst), 7849 (AccumType (int_aarch64_neon_bfdot 7850 (AccumType RegType:$Rd), 7851 (InputType RegType:$Rn), 7852 (InputType (bitconvert (AccumType 7853 (AArch64duplane32 (v4f32 V128:$Rm), 7854 VectorIndexH:$idx)))))))]> { 7855 7856 bits<2> idx; 7857 let Inst{21} = idx{0}; // L 7858 let Inst{11} = idx{1}; // H 7859} 7860 7861multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 7862 7863 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 7864 ".2h", V64, v2f32, v8i8>; 7865 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 7866 ".2h", V128, v4f32, v16i8>; 7867} 7868 7869class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 7870 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 7871 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 7872 (v16i8 V128:$Rn), 7873 (v16i8 V128:$Rm)))]> { 7874 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 7875} 7876 7877class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 7878 : I<(outs V128:$dst), 7879 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 7880 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 7881 [(set (v4f32 V128:$dst), 7882 (v4f32 (OpNode (v4f32 V128:$Rd), 7883 (v16i8 V128:$Rn), 7884 (v16i8 (bitconvert (v8bf16 7885 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 7886 VectorIndexH:$idx)))))))]>, 7887 Sched<[WriteV]> { 7888 bits<5> Rd; 7889 bits<5> Rn; 7890 bits<4> Rm; 7891 bits<3> idx; 7892 7893 let Inst{31} = 0; 7894 let Inst{30} = Q; 7895 let Inst{29-22} = 0b00111111; 7896 let Inst{21-20} = idx{1-0}; 7897 let Inst{19-16} = Rm; 7898 let Inst{15-12} = 0b1111; 7899 let Inst{11} = idx{2}; // H 7900 let Inst{10} = 0; 7901 let Inst{9-5} = Rn; 7902 let Inst{4-0} = Rd; 7903} 7904 7905class SIMDThreeSameVectorBF16MatrixMul<string asm> 7906 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 7907 V128, asm, ".4s", 7908 [(set (v4f32 V128:$dst), 7909 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 7910 (v16i8 V128:$Rn), 7911 (v16i8 V128:$Rm)))]> { 7912 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 7913 ", $Rm", ".8h", "}"); 7914} 7915 7916class SIMD_BFCVTN 7917 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 7918 "bfcvtn", ".4h", ".4s", 7919 [(set (v8bf16 V128:$Rd), 7920 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 7921 7922class SIMD_BFCVTN2 7923 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 7924 "bfcvtn2", ".8h", ".4s", 7925 [(set (v8bf16 V128:$dst), 7926 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 7927 7928class BF16ToSinglePrecision<string asm> 7929 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 7930 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 7931 Sched<[WriteFCvt]> { 7932 bits<5> Rd; 7933 bits<5> Rn; 7934 let Inst{31-10} = 0b0001111001100011010000; 7935 let Inst{9-5} = Rn; 7936 let Inst{4-0} = Rd; 7937} 7938} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 7939 7940//---------------------------------------------------------------------------- 7941// Armv8.6 Matrix Multiply Extension 7942//---------------------------------------------------------------------------- 7943 7944class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 7945 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 7946 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 7947 (v16i8 V128:$Rn), 7948 (v16i8 V128:$Rm)))]> { 7949 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 7950} 7951 7952//---------------------------------------------------------------------------- 7953// ARMv8.2-A Dot Product Instructions (Indexed) 7954class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 7955 string dst_kind, string lhs_kind, string rhs_kind, 7956 RegisterOperand RegType, 7957 ValueType AccumType, ValueType InputType, 7958 SDPatternOperator OpNode> : 7959 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 7960 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 7961 [(set (AccumType RegType:$dst), 7962 (AccumType (OpNode (AccumType RegType:$Rd), 7963 (InputType RegType:$Rn), 7964 (InputType (bitconvert (AccumType 7965 (AArch64duplane32 (v4i32 V128:$Rm), 7966 VectorIndexS:$idx)))))))]> { 7967 bits<2> idx; 7968 let Inst{21} = idx{0}; // L 7969 let Inst{11} = idx{1}; // H 7970} 7971 7972multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 7973 SDPatternOperator OpNode> { 7974 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 7975 V64, v2i32, v8i8, OpNode>; 7976 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 7977 V128, v4i32, v16i8, OpNode>; 7978} 7979 7980// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 7981class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 7982 string dst_kind, string lhs_kind, 7983 string rhs_kind, RegisterOperand RegType, 7984 ValueType AccumType, ValueType InputType, 7985 SDPatternOperator OpNode> : 7986 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 7987 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 7988 [(set (AccumType RegType:$dst), 7989 (AccumType (OpNode (AccumType RegType:$Rd), 7990 (InputType RegType:$Rn), 7991 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 7992 VectorIndexH:$idx)))))]> { 7993 // idx = H:L:M 7994 bits<3> idx; 7995 let Inst{11} = idx{2}; // H 7996 let Inst{21} = idx{1}; // L 7997 let Inst{20} = idx{0}; // M 7998} 7999 8000multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8001 SDPatternOperator OpNode> { 8002 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8003 V64, v2f32, v4f16, OpNode>; 8004 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8005 V128, v4f32, v8f16, OpNode>; 8006} 8007 8008multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8009 SDPatternOperator OpNode> { 8010 let Predicates = [HasNEON, HasFullFP16] in { 8011 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8012 V64, V64, 8013 V128_lo, VectorIndexH, 8014 asm, ".4h", ".4h", ".4h", ".h", 8015 [(set (v4f16 V64:$Rd), 8016 (OpNode (v4f16 V64:$Rn), 8017 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8018 bits<3> idx; 8019 let Inst{11} = idx{2}; 8020 let Inst{21} = idx{1}; 8021 let Inst{20} = idx{0}; 8022 } 8023 8024 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8025 V128, V128, 8026 V128_lo, VectorIndexH, 8027 asm, ".8h", ".8h", ".8h", ".h", 8028 [(set (v8f16 V128:$Rd), 8029 (OpNode (v8f16 V128:$Rn), 8030 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8031 bits<3> idx; 8032 let Inst{11} = idx{2}; 8033 let Inst{21} = idx{1}; 8034 let Inst{20} = idx{0}; 8035 } 8036 } // Predicates = [HasNEON, HasFullFP16] 8037 8038 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8039 V64, V64, 8040 V128, VectorIndexS, 8041 asm, ".2s", ".2s", ".2s", ".s", 8042 [(set (v2f32 V64:$Rd), 8043 (OpNode (v2f32 V64:$Rn), 8044 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8045 bits<2> idx; 8046 let Inst{11} = idx{1}; 8047 let Inst{21} = idx{0}; 8048 } 8049 8050 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8051 V128, V128, 8052 V128, VectorIndexS, 8053 asm, ".4s", ".4s", ".4s", ".s", 8054 [(set (v4f32 V128:$Rd), 8055 (OpNode (v4f32 V128:$Rn), 8056 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8057 bits<2> idx; 8058 let Inst{11} = idx{1}; 8059 let Inst{21} = idx{0}; 8060 } 8061 8062 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8063 V128, V128, 8064 V128, VectorIndexD, 8065 asm, ".2d", ".2d", ".2d", ".d", 8066 [(set (v2f64 V128:$Rd), 8067 (OpNode (v2f64 V128:$Rn), 8068 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8069 bits<1> idx; 8070 let Inst{11} = idx{0}; 8071 let Inst{21} = 0; 8072 } 8073 8074 let Predicates = [HasNEON, HasFullFP16] in { 8075 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8076 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8077 asm, ".h", "", "", ".h", 8078 [(set (f16 FPR16Op:$Rd), 8079 (OpNode (f16 FPR16Op:$Rn), 8080 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8081 VectorIndexH:$idx))))]> { 8082 bits<3> idx; 8083 let Inst{11} = idx{2}; 8084 let Inst{21} = idx{1}; 8085 let Inst{20} = idx{0}; 8086 } 8087 } // Predicates = [HasNEON, HasFullFP16] 8088 8089 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8090 FPR32Op, FPR32Op, V128, VectorIndexS, 8091 asm, ".s", "", "", ".s", 8092 [(set (f32 FPR32Op:$Rd), 8093 (OpNode (f32 FPR32Op:$Rn), 8094 (f32 (vector_extract (v4f32 V128:$Rm), 8095 VectorIndexS:$idx))))]> { 8096 bits<2> idx; 8097 let Inst{11} = idx{1}; 8098 let Inst{21} = idx{0}; 8099 } 8100 8101 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8102 FPR64Op, FPR64Op, V128, VectorIndexD, 8103 asm, ".d", "", "", ".d", 8104 [(set (f64 FPR64Op:$Rd), 8105 (OpNode (f64 FPR64Op:$Rn), 8106 (f64 (vector_extract (v2f64 V128:$Rm), 8107 VectorIndexD:$idx))))]> { 8108 bits<1> idx; 8109 let Inst{11} = idx{0}; 8110 let Inst{21} = 0; 8111 } 8112} 8113 8114multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8115 let Predicates = [HasNEON, HasFullFP16] in { 8116 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8117 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8118 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8119 VectorIndexH:$idx))), 8120 (!cast<Instruction>(INST # "v8i16_indexed") 8121 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8122 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8123 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8124 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8125 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8126 8127 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8128 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8129 VectorIndexH:$idx))), 8130 (!cast<Instruction>(INST # "v4i16_indexed") 8131 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8132 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8133 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8134 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8135 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8136 8137 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8138 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8139 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8140 V128_lo:$Rm, VectorIndexH:$idx)>; 8141 } // Predicates = [HasNEON, HasFullFP16] 8142 8143 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8144 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8145 (AArch64duplane32 (v4f32 V128:$Rm), 8146 VectorIndexS:$idx))), 8147 (!cast<Instruction>(INST # v2i32_indexed) 8148 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8149 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8150 (AArch64dup (f32 FPR32Op:$Rm)))), 8151 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8152 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8153 8154 8155 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8156 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8157 (AArch64duplane32 (v4f32 V128:$Rm), 8158 VectorIndexS:$idx))), 8159 (!cast<Instruction>(INST # "v4i32_indexed") 8160 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8161 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8162 (AArch64dup (f32 FPR32Op:$Rm)))), 8163 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8164 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8165 8166 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8167 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8168 (AArch64duplane64 (v2f64 V128:$Rm), 8169 VectorIndexD:$idx))), 8170 (!cast<Instruction>(INST # "v2i64_indexed") 8171 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8172 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8173 (AArch64dup (f64 FPR64Op:$Rm)))), 8174 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8175 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8176 8177 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8178 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8179 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8180 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8181 V128:$Rm, VectorIndexS:$idx)>; 8182 8183 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8184 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8185 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8186 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8187 V128:$Rm, VectorIndexD:$idx)>; 8188} 8189 8190multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8191 let Predicates = [HasNEON, HasFullFP16] in { 8192 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8193 V128_lo, VectorIndexH, 8194 asm, ".4h", ".4h", ".4h", ".h", []> { 8195 bits<3> idx; 8196 let Inst{11} = idx{2}; 8197 let Inst{21} = idx{1}; 8198 let Inst{20} = idx{0}; 8199 } 8200 8201 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8202 V128, V128, 8203 V128_lo, VectorIndexH, 8204 asm, ".8h", ".8h", ".8h", ".h", []> { 8205 bits<3> idx; 8206 let Inst{11} = idx{2}; 8207 let Inst{21} = idx{1}; 8208 let Inst{20} = idx{0}; 8209 } 8210 } // Predicates = [HasNEON, HasFullFP16] 8211 8212 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8213 V128, VectorIndexS, 8214 asm, ".2s", ".2s", ".2s", ".s", []> { 8215 bits<2> idx; 8216 let Inst{11} = idx{1}; 8217 let Inst{21} = idx{0}; 8218 } 8219 8220 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8221 V128, V128, 8222 V128, VectorIndexS, 8223 asm, ".4s", ".4s", ".4s", ".s", []> { 8224 bits<2> idx; 8225 let Inst{11} = idx{1}; 8226 let Inst{21} = idx{0}; 8227 } 8228 8229 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8230 V128, V128, 8231 V128, VectorIndexD, 8232 asm, ".2d", ".2d", ".2d", ".d", []> { 8233 bits<1> idx; 8234 let Inst{11} = idx{0}; 8235 let Inst{21} = 0; 8236 } 8237 8238 let Predicates = [HasNEON, HasFullFP16] in { 8239 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8240 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8241 asm, ".h", "", "", ".h", []> { 8242 bits<3> idx; 8243 let Inst{11} = idx{2}; 8244 let Inst{21} = idx{1}; 8245 let Inst{20} = idx{0}; 8246 } 8247 } // Predicates = [HasNEON, HasFullFP16] 8248 8249 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8250 FPR32Op, FPR32Op, V128, VectorIndexS, 8251 asm, ".s", "", "", ".s", []> { 8252 bits<2> idx; 8253 let Inst{11} = idx{1}; 8254 let Inst{21} = idx{0}; 8255 } 8256 8257 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8258 FPR64Op, FPR64Op, V128, VectorIndexD, 8259 asm, ".d", "", "", ".d", []> { 8260 bits<1> idx; 8261 let Inst{11} = idx{0}; 8262 let Inst{21} = 0; 8263 } 8264} 8265 8266multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8267 SDPatternOperator OpNodeLaneQ> { 8268 8269 def : Pat<(v4i16 (OpNodeLane 8270 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8271 VectorIndexS32b:$idx)), 8272 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8273 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8274 (UImmS1XForm $idx))>; 8275 8276 def : Pat<(v4i16 (OpNodeLaneQ 8277 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8278 VectorIndexH32b:$idx)), 8279 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8280 (UImmS1XForm $idx))>; 8281 8282 def : Pat<(v8i16 (OpNodeLane 8283 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8284 VectorIndexS32b:$idx)), 8285 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8286 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8287 (UImmS1XForm $idx))>; 8288 8289 def : Pat<(v8i16 (OpNodeLaneQ 8290 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8291 VectorIndexH32b:$idx)), 8292 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8293 (UImmS1XForm $idx))>; 8294 8295 def : Pat<(v2i32 (OpNodeLane 8296 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8297 VectorIndexD32b:$idx)), 8298 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8299 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8300 (UImmS1XForm $idx))>; 8301 8302 def : Pat<(v2i32 (OpNodeLaneQ 8303 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8304 VectorIndexS32b:$idx)), 8305 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8306 (UImmS1XForm $idx))>; 8307 8308 def : Pat<(v4i32 (OpNodeLane 8309 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8310 VectorIndexD32b:$idx)), 8311 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8312 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8313 (UImmS1XForm $idx))>; 8314 8315 def : Pat<(v4i32 (OpNodeLaneQ 8316 (v4i32 V128:$Rn), 8317 (v4i32 V128:$Rm), 8318 VectorIndexS32b:$idx)), 8319 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8320 (UImmS1XForm $idx))>; 8321 8322} 8323 8324multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8325 SDPatternOperator OpNode> { 8326 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8327 V128_lo, VectorIndexH, 8328 asm, ".4h", ".4h", ".4h", ".h", 8329 [(set (v4i16 V64:$Rd), 8330 (OpNode (v4i16 V64:$Rn), 8331 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8332 bits<3> idx; 8333 let Inst{11} = idx{2}; 8334 let Inst{21} = idx{1}; 8335 let Inst{20} = idx{0}; 8336 } 8337 8338 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8339 V128, V128, 8340 V128_lo, VectorIndexH, 8341 asm, ".8h", ".8h", ".8h", ".h", 8342 [(set (v8i16 V128:$Rd), 8343 (OpNode (v8i16 V128:$Rn), 8344 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8345 bits<3> idx; 8346 let Inst{11} = idx{2}; 8347 let Inst{21} = idx{1}; 8348 let Inst{20} = idx{0}; 8349 } 8350 8351 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8352 V64, V64, 8353 V128, VectorIndexS, 8354 asm, ".2s", ".2s", ".2s", ".s", 8355 [(set (v2i32 V64:$Rd), 8356 (OpNode (v2i32 V64:$Rn), 8357 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8358 bits<2> idx; 8359 let Inst{11} = idx{1}; 8360 let Inst{21} = idx{0}; 8361 } 8362 8363 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8364 V128, V128, 8365 V128, VectorIndexS, 8366 asm, ".4s", ".4s", ".4s", ".s", 8367 [(set (v4i32 V128:$Rd), 8368 (OpNode (v4i32 V128:$Rn), 8369 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8370 bits<2> idx; 8371 let Inst{11} = idx{1}; 8372 let Inst{21} = idx{0}; 8373 } 8374 8375 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8376 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8377 asm, ".h", "", "", ".h", []> { 8378 bits<3> idx; 8379 let Inst{11} = idx{2}; 8380 let Inst{21} = idx{1}; 8381 let Inst{20} = idx{0}; 8382 } 8383 8384 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8385 FPR32Op, FPR32Op, V128, VectorIndexS, 8386 asm, ".s", "", "", ".s", 8387 [(set (i32 FPR32Op:$Rd), 8388 (OpNode FPR32Op:$Rn, 8389 (i32 (vector_extract (v4i32 V128:$Rm), 8390 VectorIndexS:$idx))))]> { 8391 bits<2> idx; 8392 let Inst{11} = idx{1}; 8393 let Inst{21} = idx{0}; 8394 } 8395} 8396 8397multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8398 SDPatternOperator OpNode> { 8399 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8400 V64, V64, 8401 V128_lo, VectorIndexH, 8402 asm, ".4h", ".4h", ".4h", ".h", 8403 [(set (v4i16 V64:$Rd), 8404 (OpNode (v4i16 V64:$Rn), 8405 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8406 bits<3> idx; 8407 let Inst{11} = idx{2}; 8408 let Inst{21} = idx{1}; 8409 let Inst{20} = idx{0}; 8410 } 8411 8412 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8413 V128, V128, 8414 V128_lo, VectorIndexH, 8415 asm, ".8h", ".8h", ".8h", ".h", 8416 [(set (v8i16 V128:$Rd), 8417 (OpNode (v8i16 V128:$Rn), 8418 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8419 bits<3> idx; 8420 let Inst{11} = idx{2}; 8421 let Inst{21} = idx{1}; 8422 let Inst{20} = idx{0}; 8423 } 8424 8425 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8426 V64, V64, 8427 V128, VectorIndexS, 8428 asm, ".2s", ".2s", ".2s", ".s", 8429 [(set (v2i32 V64:$Rd), 8430 (OpNode (v2i32 V64:$Rn), 8431 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8432 bits<2> idx; 8433 let Inst{11} = idx{1}; 8434 let Inst{21} = idx{0}; 8435 } 8436 8437 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8438 V128, V128, 8439 V128, VectorIndexS, 8440 asm, ".4s", ".4s", ".4s", ".s", 8441 [(set (v4i32 V128:$Rd), 8442 (OpNode (v4i32 V128:$Rn), 8443 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8444 bits<2> idx; 8445 let Inst{11} = idx{1}; 8446 let Inst{21} = idx{0}; 8447 } 8448} 8449 8450multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8451 SDPatternOperator OpNode> { 8452 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8453 V128_lo, VectorIndexH, 8454 asm, ".4h", ".4h", ".4h", ".h", 8455 [(set (v4i16 V64:$dst), 8456 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8457 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8458 bits<3> idx; 8459 let Inst{11} = idx{2}; 8460 let Inst{21} = idx{1}; 8461 let Inst{20} = idx{0}; 8462 } 8463 8464 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8465 V128, V128, 8466 V128_lo, VectorIndexH, 8467 asm, ".8h", ".8h", ".8h", ".h", 8468 [(set (v8i16 V128:$dst), 8469 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8470 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8471 bits<3> idx; 8472 let Inst{11} = idx{2}; 8473 let Inst{21} = idx{1}; 8474 let Inst{20} = idx{0}; 8475 } 8476 8477 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8478 V64, V64, 8479 V128, VectorIndexS, 8480 asm, ".2s", ".2s", ".2s", ".s", 8481 [(set (v2i32 V64:$dst), 8482 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8483 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8484 bits<2> idx; 8485 let Inst{11} = idx{1}; 8486 let Inst{21} = idx{0}; 8487 } 8488 8489 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8490 V128, V128, 8491 V128, VectorIndexS, 8492 asm, ".4s", ".4s", ".4s", ".s", 8493 [(set (v4i32 V128:$dst), 8494 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8495 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8496 bits<2> idx; 8497 let Inst{11} = idx{1}; 8498 let Inst{21} = idx{0}; 8499 } 8500} 8501 8502multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8503 SDPatternOperator OpNode> { 8504 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8505 V128, V64, 8506 V128_lo, VectorIndexH, 8507 asm, ".4s", ".4s", ".4h", ".h", 8508 [(set (v4i32 V128:$Rd), 8509 (OpNode (v4i16 V64:$Rn), 8510 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8511 bits<3> idx; 8512 let Inst{11} = idx{2}; 8513 let Inst{21} = idx{1}; 8514 let Inst{20} = idx{0}; 8515 } 8516 8517 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8518 V128, V128, 8519 V128_lo, VectorIndexH, 8520 asm#"2", ".4s", ".4s", ".8h", ".h", 8521 [(set (v4i32 V128:$Rd), 8522 (OpNode (extract_high_v8i16 V128:$Rn), 8523 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8524 VectorIndexH:$idx))))]> { 8525 8526 bits<3> idx; 8527 let Inst{11} = idx{2}; 8528 let Inst{21} = idx{1}; 8529 let Inst{20} = idx{0}; 8530 } 8531 8532 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8533 V128, V64, 8534 V128, VectorIndexS, 8535 asm, ".2d", ".2d", ".2s", ".s", 8536 [(set (v2i64 V128:$Rd), 8537 (OpNode (v2i32 V64:$Rn), 8538 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8539 bits<2> idx; 8540 let Inst{11} = idx{1}; 8541 let Inst{21} = idx{0}; 8542 } 8543 8544 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8545 V128, V128, 8546 V128, VectorIndexS, 8547 asm#"2", ".2d", ".2d", ".4s", ".s", 8548 [(set (v2i64 V128:$Rd), 8549 (OpNode (extract_high_v4i32 V128:$Rn), 8550 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8551 VectorIndexS:$idx))))]> { 8552 bits<2> idx; 8553 let Inst{11} = idx{1}; 8554 let Inst{21} = idx{0}; 8555 } 8556 8557 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8558 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8559 asm, ".h", "", "", ".h", []> { 8560 bits<3> idx; 8561 let Inst{11} = idx{2}; 8562 let Inst{21} = idx{1}; 8563 let Inst{20} = idx{0}; 8564 } 8565 8566 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8567 FPR64Op, FPR32Op, V128, VectorIndexS, 8568 asm, ".s", "", "", ".s", []> { 8569 bits<2> idx; 8570 let Inst{11} = idx{1}; 8571 let Inst{21} = idx{0}; 8572 } 8573} 8574 8575multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8576 SDPatternOperator Accum> { 8577 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8578 V128, V64, 8579 V128_lo, VectorIndexH, 8580 asm, ".4s", ".4s", ".4h", ".h", 8581 [(set (v4i32 V128:$dst), 8582 (Accum (v4i32 V128:$Rd), 8583 (v4i32 (int_aarch64_neon_sqdmull 8584 (v4i16 V64:$Rn), 8585 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8586 VectorIndexH:$idx))))))]> { 8587 bits<3> idx; 8588 let Inst{11} = idx{2}; 8589 let Inst{21} = idx{1}; 8590 let Inst{20} = idx{0}; 8591 } 8592 8593 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8594 // intermediate EXTRACT_SUBREG would be untyped. 8595 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8596 (i32 (vector_extract (v4i32 8597 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8598 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8599 VectorIndexH:$idx)))), 8600 (i64 0))))), 8601 (EXTRACT_SUBREG 8602 (!cast<Instruction>(NAME # v4i16_indexed) 8603 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8604 V128_lo:$Rm, VectorIndexH:$idx), 8605 ssub)>; 8606 8607 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8608 V128, V128, 8609 V128_lo, VectorIndexH, 8610 asm#"2", ".4s", ".4s", ".8h", ".h", 8611 [(set (v4i32 V128:$dst), 8612 (Accum (v4i32 V128:$Rd), 8613 (v4i32 (int_aarch64_neon_sqdmull 8614 (extract_high_v8i16 V128:$Rn), 8615 (extract_high_v8i16 8616 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8617 VectorIndexH:$idx))))))]> { 8618 bits<3> idx; 8619 let Inst{11} = idx{2}; 8620 let Inst{21} = idx{1}; 8621 let Inst{20} = idx{0}; 8622 } 8623 8624 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8625 V128, V64, 8626 V128, VectorIndexS, 8627 asm, ".2d", ".2d", ".2s", ".s", 8628 [(set (v2i64 V128:$dst), 8629 (Accum (v2i64 V128:$Rd), 8630 (v2i64 (int_aarch64_neon_sqdmull 8631 (v2i32 V64:$Rn), 8632 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8633 VectorIndexS:$idx))))))]> { 8634 bits<2> idx; 8635 let Inst{11} = idx{1}; 8636 let Inst{21} = idx{0}; 8637 } 8638 8639 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8640 V128, V128, 8641 V128, VectorIndexS, 8642 asm#"2", ".2d", ".2d", ".4s", ".s", 8643 [(set (v2i64 V128:$dst), 8644 (Accum (v2i64 V128:$Rd), 8645 (v2i64 (int_aarch64_neon_sqdmull 8646 (extract_high_v4i32 V128:$Rn), 8647 (extract_high_v4i32 8648 (AArch64duplane32 (v4i32 V128:$Rm), 8649 VectorIndexS:$idx))))))]> { 8650 bits<2> idx; 8651 let Inst{11} = idx{1}; 8652 let Inst{21} = idx{0}; 8653 } 8654 8655 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8656 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8657 asm, ".h", "", "", ".h", []> { 8658 bits<3> idx; 8659 let Inst{11} = idx{2}; 8660 let Inst{21} = idx{1}; 8661 let Inst{20} = idx{0}; 8662 } 8663 8664 8665 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8666 FPR64Op, FPR32Op, V128, VectorIndexS, 8667 asm, ".s", "", "", ".s", 8668 [(set (i64 FPR64Op:$dst), 8669 (Accum (i64 FPR64Op:$Rd), 8670 (i64 (int_aarch64_neon_sqdmulls_scalar 8671 (i32 FPR32Op:$Rn), 8672 (i32 (vector_extract (v4i32 V128:$Rm), 8673 VectorIndexS:$idx))))))]> { 8674 8675 bits<2> idx; 8676 let Inst{11} = idx{1}; 8677 let Inst{21} = idx{0}; 8678 } 8679} 8680 8681multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8682 SDPatternOperator OpNode> { 8683 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8684 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8685 V128, V64, 8686 V128_lo, VectorIndexH, 8687 asm, ".4s", ".4s", ".4h", ".h", 8688 [(set (v4i32 V128:$Rd), 8689 (OpNode (v4i16 V64:$Rn), 8690 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8691 bits<3> idx; 8692 let Inst{11} = idx{2}; 8693 let Inst{21} = idx{1}; 8694 let Inst{20} = idx{0}; 8695 } 8696 8697 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8698 V128, V128, 8699 V128_lo, VectorIndexH, 8700 asm#"2", ".4s", ".4s", ".8h", ".h", 8701 [(set (v4i32 V128:$Rd), 8702 (OpNode (extract_high_v8i16 V128:$Rn), 8703 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8704 VectorIndexH:$idx))))]> { 8705 8706 bits<3> idx; 8707 let Inst{11} = idx{2}; 8708 let Inst{21} = idx{1}; 8709 let Inst{20} = idx{0}; 8710 } 8711 8712 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8713 V128, V64, 8714 V128, VectorIndexS, 8715 asm, ".2d", ".2d", ".2s", ".s", 8716 [(set (v2i64 V128:$Rd), 8717 (OpNode (v2i32 V64:$Rn), 8718 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8719 bits<2> idx; 8720 let Inst{11} = idx{1}; 8721 let Inst{21} = idx{0}; 8722 } 8723 8724 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8725 V128, V128, 8726 V128, VectorIndexS, 8727 asm#"2", ".2d", ".2d", ".4s", ".s", 8728 [(set (v2i64 V128:$Rd), 8729 (OpNode (extract_high_v4i32 V128:$Rn), 8730 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8731 VectorIndexS:$idx))))]> { 8732 bits<2> idx; 8733 let Inst{11} = idx{1}; 8734 let Inst{21} = idx{0}; 8735 } 8736 } 8737} 8738 8739multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8740 SDPatternOperator OpNode> { 8741 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8742 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8743 V128, V64, 8744 V128_lo, VectorIndexH, 8745 asm, ".4s", ".4s", ".4h", ".h", 8746 [(set (v4i32 V128:$dst), 8747 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8748 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8749 bits<3> idx; 8750 let Inst{11} = idx{2}; 8751 let Inst{21} = idx{1}; 8752 let Inst{20} = idx{0}; 8753 } 8754 8755 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8756 V128, V128, 8757 V128_lo, VectorIndexH, 8758 asm#"2", ".4s", ".4s", ".8h", ".h", 8759 [(set (v4i32 V128:$dst), 8760 (OpNode (v4i32 V128:$Rd), 8761 (extract_high_v8i16 V128:$Rn), 8762 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8763 VectorIndexH:$idx))))]> { 8764 bits<3> idx; 8765 let Inst{11} = idx{2}; 8766 let Inst{21} = idx{1}; 8767 let Inst{20} = idx{0}; 8768 } 8769 8770 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8771 V128, V64, 8772 V128, VectorIndexS, 8773 asm, ".2d", ".2d", ".2s", ".s", 8774 [(set (v2i64 V128:$dst), 8775 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8776 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8777 bits<2> idx; 8778 let Inst{11} = idx{1}; 8779 let Inst{21} = idx{0}; 8780 } 8781 8782 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8783 V128, V128, 8784 V128, VectorIndexS, 8785 asm#"2", ".2d", ".2d", ".4s", ".s", 8786 [(set (v2i64 V128:$dst), 8787 (OpNode (v2i64 V128:$Rd), 8788 (extract_high_v4i32 V128:$Rn), 8789 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8790 VectorIndexS:$idx))))]> { 8791 bits<2> idx; 8792 let Inst{11} = idx{1}; 8793 let Inst{21} = idx{0}; 8794 } 8795 } 8796} 8797 8798//---------------------------------------------------------------------------- 8799// AdvSIMD scalar shift by immediate 8800//---------------------------------------------------------------------------- 8801 8802let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8803class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8804 RegisterClass regtype1, RegisterClass regtype2, 8805 Operand immtype, string asm, list<dag> pattern> 8806 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8807 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8808 Sched<[WriteV]> { 8809 bits<5> Rd; 8810 bits<5> Rn; 8811 bits<7> imm; 8812 let Inst{31-30} = 0b01; 8813 let Inst{29} = U; 8814 let Inst{28-23} = 0b111110; 8815 let Inst{22-16} = fixed_imm; 8816 let Inst{15-11} = opc; 8817 let Inst{10} = 1; 8818 let Inst{9-5} = Rn; 8819 let Inst{4-0} = Rd; 8820} 8821 8822let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8823class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8824 RegisterClass regtype1, RegisterClass regtype2, 8825 Operand immtype, string asm, list<dag> pattern> 8826 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8827 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8828 Sched<[WriteV]> { 8829 bits<5> Rd; 8830 bits<5> Rn; 8831 bits<7> imm; 8832 let Inst{31-30} = 0b01; 8833 let Inst{29} = U; 8834 let Inst{28-23} = 0b111110; 8835 let Inst{22-16} = fixed_imm; 8836 let Inst{15-11} = opc; 8837 let Inst{10} = 1; 8838 let Inst{9-5} = Rn; 8839 let Inst{4-0} = Rd; 8840} 8841 8842 8843multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8844 let Predicates = [HasNEON, HasFullFP16] in { 8845 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8846 FPR16, FPR16, vecshiftR16, asm, []> { 8847 let Inst{19-16} = imm{3-0}; 8848 } 8849 } // Predicates = [HasNEON, HasFullFP16] 8850 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8851 FPR32, FPR32, vecshiftR32, asm, []> { 8852 let Inst{20-16} = imm{4-0}; 8853 } 8854 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8855 FPR64, FPR64, vecshiftR64, asm, []> { 8856 let Inst{21-16} = imm{5-0}; 8857 } 8858} 8859 8860multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8861 SDPatternOperator OpNode> { 8862 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8863 FPR64, FPR64, vecshiftR64, asm, 8864 [(set (i64 FPR64:$Rd), 8865 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8866 let Inst{21-16} = imm{5-0}; 8867 } 8868 8869 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8870 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8871} 8872 8873multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8874 SDPatternOperator OpNode = null_frag> { 8875 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8876 FPR64, FPR64, vecshiftR64, asm, 8877 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8878 (i32 vecshiftR64:$imm)))]> { 8879 let Inst{21-16} = imm{5-0}; 8880 } 8881 8882 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8883 (i32 vecshiftR64:$imm))), 8884 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8885 vecshiftR64:$imm)>; 8886} 8887 8888multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8889 SDPatternOperator OpNode> { 8890 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8891 FPR64, FPR64, vecshiftL64, asm, 8892 [(set (v1i64 FPR64:$Rd), 8893 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8894 let Inst{21-16} = imm{5-0}; 8895 } 8896} 8897 8898let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8899multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8900 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8901 FPR64, FPR64, vecshiftL64, asm, []> { 8902 let Inst{21-16} = imm{5-0}; 8903 } 8904} 8905 8906let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8907multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8908 SDPatternOperator OpNode = null_frag> { 8909 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8910 FPR8, FPR16, vecshiftR8, asm, []> { 8911 let Inst{18-16} = imm{2-0}; 8912 } 8913 8914 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8915 FPR16, FPR32, vecshiftR16, asm, []> { 8916 let Inst{19-16} = imm{3-0}; 8917 } 8918 8919 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8920 FPR32, FPR64, vecshiftR32, asm, 8921 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 8922 let Inst{20-16} = imm{4-0}; 8923 } 8924} 8925 8926multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 8927 SDPatternOperator OpNode> { 8928 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8929 FPR8, FPR8, vecshiftL8, asm, []> { 8930 let Inst{18-16} = imm{2-0}; 8931 } 8932 8933 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8934 FPR16, FPR16, vecshiftL16, asm, []> { 8935 let Inst{19-16} = imm{3-0}; 8936 } 8937 8938 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8939 FPR32, FPR32, vecshiftL32, asm, 8940 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 8941 let Inst{20-16} = imm{4-0}; 8942 } 8943 8944 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8945 FPR64, FPR64, vecshiftL64, asm, 8946 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8947 let Inst{21-16} = imm{5-0}; 8948 } 8949 8950 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8951 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8952} 8953 8954multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 8955 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8956 FPR8, FPR8, vecshiftR8, asm, []> { 8957 let Inst{18-16} = imm{2-0}; 8958 } 8959 8960 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8961 FPR16, FPR16, vecshiftR16, asm, []> { 8962 let Inst{19-16} = imm{3-0}; 8963 } 8964 8965 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8966 FPR32, FPR32, vecshiftR32, asm, []> { 8967 let Inst{20-16} = imm{4-0}; 8968 } 8969 8970 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8971 FPR64, FPR64, vecshiftR64, asm, []> { 8972 let Inst{21-16} = imm{5-0}; 8973 } 8974} 8975 8976//---------------------------------------------------------------------------- 8977// AdvSIMD vector x indexed element 8978//---------------------------------------------------------------------------- 8979 8980let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8981class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 8982 RegisterOperand dst_reg, RegisterOperand src_reg, 8983 Operand immtype, 8984 string asm, string dst_kind, string src_kind, 8985 list<dag> pattern> 8986 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 8987 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 8988 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 8989 Sched<[WriteV]> { 8990 bits<5> Rd; 8991 bits<5> Rn; 8992 let Inst{31} = 0; 8993 let Inst{30} = Q; 8994 let Inst{29} = U; 8995 let Inst{28-23} = 0b011110; 8996 let Inst{22-16} = fixed_imm; 8997 let Inst{15-11} = opc; 8998 let Inst{10} = 1; 8999 let Inst{9-5} = Rn; 9000 let Inst{4-0} = Rd; 9001} 9002 9003let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9004class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9005 RegisterOperand vectype1, RegisterOperand vectype2, 9006 Operand immtype, 9007 string asm, string dst_kind, string src_kind, 9008 list<dag> pattern> 9009 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9010 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9011 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9012 Sched<[WriteV]> { 9013 bits<5> Rd; 9014 bits<5> Rn; 9015 let Inst{31} = 0; 9016 let Inst{30} = Q; 9017 let Inst{29} = U; 9018 let Inst{28-23} = 0b011110; 9019 let Inst{22-16} = fixed_imm; 9020 let Inst{15-11} = opc; 9021 let Inst{10} = 1; 9022 let Inst{9-5} = Rn; 9023 let Inst{4-0} = Rd; 9024} 9025 9026multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9027 Intrinsic OpNode> { 9028 let Predicates = [HasNEON, HasFullFP16] in { 9029 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9030 V64, V64, vecshiftR16, 9031 asm, ".4h", ".4h", 9032 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9033 bits<4> imm; 9034 let Inst{19-16} = imm; 9035 } 9036 9037 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9038 V128, V128, vecshiftR16, 9039 asm, ".8h", ".8h", 9040 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9041 bits<4> imm; 9042 let Inst{19-16} = imm; 9043 } 9044 } // Predicates = [HasNEON, HasFullFP16] 9045 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9046 V64, V64, vecshiftR32, 9047 asm, ".2s", ".2s", 9048 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9049 bits<5> imm; 9050 let Inst{20-16} = imm; 9051 } 9052 9053 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9054 V128, V128, vecshiftR32, 9055 asm, ".4s", ".4s", 9056 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9057 bits<5> imm; 9058 let Inst{20-16} = imm; 9059 } 9060 9061 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9062 V128, V128, vecshiftR64, 9063 asm, ".2d", ".2d", 9064 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9065 bits<6> imm; 9066 let Inst{21-16} = imm; 9067 } 9068} 9069 9070multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9071 Intrinsic OpNode> { 9072 let Predicates = [HasNEON, HasFullFP16] in { 9073 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9074 V64, V64, vecshiftR16, 9075 asm, ".4h", ".4h", 9076 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9077 bits<4> imm; 9078 let Inst{19-16} = imm; 9079 } 9080 9081 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9082 V128, V128, vecshiftR16, 9083 asm, ".8h", ".8h", 9084 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9085 bits<4> imm; 9086 let Inst{19-16} = imm; 9087 } 9088 } // Predicates = [HasNEON, HasFullFP16] 9089 9090 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9091 V64, V64, vecshiftR32, 9092 asm, ".2s", ".2s", 9093 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9094 bits<5> imm; 9095 let Inst{20-16} = imm; 9096 } 9097 9098 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9099 V128, V128, vecshiftR32, 9100 asm, ".4s", ".4s", 9101 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9102 bits<5> imm; 9103 let Inst{20-16} = imm; 9104 } 9105 9106 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9107 V128, V128, vecshiftR64, 9108 asm, ".2d", ".2d", 9109 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9110 bits<6> imm; 9111 let Inst{21-16} = imm; 9112 } 9113} 9114 9115multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9116 SDPatternOperator OpNode> { 9117 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9118 V64, V128, vecshiftR16Narrow, 9119 asm, ".8b", ".8h", 9120 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9121 bits<3> imm; 9122 let Inst{18-16} = imm; 9123 } 9124 9125 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9126 V128, V128, vecshiftR16Narrow, 9127 asm#"2", ".16b", ".8h", []> { 9128 bits<3> imm; 9129 let Inst{18-16} = imm; 9130 let hasSideEffects = 0; 9131 } 9132 9133 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9134 V64, V128, vecshiftR32Narrow, 9135 asm, ".4h", ".4s", 9136 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9137 bits<4> imm; 9138 let Inst{19-16} = imm; 9139 } 9140 9141 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9142 V128, V128, vecshiftR32Narrow, 9143 asm#"2", ".8h", ".4s", []> { 9144 bits<4> imm; 9145 let Inst{19-16} = imm; 9146 let hasSideEffects = 0; 9147 } 9148 9149 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9150 V64, V128, vecshiftR64Narrow, 9151 asm, ".2s", ".2d", 9152 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9153 bits<5> imm; 9154 let Inst{20-16} = imm; 9155 } 9156 9157 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9158 V128, V128, vecshiftR64Narrow, 9159 asm#"2", ".4s", ".2d", []> { 9160 bits<5> imm; 9161 let Inst{20-16} = imm; 9162 let hasSideEffects = 0; 9163 } 9164 9165 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9166 // themselves, so put them here instead. 9167 9168 // Patterns involving what's effectively an insert high and a normal 9169 // intrinsic, represented by CONCAT_VECTORS. 9170 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9171 vecshiftR16Narrow:$imm)), 9172 (!cast<Instruction>(NAME # "v16i8_shift") 9173 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9174 V128:$Rn, vecshiftR16Narrow:$imm)>; 9175 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9176 vecshiftR32Narrow:$imm)), 9177 (!cast<Instruction>(NAME # "v8i16_shift") 9178 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9179 V128:$Rn, vecshiftR32Narrow:$imm)>; 9180 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9181 vecshiftR64Narrow:$imm)), 9182 (!cast<Instruction>(NAME # "v4i32_shift") 9183 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9184 V128:$Rn, vecshiftR64Narrow:$imm)>; 9185} 9186 9187multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9188 SDPatternOperator OpNode> { 9189 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9190 V64, V64, vecshiftL8, 9191 asm, ".8b", ".8b", 9192 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9193 (i32 vecshiftL8:$imm)))]> { 9194 bits<3> imm; 9195 let Inst{18-16} = imm; 9196 } 9197 9198 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9199 V128, V128, vecshiftL8, 9200 asm, ".16b", ".16b", 9201 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9202 (i32 vecshiftL8:$imm)))]> { 9203 bits<3> imm; 9204 let Inst{18-16} = imm; 9205 } 9206 9207 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9208 V64, V64, vecshiftL16, 9209 asm, ".4h", ".4h", 9210 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9211 (i32 vecshiftL16:$imm)))]> { 9212 bits<4> imm; 9213 let Inst{19-16} = imm; 9214 } 9215 9216 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9217 V128, V128, vecshiftL16, 9218 asm, ".8h", ".8h", 9219 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9220 (i32 vecshiftL16:$imm)))]> { 9221 bits<4> imm; 9222 let Inst{19-16} = imm; 9223 } 9224 9225 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9226 V64, V64, vecshiftL32, 9227 asm, ".2s", ".2s", 9228 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9229 (i32 vecshiftL32:$imm)))]> { 9230 bits<5> imm; 9231 let Inst{20-16} = imm; 9232 } 9233 9234 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9235 V128, V128, vecshiftL32, 9236 asm, ".4s", ".4s", 9237 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9238 (i32 vecshiftL32:$imm)))]> { 9239 bits<5> imm; 9240 let Inst{20-16} = imm; 9241 } 9242 9243 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9244 V128, V128, vecshiftL64, 9245 asm, ".2d", ".2d", 9246 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9247 (i32 vecshiftL64:$imm)))]> { 9248 bits<6> imm; 9249 let Inst{21-16} = imm; 9250 } 9251} 9252 9253multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9254 SDPatternOperator OpNode> { 9255 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9256 V64, V64, vecshiftR8, 9257 asm, ".8b", ".8b", 9258 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9259 (i32 vecshiftR8:$imm)))]> { 9260 bits<3> imm; 9261 let Inst{18-16} = imm; 9262 } 9263 9264 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9265 V128, V128, vecshiftR8, 9266 asm, ".16b", ".16b", 9267 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9268 (i32 vecshiftR8:$imm)))]> { 9269 bits<3> imm; 9270 let Inst{18-16} = imm; 9271 } 9272 9273 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9274 V64, V64, vecshiftR16, 9275 asm, ".4h", ".4h", 9276 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9277 (i32 vecshiftR16:$imm)))]> { 9278 bits<4> imm; 9279 let Inst{19-16} = imm; 9280 } 9281 9282 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9283 V128, V128, vecshiftR16, 9284 asm, ".8h", ".8h", 9285 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9286 (i32 vecshiftR16:$imm)))]> { 9287 bits<4> imm; 9288 let Inst{19-16} = imm; 9289 } 9290 9291 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9292 V64, V64, vecshiftR32, 9293 asm, ".2s", ".2s", 9294 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9295 (i32 vecshiftR32:$imm)))]> { 9296 bits<5> imm; 9297 let Inst{20-16} = imm; 9298 } 9299 9300 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9301 V128, V128, vecshiftR32, 9302 asm, ".4s", ".4s", 9303 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9304 (i32 vecshiftR32:$imm)))]> { 9305 bits<5> imm; 9306 let Inst{20-16} = imm; 9307 } 9308 9309 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9310 V128, V128, vecshiftR64, 9311 asm, ".2d", ".2d", 9312 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9313 (i32 vecshiftR64:$imm)))]> { 9314 bits<6> imm; 9315 let Inst{21-16} = imm; 9316 } 9317} 9318 9319let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9320multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9321 SDPatternOperator OpNode = null_frag> { 9322 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9323 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9324 [(set (v8i8 V64:$dst), 9325 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9326 (i32 vecshiftR8:$imm)))]> { 9327 bits<3> imm; 9328 let Inst{18-16} = imm; 9329 } 9330 9331 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9332 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9333 [(set (v16i8 V128:$dst), 9334 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9335 (i32 vecshiftR8:$imm)))]> { 9336 bits<3> imm; 9337 let Inst{18-16} = imm; 9338 } 9339 9340 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9341 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9342 [(set (v4i16 V64:$dst), 9343 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9344 (i32 vecshiftR16:$imm)))]> { 9345 bits<4> imm; 9346 let Inst{19-16} = imm; 9347 } 9348 9349 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9350 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9351 [(set (v8i16 V128:$dst), 9352 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9353 (i32 vecshiftR16:$imm)))]> { 9354 bits<4> imm; 9355 let Inst{19-16} = imm; 9356 } 9357 9358 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9359 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9360 [(set (v2i32 V64:$dst), 9361 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9362 (i32 vecshiftR32:$imm)))]> { 9363 bits<5> imm; 9364 let Inst{20-16} = imm; 9365 } 9366 9367 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9368 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9369 [(set (v4i32 V128:$dst), 9370 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9371 (i32 vecshiftR32:$imm)))]> { 9372 bits<5> imm; 9373 let Inst{20-16} = imm; 9374 } 9375 9376 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9377 V128, V128, vecshiftR64, 9378 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9379 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9380 (i32 vecshiftR64:$imm)))]> { 9381 bits<6> imm; 9382 let Inst{21-16} = imm; 9383 } 9384} 9385 9386multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9387 SDPatternOperator OpNode = null_frag> { 9388 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9389 V64, V64, vecshiftL8, 9390 asm, ".8b", ".8b", 9391 [(set (v8i8 V64:$dst), 9392 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9393 (i32 vecshiftL8:$imm)))]> { 9394 bits<3> imm; 9395 let Inst{18-16} = imm; 9396 } 9397 9398 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9399 V128, V128, vecshiftL8, 9400 asm, ".16b", ".16b", 9401 [(set (v16i8 V128:$dst), 9402 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9403 (i32 vecshiftL8:$imm)))]> { 9404 bits<3> imm; 9405 let Inst{18-16} = imm; 9406 } 9407 9408 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9409 V64, V64, vecshiftL16, 9410 asm, ".4h", ".4h", 9411 [(set (v4i16 V64:$dst), 9412 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9413 (i32 vecshiftL16:$imm)))]> { 9414 bits<4> imm; 9415 let Inst{19-16} = imm; 9416 } 9417 9418 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9419 V128, V128, vecshiftL16, 9420 asm, ".8h", ".8h", 9421 [(set (v8i16 V128:$dst), 9422 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9423 (i32 vecshiftL16:$imm)))]> { 9424 bits<4> imm; 9425 let Inst{19-16} = imm; 9426 } 9427 9428 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9429 V64, V64, vecshiftL32, 9430 asm, ".2s", ".2s", 9431 [(set (v2i32 V64:$dst), 9432 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9433 (i32 vecshiftL32:$imm)))]> { 9434 bits<5> imm; 9435 let Inst{20-16} = imm; 9436 } 9437 9438 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9439 V128, V128, vecshiftL32, 9440 asm, ".4s", ".4s", 9441 [(set (v4i32 V128:$dst), 9442 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9443 (i32 vecshiftL32:$imm)))]> { 9444 bits<5> imm; 9445 let Inst{20-16} = imm; 9446 } 9447 9448 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9449 V128, V128, vecshiftL64, 9450 asm, ".2d", ".2d", 9451 [(set (v2i64 V128:$dst), 9452 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9453 (i32 vecshiftL64:$imm)))]> { 9454 bits<6> imm; 9455 let Inst{21-16} = imm; 9456 } 9457} 9458 9459multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9460 SDPatternOperator OpNode> { 9461 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9462 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9463 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9464 bits<3> imm; 9465 let Inst{18-16} = imm; 9466 } 9467 9468 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9469 V128, V128, vecshiftL8, 9470 asm#"2", ".8h", ".16b", 9471 [(set (v8i16 V128:$Rd), 9472 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 9473 bits<3> imm; 9474 let Inst{18-16} = imm; 9475 } 9476 9477 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9478 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9479 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9480 bits<4> imm; 9481 let Inst{19-16} = imm; 9482 } 9483 9484 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9485 V128, V128, vecshiftL16, 9486 asm#"2", ".4s", ".8h", 9487 [(set (v4i32 V128:$Rd), 9488 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 9489 9490 bits<4> imm; 9491 let Inst{19-16} = imm; 9492 } 9493 9494 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9495 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9496 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9497 bits<5> imm; 9498 let Inst{20-16} = imm; 9499 } 9500 9501 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9502 V128, V128, vecshiftL32, 9503 asm#"2", ".2d", ".4s", 9504 [(set (v2i64 V128:$Rd), 9505 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9506 bits<5> imm; 9507 let Inst{20-16} = imm; 9508 } 9509} 9510 9511 9512//--- 9513// Vector load/store 9514//--- 9515// SIMD ldX/stX no-index memory references don't allow the optional 9516// ", #0" constant and handle post-indexing explicitly, so we use 9517// a more specialized parse method for them. Otherwise, it's the same as 9518// the general GPR64sp handling. 9519 9520class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9521 string asm, dag oops, dag iops, list<dag> pattern> 9522 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9523 bits<5> Vt; 9524 bits<5> Rn; 9525 let Inst{31} = 0; 9526 let Inst{30} = Q; 9527 let Inst{29-23} = 0b0011000; 9528 let Inst{22} = L; 9529 let Inst{21-16} = 0b000000; 9530 let Inst{15-12} = opcode; 9531 let Inst{11-10} = size; 9532 let Inst{9-5} = Rn; 9533 let Inst{4-0} = Vt; 9534} 9535 9536class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9537 string asm, dag oops, dag iops> 9538 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9539 bits<5> Vt; 9540 bits<5> Rn; 9541 bits<5> Xm; 9542 let Inst{31} = 0; 9543 let Inst{30} = Q; 9544 let Inst{29-23} = 0b0011001; 9545 let Inst{22} = L; 9546 let Inst{21} = 0; 9547 let Inst{20-16} = Xm; 9548 let Inst{15-12} = opcode; 9549 let Inst{11-10} = size; 9550 let Inst{9-5} = Rn; 9551 let Inst{4-0} = Vt; 9552} 9553 9554// The immediate form of AdvSIMD post-indexed addressing is encoded with 9555// register post-index addressing from the zero register. 9556multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9557 int Offset, int Size> { 9558 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9559 // "ld1\t$Vt, [$Rn], #16" 9560 // may get mapped to 9561 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9562 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9563 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9564 GPR64sp:$Rn, 9565 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9566 XZR), 1>; 9567 9568 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9569 // "ld1.8b\t$Vt, [$Rn], #16" 9570 // may get mapped to 9571 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9572 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9573 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9574 GPR64sp:$Rn, 9575 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9576 XZR), 0>; 9577 9578 // E.g. "ld1.8b { v0, v1 }, [x1]" 9579 // "ld1\t$Vt, [$Rn]" 9580 // may get mapped to 9581 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9582 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9583 (!cast<Instruction>(BaseName # Count # "v" # layout) 9584 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9585 GPR64sp:$Rn), 0>; 9586 9587 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9588 // "ld1\t$Vt, [$Rn], $Xm" 9589 // may get mapped to 9590 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9591 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9592 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9593 GPR64sp:$Rn, 9594 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9595 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9596} 9597 9598multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9599 int Offset128, int Offset64, bits<4> opcode> { 9600 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9601 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9602 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9603 (ins GPR64sp:$Rn), []>; 9604 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9605 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9606 (ins GPR64sp:$Rn), []>; 9607 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9608 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9609 (ins GPR64sp:$Rn), []>; 9610 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9611 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9612 (ins GPR64sp:$Rn), []>; 9613 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9614 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9615 (ins GPR64sp:$Rn), []>; 9616 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9617 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9618 (ins GPR64sp:$Rn), []>; 9619 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9620 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9621 (ins GPR64sp:$Rn), []>; 9622 9623 9624 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9625 (outs GPR64sp:$wback, 9626 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9627 (ins GPR64sp:$Rn, 9628 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9629 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9630 (outs GPR64sp:$wback, 9631 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9632 (ins GPR64sp:$Rn, 9633 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9634 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9635 (outs GPR64sp:$wback, 9636 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9637 (ins GPR64sp:$Rn, 9638 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9639 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9640 (outs GPR64sp:$wback, 9641 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9642 (ins GPR64sp:$Rn, 9643 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9644 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9645 (outs GPR64sp:$wback, 9646 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9647 (ins GPR64sp:$Rn, 9648 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9649 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9650 (outs GPR64sp:$wback, 9651 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9652 (ins GPR64sp:$Rn, 9653 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9654 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9655 (outs GPR64sp:$wback, 9656 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9657 (ins GPR64sp:$Rn, 9658 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9659 } 9660 9661 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9662 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9663 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9664 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9665 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9666 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9667 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9668} 9669 9670// Only ld1/st1 has a v1d version. 9671multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9672 int Offset128, int Offset64, bits<4> opcode> { 9673 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9674 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9675 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9676 GPR64sp:$Rn), []>; 9677 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9678 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9679 GPR64sp:$Rn), []>; 9680 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9681 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9682 GPR64sp:$Rn), []>; 9683 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9684 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9685 GPR64sp:$Rn), []>; 9686 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9687 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9688 GPR64sp:$Rn), []>; 9689 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9690 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9691 GPR64sp:$Rn), []>; 9692 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9693 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9694 GPR64sp:$Rn), []>; 9695 9696 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9697 (outs GPR64sp:$wback), 9698 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9699 GPR64sp:$Rn, 9700 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9701 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9702 (outs GPR64sp:$wback), 9703 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9704 GPR64sp:$Rn, 9705 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9706 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9707 (outs GPR64sp:$wback), 9708 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9709 GPR64sp:$Rn, 9710 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9711 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9712 (outs GPR64sp:$wback), 9713 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9714 GPR64sp:$Rn, 9715 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9716 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9717 (outs GPR64sp:$wback), 9718 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9719 GPR64sp:$Rn, 9720 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9721 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9722 (outs GPR64sp:$wback), 9723 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9724 GPR64sp:$Rn, 9725 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9726 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9727 (outs GPR64sp:$wback), 9728 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9729 GPR64sp:$Rn, 9730 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9731 } 9732 9733 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9734 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9735 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9736 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9737 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9738 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9739 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9740} 9741 9742multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9743 int Offset128, int Offset64, bits<4> opcode> 9744 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9745 9746 // LD1 instructions have extra "1d" variants. 9747 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9748 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9749 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9750 (ins GPR64sp:$Rn), []>; 9751 9752 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9753 (outs GPR64sp:$wback, 9754 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9755 (ins GPR64sp:$Rn, 9756 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9757 } 9758 9759 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9760} 9761 9762multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9763 int Offset128, int Offset64, bits<4> opcode> 9764 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9765 9766 // ST1 instructions have extra "1d" variants. 9767 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9768 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9769 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9770 GPR64sp:$Rn), []>; 9771 9772 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9773 (outs GPR64sp:$wback), 9774 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9775 GPR64sp:$Rn, 9776 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9777 } 9778 9779 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9780} 9781 9782multiclass SIMDLd1Multiple<string asm> { 9783 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9784 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9785 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9786 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9787} 9788 9789multiclass SIMDSt1Multiple<string asm> { 9790 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9791 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9792 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9793 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9794} 9795 9796multiclass SIMDLd2Multiple<string asm> { 9797 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9798} 9799 9800multiclass SIMDSt2Multiple<string asm> { 9801 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9802} 9803 9804multiclass SIMDLd3Multiple<string asm> { 9805 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9806} 9807 9808multiclass SIMDSt3Multiple<string asm> { 9809 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9810} 9811 9812multiclass SIMDLd4Multiple<string asm> { 9813 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9814} 9815 9816multiclass SIMDSt4Multiple<string asm> { 9817 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9818} 9819 9820//--- 9821// AdvSIMD Load/store single-element 9822//--- 9823 9824class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9825 string asm, string operands, string cst, 9826 dag oops, dag iops, list<dag> pattern> 9827 : I<oops, iops, asm, operands, cst, pattern> { 9828 bits<5> Vt; 9829 bits<5> Rn; 9830 let Inst{31} = 0; 9831 let Inst{29-24} = 0b001101; 9832 let Inst{22} = L; 9833 let Inst{21} = R; 9834 let Inst{15-13} = opcode; 9835 let Inst{9-5} = Rn; 9836 let Inst{4-0} = Vt; 9837} 9838 9839class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9840 string asm, string operands, string cst, 9841 dag oops, dag iops, list<dag> pattern> 9842 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9843 bits<5> Vt; 9844 bits<5> Rn; 9845 let Inst{31} = 0; 9846 let Inst{29-24} = 0b001101; 9847 let Inst{22} = L; 9848 let Inst{21} = R; 9849 let Inst{15-13} = opcode; 9850 let Inst{9-5} = Rn; 9851 let Inst{4-0} = Vt; 9852} 9853 9854 9855let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9856class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9857 DAGOperand listtype> 9858 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9859 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9860 []> { 9861 let Inst{30} = Q; 9862 let Inst{23} = 0; 9863 let Inst{20-16} = 0b00000; 9864 let Inst{12} = S; 9865 let Inst{11-10} = size; 9866} 9867let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9868class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9869 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9870 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9871 "$Rn = $wback", 9872 (outs GPR64sp:$wback, listtype:$Vt), 9873 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9874 bits<5> Xm; 9875 let Inst{30} = Q; 9876 let Inst{23} = 1; 9877 let Inst{20-16} = Xm; 9878 let Inst{12} = S; 9879 let Inst{11-10} = size; 9880} 9881 9882multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9883 int Offset, int Size> { 9884 // E.g. "ld1r { v0.8b }, [x1], #1" 9885 // "ld1r.8b\t$Vt, [$Rn], #1" 9886 // may get mapped to 9887 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9888 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9889 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9890 GPR64sp:$Rn, 9891 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9892 XZR), 1>; 9893 9894 // E.g. "ld1r.8b { v0 }, [x1], #1" 9895 // "ld1r.8b\t$Vt, [$Rn], #1" 9896 // may get mapped to 9897 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9898 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9899 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9900 GPR64sp:$Rn, 9901 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9902 XZR), 0>; 9903 9904 // E.g. "ld1r.8b { v0 }, [x1]" 9905 // "ld1r.8b\t$Vt, [$Rn]" 9906 // may get mapped to 9907 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9908 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9909 (!cast<Instruction>(BaseName # "v" # layout) 9910 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9911 GPR64sp:$Rn), 0>; 9912 9913 // E.g. "ld1r.8b { v0 }, [x1], x2" 9914 // "ld1r.8b\t$Vt, [$Rn], $Xm" 9915 // may get mapped to 9916 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9917 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9918 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9919 GPR64sp:$Rn, 9920 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9921 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9922} 9923 9924multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 9925 int Offset1, int Offset2, int Offset4, int Offset8> { 9926 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 9927 !cast<DAGOperand>("VecList" # Count # "8b")>; 9928 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 9929 !cast<DAGOperand>("VecList" # Count #"16b")>; 9930 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 9931 !cast<DAGOperand>("VecList" # Count #"4h")>; 9932 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 9933 !cast<DAGOperand>("VecList" # Count #"8h")>; 9934 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 9935 !cast<DAGOperand>("VecList" # Count #"2s")>; 9936 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 9937 !cast<DAGOperand>("VecList" # Count #"4s")>; 9938 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 9939 !cast<DAGOperand>("VecList" # Count #"1d")>; 9940 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 9941 !cast<DAGOperand>("VecList" # Count #"2d")>; 9942 9943 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 9944 !cast<DAGOperand>("VecList" # Count # "8b"), 9945 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9946 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 9947 !cast<DAGOperand>("VecList" # Count # "16b"), 9948 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9949 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 9950 !cast<DAGOperand>("VecList" # Count # "4h"), 9951 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9952 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 9953 !cast<DAGOperand>("VecList" # Count # "8h"), 9954 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9955 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 9956 !cast<DAGOperand>("VecList" # Count # "2s"), 9957 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9958 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 9959 !cast<DAGOperand>("VecList" # Count # "4s"), 9960 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9961 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 9962 !cast<DAGOperand>("VecList" # Count # "1d"), 9963 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9964 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 9965 !cast<DAGOperand>("VecList" # Count # "2d"), 9966 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9967 9968 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 9969 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 9970 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 9971 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 9972 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 9973 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 9974 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 9975 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 9976} 9977 9978class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 9979 dag oops, dag iops, list<dag> pattern> 9980 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9981 pattern> { 9982 // idx encoded in Q:S:size fields. 9983 bits<4> idx; 9984 let Inst{30} = idx{3}; 9985 let Inst{23} = 0; 9986 let Inst{20-16} = 0b00000; 9987 let Inst{12} = idx{2}; 9988 let Inst{11-10} = idx{1-0}; 9989} 9990class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 9991 dag oops, dag iops, list<dag> pattern> 9992 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9993 oops, iops, pattern> { 9994 // idx encoded in Q:S:size fields. 9995 bits<4> idx; 9996 let Inst{30} = idx{3}; 9997 let Inst{23} = 0; 9998 let Inst{20-16} = 0b00000; 9999 let Inst{12} = idx{2}; 10000 let Inst{11-10} = idx{1-0}; 10001} 10002class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10003 dag oops, dag iops> 10004 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10005 "$Rn = $wback", oops, iops, []> { 10006 // idx encoded in Q:S:size fields. 10007 bits<4> idx; 10008 bits<5> Xm; 10009 let Inst{30} = idx{3}; 10010 let Inst{23} = 1; 10011 let Inst{20-16} = Xm; 10012 let Inst{12} = idx{2}; 10013 let Inst{11-10} = idx{1-0}; 10014} 10015class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10016 dag oops, dag iops> 10017 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10018 "$Rn = $wback", oops, iops, []> { 10019 // idx encoded in Q:S:size fields. 10020 bits<4> idx; 10021 bits<5> Xm; 10022 let Inst{30} = idx{3}; 10023 let Inst{23} = 1; 10024 let Inst{20-16} = Xm; 10025 let Inst{12} = idx{2}; 10026 let Inst{11-10} = idx{1-0}; 10027} 10028 10029class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10030 dag oops, dag iops, list<dag> pattern> 10031 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10032 pattern> { 10033 // idx encoded in Q:S:size<1> fields. 10034 bits<3> idx; 10035 let Inst{30} = idx{2}; 10036 let Inst{23} = 0; 10037 let Inst{20-16} = 0b00000; 10038 let Inst{12} = idx{1}; 10039 let Inst{11} = idx{0}; 10040 let Inst{10} = size; 10041} 10042class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10043 dag oops, dag iops, list<dag> pattern> 10044 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10045 oops, iops, pattern> { 10046 // idx encoded in Q:S:size<1> fields. 10047 bits<3> idx; 10048 let Inst{30} = idx{2}; 10049 let Inst{23} = 0; 10050 let Inst{20-16} = 0b00000; 10051 let Inst{12} = idx{1}; 10052 let Inst{11} = idx{0}; 10053 let Inst{10} = size; 10054} 10055 10056class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10057 dag oops, dag iops> 10058 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10059 "$Rn = $wback", oops, iops, []> { 10060 // idx encoded in Q:S:size<1> fields. 10061 bits<3> idx; 10062 bits<5> Xm; 10063 let Inst{30} = idx{2}; 10064 let Inst{23} = 1; 10065 let Inst{20-16} = Xm; 10066 let Inst{12} = idx{1}; 10067 let Inst{11} = idx{0}; 10068 let Inst{10} = size; 10069} 10070class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10071 dag oops, dag iops> 10072 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10073 "$Rn = $wback", oops, iops, []> { 10074 // idx encoded in Q:S:size<1> fields. 10075 bits<3> idx; 10076 bits<5> Xm; 10077 let Inst{30} = idx{2}; 10078 let Inst{23} = 1; 10079 let Inst{20-16} = Xm; 10080 let Inst{12} = idx{1}; 10081 let Inst{11} = idx{0}; 10082 let Inst{10} = size; 10083} 10084class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10085 dag oops, dag iops, list<dag> pattern> 10086 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10087 pattern> { 10088 // idx encoded in Q:S fields. 10089 bits<2> idx; 10090 let Inst{30} = idx{1}; 10091 let Inst{23} = 0; 10092 let Inst{20-16} = 0b00000; 10093 let Inst{12} = idx{0}; 10094 let Inst{11-10} = size; 10095} 10096class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10097 dag oops, dag iops, list<dag> pattern> 10098 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10099 oops, iops, pattern> { 10100 // idx encoded in Q:S fields. 10101 bits<2> idx; 10102 let Inst{30} = idx{1}; 10103 let Inst{23} = 0; 10104 let Inst{20-16} = 0b00000; 10105 let Inst{12} = idx{0}; 10106 let Inst{11-10} = size; 10107} 10108class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10109 string asm, dag oops, dag iops> 10110 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10111 "$Rn = $wback", oops, iops, []> { 10112 // idx encoded in Q:S fields. 10113 bits<2> idx; 10114 bits<5> Xm; 10115 let Inst{30} = idx{1}; 10116 let Inst{23} = 1; 10117 let Inst{20-16} = Xm; 10118 let Inst{12} = idx{0}; 10119 let Inst{11-10} = size; 10120} 10121class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10122 string asm, dag oops, dag iops> 10123 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10124 "$Rn = $wback", oops, iops, []> { 10125 // idx encoded in Q:S fields. 10126 bits<2> idx; 10127 bits<5> Xm; 10128 let Inst{30} = idx{1}; 10129 let Inst{23} = 1; 10130 let Inst{20-16} = Xm; 10131 let Inst{12} = idx{0}; 10132 let Inst{11-10} = size; 10133} 10134class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10135 dag oops, dag iops, list<dag> pattern> 10136 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10137 pattern> { 10138 // idx encoded in Q field. 10139 bits<1> idx; 10140 let Inst{30} = idx; 10141 let Inst{23} = 0; 10142 let Inst{20-16} = 0b00000; 10143 let Inst{12} = 0; 10144 let Inst{11-10} = size; 10145} 10146class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10147 dag oops, dag iops, list<dag> pattern> 10148 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10149 oops, iops, pattern> { 10150 // idx encoded in Q field. 10151 bits<1> idx; 10152 let Inst{30} = idx; 10153 let Inst{23} = 0; 10154 let Inst{20-16} = 0b00000; 10155 let Inst{12} = 0; 10156 let Inst{11-10} = size; 10157} 10158class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10159 string asm, dag oops, dag iops> 10160 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10161 "$Rn = $wback", oops, iops, []> { 10162 // idx encoded in Q field. 10163 bits<1> idx; 10164 bits<5> Xm; 10165 let Inst{30} = idx; 10166 let Inst{23} = 1; 10167 let Inst{20-16} = Xm; 10168 let Inst{12} = 0; 10169 let Inst{11-10} = size; 10170} 10171class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10172 string asm, dag oops, dag iops> 10173 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10174 "$Rn = $wback", oops, iops, []> { 10175 // idx encoded in Q field. 10176 bits<1> idx; 10177 bits<5> Xm; 10178 let Inst{30} = idx; 10179 let Inst{23} = 1; 10180 let Inst{20-16} = Xm; 10181 let Inst{12} = 0; 10182 let Inst{11-10} = size; 10183} 10184 10185let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10186multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10187 RegisterOperand listtype, 10188 RegisterOperand GPR64pi> { 10189 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10190 (outs listtype:$dst), 10191 (ins listtype:$Vt, VectorIndexB:$idx, 10192 GPR64sp:$Rn), []>; 10193 10194 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10195 (outs GPR64sp:$wback, listtype:$dst), 10196 (ins listtype:$Vt, VectorIndexB:$idx, 10197 GPR64sp:$Rn, GPR64pi:$Xm)>; 10198} 10199let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10200multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10201 RegisterOperand listtype, 10202 RegisterOperand GPR64pi> { 10203 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10204 (outs listtype:$dst), 10205 (ins listtype:$Vt, VectorIndexH:$idx, 10206 GPR64sp:$Rn), []>; 10207 10208 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10209 (outs GPR64sp:$wback, listtype:$dst), 10210 (ins listtype:$Vt, VectorIndexH:$idx, 10211 GPR64sp:$Rn, GPR64pi:$Xm)>; 10212} 10213let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10214multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10215 RegisterOperand listtype, 10216 RegisterOperand GPR64pi> { 10217 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10218 (outs listtype:$dst), 10219 (ins listtype:$Vt, VectorIndexS:$idx, 10220 GPR64sp:$Rn), []>; 10221 10222 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10223 (outs GPR64sp:$wback, listtype:$dst), 10224 (ins listtype:$Vt, VectorIndexS:$idx, 10225 GPR64sp:$Rn, GPR64pi:$Xm)>; 10226} 10227let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10228multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10229 RegisterOperand listtype, RegisterOperand GPR64pi> { 10230 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10231 (outs listtype:$dst), 10232 (ins listtype:$Vt, VectorIndexD:$idx, 10233 GPR64sp:$Rn), []>; 10234 10235 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10236 (outs GPR64sp:$wback, listtype:$dst), 10237 (ins listtype:$Vt, VectorIndexD:$idx, 10238 GPR64sp:$Rn, GPR64pi:$Xm)>; 10239} 10240let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10241multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10242 RegisterOperand listtype, RegisterOperand GPR64pi> { 10243 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10244 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10245 GPR64sp:$Rn), []>; 10246 10247 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10248 (outs GPR64sp:$wback), 10249 (ins listtype:$Vt, VectorIndexB:$idx, 10250 GPR64sp:$Rn, GPR64pi:$Xm)>; 10251} 10252let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10253multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10254 RegisterOperand listtype, RegisterOperand GPR64pi> { 10255 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10256 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10257 GPR64sp:$Rn), []>; 10258 10259 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10260 (outs GPR64sp:$wback), 10261 (ins listtype:$Vt, VectorIndexH:$idx, 10262 GPR64sp:$Rn, GPR64pi:$Xm)>; 10263} 10264let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10265multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10266 RegisterOperand listtype, RegisterOperand GPR64pi> { 10267 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10268 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10269 GPR64sp:$Rn), []>; 10270 10271 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10272 (outs GPR64sp:$wback), 10273 (ins listtype:$Vt, VectorIndexS:$idx, 10274 GPR64sp:$Rn, GPR64pi:$Xm)>; 10275} 10276let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10277multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10278 RegisterOperand listtype, RegisterOperand GPR64pi> { 10279 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10280 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10281 GPR64sp:$Rn), []>; 10282 10283 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10284 (outs GPR64sp:$wback), 10285 (ins listtype:$Vt, VectorIndexD:$idx, 10286 GPR64sp:$Rn, GPR64pi:$Xm)>; 10287} 10288 10289multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10290 string Count, int Offset, Operand idxtype> { 10291 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10292 // "ld1\t$Vt, [$Rn], #1" 10293 // may get mapped to 10294 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10295 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10296 (!cast<Instruction>(NAME # Type # "_POST") 10297 GPR64sp:$Rn, 10298 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10299 idxtype:$idx, XZR), 1>; 10300 10301 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10302 // "ld1.8b\t$Vt, [$Rn], #1" 10303 // may get mapped to 10304 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10305 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10306 (!cast<Instruction>(NAME # Type # "_POST") 10307 GPR64sp:$Rn, 10308 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10309 idxtype:$idx, XZR), 0>; 10310 10311 // E.g. "ld1.8b { v0 }[0], [x1]" 10312 // "ld1.8b\t$Vt, [$Rn]" 10313 // may get mapped to 10314 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10315 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10316 (!cast<Instruction>(NAME # Type) 10317 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10318 idxtype:$idx, GPR64sp:$Rn), 0>; 10319 10320 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10321 // "ld1.8b\t$Vt, [$Rn], $Xm" 10322 // may get mapped to 10323 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10324 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10325 (!cast<Instruction>(NAME # Type # "_POST") 10326 GPR64sp:$Rn, 10327 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10328 idxtype:$idx, 10329 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10330} 10331 10332multiclass SIMDLdSt1SingleAliases<string asm> { 10333 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10334 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10335 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10336 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10337} 10338 10339multiclass SIMDLdSt2SingleAliases<string asm> { 10340 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10341 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10342 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10343 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10344} 10345 10346multiclass SIMDLdSt3SingleAliases<string asm> { 10347 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10348 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10349 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10350 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10351} 10352 10353multiclass SIMDLdSt4SingleAliases<string asm> { 10354 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10355 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10356 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10357 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10358} 10359} // end of 'let Predicates = [HasNEON]' 10360 10361//---------------------------------------------------------------------------- 10362// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10363//---------------------------------------------------------------------------- 10364 10365let Predicates = [HasNEON, HasRDM] in { 10366 10367class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10368 RegisterOperand regtype, string asm, 10369 string kind, list<dag> pattern> 10370 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10371 pattern> { 10372} 10373multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10374 SDPatternOperator Accum> { 10375 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10376 [(set (v4i16 V64:$dst), 10377 (Accum (v4i16 V64:$Rd), 10378 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 10379 (v4i16 V64:$Rm)))))]>; 10380 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10381 [(set (v8i16 V128:$dst), 10382 (Accum (v8i16 V128:$Rd), 10383 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 10384 (v8i16 V128:$Rm)))))]>; 10385 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10386 [(set (v2i32 V64:$dst), 10387 (Accum (v2i32 V64:$Rd), 10388 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 10389 (v2i32 V64:$Rm)))))]>; 10390 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10391 [(set (v4i32 V128:$dst), 10392 (Accum (v4i32 V128:$Rd), 10393 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 10394 (v4i32 V128:$Rm)))))]>; 10395} 10396 10397multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10398 SDPatternOperator Accum> { 10399 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10400 V64, V64, V128_lo, VectorIndexH, 10401 asm, ".4h", ".4h", ".4h", ".h", 10402 [(set (v4i16 V64:$dst), 10403 (Accum (v4i16 V64:$Rd), 10404 (v4i16 (int_aarch64_neon_sqrdmulh 10405 (v4i16 V64:$Rn), 10406 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10407 VectorIndexH:$idx))))))]> { 10408 bits<3> idx; 10409 let Inst{11} = idx{2}; 10410 let Inst{21} = idx{1}; 10411 let Inst{20} = idx{0}; 10412 } 10413 10414 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10415 V128, V128, V128_lo, VectorIndexH, 10416 asm, ".8h", ".8h", ".8h", ".h", 10417 [(set (v8i16 V128:$dst), 10418 (Accum (v8i16 V128:$Rd), 10419 (v8i16 (int_aarch64_neon_sqrdmulh 10420 (v8i16 V128:$Rn), 10421 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10422 VectorIndexH:$idx))))))]> { 10423 bits<3> idx; 10424 let Inst{11} = idx{2}; 10425 let Inst{21} = idx{1}; 10426 let Inst{20} = idx{0}; 10427 } 10428 10429 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10430 V64, V64, V128, VectorIndexS, 10431 asm, ".2s", ".2s", ".2s", ".s", 10432 [(set (v2i32 V64:$dst), 10433 (Accum (v2i32 V64:$Rd), 10434 (v2i32 (int_aarch64_neon_sqrdmulh 10435 (v2i32 V64:$Rn), 10436 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10437 VectorIndexS:$idx))))))]> { 10438 bits<2> idx; 10439 let Inst{11} = idx{1}; 10440 let Inst{21} = idx{0}; 10441 } 10442 10443 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10444 // an intermediate EXTRACT_SUBREG would be untyped. 10445 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 10446 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 10447 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10448 (i32 (vector_extract 10449 (v4i32 (insert_subvector 10450 (undef), 10451 (v2i32 (int_aarch64_neon_sqrdmulh 10452 (v2i32 V64:$Rn), 10453 (v2i32 (AArch64duplane32 10454 (v4i32 V128:$Rm), 10455 VectorIndexS:$idx)))), 10456 (i32 0))), 10457 (i64 0))))), 10458 (EXTRACT_SUBREG 10459 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 10460 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 10461 FPR32Op:$Rd, 10462 ssub)), 10463 V64:$Rn, 10464 V128:$Rm, 10465 VectorIndexS:$idx)), 10466 ssub)>; 10467 10468 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10469 V128, V128, V128, VectorIndexS, 10470 asm, ".4s", ".4s", ".4s", ".s", 10471 [(set (v4i32 V128:$dst), 10472 (Accum (v4i32 V128:$Rd), 10473 (v4i32 (int_aarch64_neon_sqrdmulh 10474 (v4i32 V128:$Rn), 10475 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10476 VectorIndexS:$idx))))))]> { 10477 bits<2> idx; 10478 let Inst{11} = idx{1}; 10479 let Inst{21} = idx{0}; 10480 } 10481 10482 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 10483 // an intermediate EXTRACT_SUBREG would be untyped. 10484 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 10485 (i32 (vector_extract 10486 (v4i32 (int_aarch64_neon_sqrdmulh 10487 (v4i32 V128:$Rn), 10488 (v4i32 (AArch64duplane32 10489 (v4i32 V128:$Rm), 10490 VectorIndexS:$idx)))), 10491 (i64 0))))), 10492 (EXTRACT_SUBREG 10493 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 10494 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 10495 FPR32Op:$Rd, 10496 ssub)), 10497 V128:$Rn, 10498 V128:$Rm, 10499 VectorIndexS:$idx)), 10500 ssub)>; 10501 10502 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10503 FPR16Op, FPR16Op, V128_lo, 10504 VectorIndexH, asm, ".h", "", "", ".h", 10505 []> { 10506 bits<3> idx; 10507 let Inst{11} = idx{2}; 10508 let Inst{21} = idx{1}; 10509 let Inst{20} = idx{0}; 10510 } 10511 10512 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10513 FPR32Op, FPR32Op, V128, VectorIndexS, 10514 asm, ".s", "", "", ".s", 10515 [(set (i32 FPR32Op:$dst), 10516 (Accum (i32 FPR32Op:$Rd), 10517 (i32 (int_aarch64_neon_sqrdmulh 10518 (i32 FPR32Op:$Rn), 10519 (i32 (vector_extract (v4i32 V128:$Rm), 10520 VectorIndexS:$idx))))))]> { 10521 bits<2> idx; 10522 let Inst{11} = idx{1}; 10523 let Inst{21} = idx{0}; 10524 } 10525} 10526} // let Predicates = [HasNeon, HasRDM] 10527 10528//---------------------------------------------------------------------------- 10529// ARMv8.3 Complex ADD/MLA instructions 10530//---------------------------------------------------------------------------- 10531 10532class ComplexRotationOperand<int Angle, int Remainder, string Type> 10533 : AsmOperandClass { 10534 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10535 let DiagnosticType = "InvalidComplexRotation" # Type; 10536 let Name = "ComplexRotation" # Type; 10537} 10538def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10539 SDNodeXForm<imm, [{ 10540 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10541}]>> { 10542 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10543 let PrintMethod = "printComplexRotationOp<90, 0>"; 10544} 10545def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10546 SDNodeXForm<imm, [{ 10547 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10548}]>> { 10549 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10550 let PrintMethod = "printComplexRotationOp<180, 90>"; 10551} 10552let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10553class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10554 RegisterOperand regtype, Operand rottype, 10555 string asm, string kind, list<dag> pattern> 10556 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10557 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10558 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10559 Sched<[WriteV]> { 10560 bits<5> Rd; 10561 bits<5> Rn; 10562 bits<5> Rm; 10563 bits<1> rot; 10564 let Inst{31} = 0; 10565 let Inst{30} = Q; 10566 let Inst{29} = U; 10567 let Inst{28-24} = 0b01110; 10568 let Inst{23-22} = size; 10569 let Inst{21} = 0; 10570 let Inst{20-16} = Rm; 10571 let Inst{15-13} = opcode; 10572 // Non-tied version (FCADD) only has one rotation bit 10573 let Inst{12} = rot; 10574 let Inst{11} = 0; 10575 let Inst{10} = 1; 10576 let Inst{9-5} = Rn; 10577 let Inst{4-0} = Rd; 10578} 10579 10580//8.3 CompNum - Floating-point complex number support 10581multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10582 string asm, SDPatternOperator OpNode>{ 10583 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10584 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10585 asm, ".4h", 10586 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10587 (v4f16 V64:$Rn), 10588 (v4f16 V64:$Rm), 10589 (rottype i32:$rot)))]>; 10590 10591 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10592 asm, ".8h", 10593 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10594 (v8f16 V128:$Rn), 10595 (v8f16 V128:$Rm), 10596 (rottype i32:$rot)))]>; 10597 } 10598 10599 let Predicates = [HasComplxNum, HasNEON] in { 10600 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10601 asm, ".2s", 10602 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10603 (v2f32 V64:$Rn), 10604 (v2f32 V64:$Rm), 10605 (rottype i32:$rot)))]>; 10606 10607 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10608 asm, ".4s", 10609 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10610 (v4f32 V128:$Rn), 10611 (v4f32 V128:$Rm), 10612 (rottype i32:$rot)))]>; 10613 10614 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10615 asm, ".2d", 10616 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10617 (v2f64 V128:$Rn), 10618 (v2f64 V128:$Rm), 10619 (rottype i32:$rot)))]>; 10620 } 10621} 10622 10623let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10624class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10625 bits<3> opcode, 10626 RegisterOperand regtype, 10627 Operand rottype, string asm, 10628 string kind, list<dag> pattern> 10629 : I<(outs regtype:$dst), 10630 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10631 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10632 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10633 Sched<[WriteV]> { 10634 bits<5> Rd; 10635 bits<5> Rn; 10636 bits<5> Rm; 10637 bits<2> rot; 10638 let Inst{31} = 0; 10639 let Inst{30} = Q; 10640 let Inst{29} = U; 10641 let Inst{28-24} = 0b01110; 10642 let Inst{23-22} = size; 10643 let Inst{21} = 0; 10644 let Inst{20-16} = Rm; 10645 let Inst{15-13} = opcode; 10646 let Inst{12-11} = rot; 10647 let Inst{10} = 1; 10648 let Inst{9-5} = Rn; 10649 let Inst{4-0} = Rd; 10650} 10651 10652multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10653 Operand rottype, string asm, 10654 SDPatternOperator OpNode> { 10655 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10656 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10657 rottype, asm, ".4h", 10658 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10659 (v4f16 V64:$Rn), 10660 (v4f16 V64:$Rm), 10661 (rottype i32:$rot)))]>; 10662 10663 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10664 rottype, asm, ".8h", 10665 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10666 (v8f16 V128:$Rn), 10667 (v8f16 V128:$Rm), 10668 (rottype i32:$rot)))]>; 10669 } 10670 10671 let Predicates = [HasComplxNum, HasNEON] in { 10672 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10673 rottype, asm, ".2s", 10674 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10675 (v2f32 V64:$Rn), 10676 (v2f32 V64:$Rm), 10677 (rottype i32:$rot)))]>; 10678 10679 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10680 rottype, asm, ".4s", 10681 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10682 (v4f32 V128:$Rn), 10683 (v4f32 V128:$Rm), 10684 (rottype i32:$rot)))]>; 10685 10686 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10687 rottype, asm, ".2d", 10688 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10689 (v2f64 V128:$Rn), 10690 (v2f64 V128:$Rm), 10691 (rottype i32:$rot)))]>; 10692 } 10693} 10694 10695let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10696class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10697 bit opc1, bit opc2, RegisterOperand dst_reg, 10698 RegisterOperand lhs_reg, 10699 RegisterOperand rhs_reg, Operand vec_idx, 10700 Operand rottype, string asm, string apple_kind, 10701 string dst_kind, string lhs_kind, 10702 string rhs_kind, list<dag> pattern> 10703 : I<(outs dst_reg:$dst), 10704 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10705 asm, 10706 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10707 "$idx, $rot" # "|" # apple_kind # 10708 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10709 Sched<[WriteV]> { 10710 bits<5> Rd; 10711 bits<5> Rn; 10712 bits<5> Rm; 10713 bits<2> rot; 10714 10715 let Inst{31} = 0; 10716 let Inst{30} = Q; 10717 let Inst{29} = U; 10718 let Inst{28} = Scalar; 10719 let Inst{27-24} = 0b1111; 10720 let Inst{23-22} = size; 10721 // Bit 21 must be set by the derived class. 10722 let Inst{20-16} = Rm; 10723 let Inst{15} = opc1; 10724 let Inst{14-13} = rot; 10725 let Inst{12} = opc2; 10726 // Bit 11 must be set by the derived class. 10727 let Inst{10} = 0; 10728 let Inst{9-5} = Rn; 10729 let Inst{4-0} = Rd; 10730} 10731 10732// The complex instructions index by pairs of elements, so the VectorIndexes 10733// don't match the lane types, and the index bits are different to the other 10734// classes. 10735multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10736 string asm, SDPatternOperator OpNode> { 10737 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10738 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10739 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10740 ".4h", ".h", []> { 10741 bits<1> idx; 10742 let Inst{11} = 0; 10743 let Inst{21} = idx{0}; 10744 } 10745 10746 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10747 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10748 ".8h", ".8h", ".h", []> { 10749 bits<2> idx; 10750 let Inst{11} = idx{1}; 10751 let Inst{21} = idx{0}; 10752 } 10753 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10754 10755 let Predicates = [HasComplxNum, HasNEON] in { 10756 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10757 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10758 ".4s", ".4s", ".s", []> { 10759 bits<1> idx; 10760 let Inst{11} = idx{0}; 10761 let Inst{21} = 0; 10762 } 10763 } // Predicates = [HasComplxNum, HasNEON] 10764} 10765 10766//---------------------------------------------------------------------------- 10767// Crypto extensions 10768//---------------------------------------------------------------------------- 10769 10770let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10771class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10772 list<dag> pat> 10773 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10774 Sched<[WriteV]>{ 10775 bits<5> Rd; 10776 bits<5> Rn; 10777 let Inst{31-16} = 0b0100111000101000; 10778 let Inst{15-12} = opc; 10779 let Inst{11-10} = 0b10; 10780 let Inst{9-5} = Rn; 10781 let Inst{4-0} = Rd; 10782} 10783 10784class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10785 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10786 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10787 10788class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10789 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10790 "$Rd = $dst", 10791 [(set (v16i8 V128:$dst), 10792 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10793 10794let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10795class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10796 dag oops, dag iops, list<dag> pat> 10797 : I<oops, iops, asm, 10798 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10799 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10800 Sched<[WriteV]>{ 10801 bits<5> Rd; 10802 bits<5> Rn; 10803 bits<5> Rm; 10804 let Inst{31-21} = 0b01011110000; 10805 let Inst{20-16} = Rm; 10806 let Inst{15} = 0; 10807 let Inst{14-12} = opc; 10808 let Inst{11-10} = 0b00; 10809 let Inst{9-5} = Rn; 10810 let Inst{4-0} = Rd; 10811} 10812 10813class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10814 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10815 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10816 [(set (v4i32 FPR128:$dst), 10817 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10818 (v4i32 V128:$Rm)))]>; 10819 10820class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10821 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10822 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10823 [(set (v4i32 V128:$dst), 10824 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10825 (v4i32 V128:$Rm)))]>; 10826 10827class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10828 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10829 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10830 [(set (v4i32 FPR128:$dst), 10831 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10832 (v4i32 V128:$Rm)))]>; 10833 10834let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10835class SHA2OpInst<bits<4> opc, string asm, string kind, 10836 string cstr, dag oops, dag iops, 10837 list<dag> pat> 10838 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10839 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10840 Sched<[WriteV]>{ 10841 bits<5> Rd; 10842 bits<5> Rn; 10843 let Inst{31-16} = 0b0101111000101000; 10844 let Inst{15-12} = opc; 10845 let Inst{11-10} = 0b10; 10846 let Inst{9-5} = Rn; 10847 let Inst{4-0} = Rd; 10848} 10849 10850class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10851 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10852 (ins V128:$Rd, V128:$Rn), 10853 [(set (v4i32 V128:$dst), 10854 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10855 10856class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10857 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10858 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10859 10860// Armv8.2-A Crypto extensions 10861class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10862 list<dag> pattern> 10863 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10864 bits<5> Vd; 10865 bits<5> Vn; 10866 let Inst{31-25} = 0b1100111; 10867 let Inst{9-5} = Vn; 10868 let Inst{4-0} = Vd; 10869} 10870 10871class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10872 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops, 10873 "$Vm = $Vd", []> { 10874 let Inst{31-25} = 0b1100111; 10875 let Inst{24-21} = 0b0110; 10876 let Inst{20-15} = 0b000001; 10877 let Inst{14} = op0; 10878 let Inst{13-12} = 0b00; 10879 let Inst{11-10} = op1; 10880} 10881class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10882 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 10883class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10884 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 10885 10886class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10887 string asmops, string cst> 10888 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10889 bits<5> Vm; 10890 let Inst{24-21} = 0b0011; 10891 let Inst{20-16} = Vm; 10892 let Inst{15} = 0b1; 10893 let Inst{14} = op0; 10894 let Inst{13-12} = 0b00; 10895 let Inst{11-10} = op1; 10896} 10897class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10898 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10899 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 10900class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10901 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10902 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10903class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10904 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10905 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 10906class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10907 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10908 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10909class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 10910 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 10911 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 10912 10913class CryptoRRRR<bits<2>op0, string asm, string asmops> 10914 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 10915 asmops, "", []> { 10916 bits<5> Vm; 10917 bits<5> Va; 10918 let Inst{24-23} = 0b00; 10919 let Inst{22-21} = op0; 10920 let Inst{20-16} = Vm; 10921 let Inst{15} = 0b0; 10922 let Inst{14-10} = Va; 10923} 10924class CryptoRRRR_16B<bits<2>op0, string asm> 10925 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 10926 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 10927} 10928class CryptoRRRR_4S<bits<2>op0, string asm> 10929 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 10930 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 10931} 10932 10933class CryptoRRRi6<string asm> 10934 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 10935 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 10936 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 10937 bits<6> imm; 10938 bits<5> Vm; 10939 let Inst{24-21} = 0b0100; 10940 let Inst{20-16} = Vm; 10941 let Inst{15-10} = imm; 10942 let Inst{9-5} = Vn; 10943 let Inst{4-0} = Vd; 10944} 10945 10946class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 10947 : BaseCryptoV82<(outs V128:$Vdst), 10948 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 10949 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 10950 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 10951 bits<2> imm; 10952 bits<5> Vm; 10953 let Inst{24-21} = 0b0010; 10954 let Inst{20-16} = Vm; 10955 let Inst{15} = 0b1; 10956 let Inst{14} = op0; 10957 let Inst{13-12} = imm; 10958 let Inst{11-10} = op1; 10959} 10960 10961//---------------------------------------------------------------------------- 10962// v8.1 atomic instructions extension: 10963// * CAS 10964// * CASP 10965// * SWP 10966// * LDOPregister<OP>, and aliases STOPregister<OP> 10967 10968// Instruction encodings: 10969// 10970// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 10971// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 10972// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 10973// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 10974// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 10975// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 10976 10977// Instruction syntax: 10978// 10979// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10980// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 10981// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 10982// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 10983// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10984// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 10985// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10986// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 10987// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 10988// ST<OP>{<order>} <Xs>, [<Xn|SP>] 10989 10990let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 10991class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 10992 string cstr, list<dag> pattern> 10993 : I<oops, iops, asm, operands, cstr, pattern> { 10994 bits<2> Sz; 10995 bit NP; 10996 bit Acq; 10997 bit Rel; 10998 bits<5> Rs; 10999 bits<5> Rn; 11000 bits<5> Rt; 11001 let Inst{31-30} = Sz; 11002 let Inst{29-24} = 0b001000; 11003 let Inst{23} = NP; 11004 let Inst{22} = Acq; 11005 let Inst{21} = 0b1; 11006 let Inst{20-16} = Rs; 11007 let Inst{15} = Rel; 11008 let Inst{14-10} = 0b11111; 11009 let Inst{9-5} = Rn; 11010 let Inst{4-0} = Rt; 11011 let Predicates = [HasLSE]; 11012} 11013 11014class BaseCAS<string order, string size, RegisterClass RC> 11015 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11016 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11017 "$out = $Rs",[]>, 11018 Sched<[WriteAtomic]> { 11019 let NP = 1; 11020} 11021 11022multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11023 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11024 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11025 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11026 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11027} 11028 11029class BaseCASP<string order, string size, RegisterOperand RC> 11030 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11031 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11032 "$out = $Rs",[]>, 11033 Sched<[WriteAtomic]> { 11034 let NP = 0; 11035} 11036 11037multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11038 let Sz = 0b00, Acq = Acq, Rel = Rel in 11039 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11040 let Sz = 0b01, Acq = Acq, Rel = Rel in 11041 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11042} 11043 11044let Predicates = [HasLSE] in 11045class BaseSWP<string order, string size, RegisterClass RC> 11046 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11047 "\t$Rs, $Rt, [$Rn]","",[]>, 11048 Sched<[WriteAtomic]> { 11049 bits<2> Sz; 11050 bit Acq; 11051 bit Rel; 11052 bits<5> Rs; 11053 bits<3> opc = 0b000; 11054 bits<5> Rn; 11055 bits<5> Rt; 11056 let Inst{31-30} = Sz; 11057 let Inst{29-24} = 0b111000; 11058 let Inst{23} = Acq; 11059 let Inst{22} = Rel; 11060 let Inst{21} = 0b1; 11061 let Inst{20-16} = Rs; 11062 let Inst{15} = 0b1; 11063 let Inst{14-12} = opc; 11064 let Inst{11-10} = 0b00; 11065 let Inst{9-5} = Rn; 11066 let Inst{4-0} = Rt; 11067 let Predicates = [HasLSE]; 11068} 11069 11070multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11071 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11072 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11073 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11074 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11075} 11076 11077let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11078class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11079 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11080 "\t$Rs, $Rt, [$Rn]","",[]>, 11081 Sched<[WriteAtomic]> { 11082 bits<2> Sz; 11083 bit Acq; 11084 bit Rel; 11085 bits<5> Rs; 11086 bits<3> opc; 11087 bits<5> Rn; 11088 bits<5> Rt; 11089 let Inst{31-30} = Sz; 11090 let Inst{29-24} = 0b111000; 11091 let Inst{23} = Acq; 11092 let Inst{22} = Rel; 11093 let Inst{21} = 0b1; 11094 let Inst{20-16} = Rs; 11095 let Inst{15} = 0b0; 11096 let Inst{14-12} = opc; 11097 let Inst{11-10} = 0b00; 11098 let Inst{9-5} = Rn; 11099 let Inst{4-0} = Rt; 11100 let Predicates = [HasLSE]; 11101} 11102 11103multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11104 string order> { 11105 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11106 def B : BaseLDOPregister<op, order, "b", GPR32>; 11107 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11108 def H : BaseLDOPregister<op, order, "h", GPR32>; 11109 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11110 def W : BaseLDOPregister<op, order, "", GPR32>; 11111 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11112 def X : BaseLDOPregister<op, order, "", GPR64>; 11113} 11114 11115// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11116// complex DAG for DstRHS. 11117let Predicates = [HasLSE] in 11118multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11119 string size, dag SrcRHS, dag DstRHS> { 11120 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11121 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11122 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11123 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11124 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11125 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11126 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11127 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11128 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11129 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11130} 11131 11132multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11133 string size, dag RHS> { 11134 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11135} 11136 11137multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11138 string size, dag LHS, dag RHS> { 11139 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11140} 11141 11142multiclass LDOPregister_patterns<string inst, string op> { 11143 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11144 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11145 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11146 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11147} 11148 11149multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11150 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11151 (i64 GPR64:$Rm), 11152 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11153 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11154 (i32 GPR32:$Rm), 11155 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11156 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11157 (i32 GPR32:$Rm), 11158 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11159 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11160 (i32 GPR32:$Rm), 11161 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11162} 11163 11164let Predicates = [HasLSE] in 11165multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11166 string size, dag OLD, dag NEW> { 11167 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11168 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11169 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11170 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11171 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11172 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11173 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11174 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11175 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11176 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11177} 11178 11179multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11180 string size, dag OLD, dag NEW> { 11181 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11182} 11183 11184multiclass CASregister_patterns<string inst, string op> { 11185 defm : CASregister_patterns_ord<inst, "X", op, "64", 11186 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11187 defm : CASregister_patterns_ord<inst, "W", op, "32", 11188 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11189 defm : CASregister_patterns_ord<inst, "H", op, "16", 11190 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11191 defm : CASregister_patterns_ord<inst, "B", op, "8", 11192 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11193} 11194 11195let Predicates = [HasLSE] in 11196class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11197 Instruction inst> : 11198 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11199 11200multiclass STOPregister<string asm, string instr> { 11201 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11202 !cast<Instruction>(instr # "LB")>; 11203 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11204 !cast<Instruction>(instr # "LH")>; 11205 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11206 !cast<Instruction>(instr # "LW")>; 11207 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11208 !cast<Instruction>(instr # "LX")>; 11209 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11210 !cast<Instruction>(instr # "B")>; 11211 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11212 !cast<Instruction>(instr # "H")>; 11213 def : BaseSTOPregister<asm, GPR32, WZR, 11214 !cast<Instruction>(instr # "W")>; 11215 def : BaseSTOPregister<asm, GPR64, XZR, 11216 !cast<Instruction>(instr # "X")>; 11217} 11218 11219//---------------------------------------------------------------------------- 11220// Allow the size specifier tokens to be upper case, not just lower. 11221def : TokenAlias<".4B", ".4b">; // Add dot product 11222def : TokenAlias<".8B", ".8b">; 11223def : TokenAlias<".4H", ".4h">; 11224def : TokenAlias<".2S", ".2s">; 11225def : TokenAlias<".1D", ".1d">; 11226def : TokenAlias<".16B", ".16b">; 11227def : TokenAlias<".8H", ".8h">; 11228def : TokenAlias<".4S", ".4s">; 11229def : TokenAlias<".2D", ".2d">; 11230def : TokenAlias<".1Q", ".1q">; 11231def : TokenAlias<".2H", ".2h">; 11232def : TokenAlias<".B", ".b">; 11233def : TokenAlias<".H", ".h">; 11234def : TokenAlias<".S", ".s">; 11235def : TokenAlias<".D", ".d">; 11236def : TokenAlias<".Q", ".q">; 11237