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>; 39def DestructiveUnaryPassthru : DestructiveInstTypeEnum<9>; 40 41class FalseLanesEnum<bits<2> val> { 42 bits<2> Value = val; 43} 44def FalseLanesNone : FalseLanesEnum<0>; 45def FalseLanesZero : FalseLanesEnum<1>; 46def FalseLanesUndef : FalseLanesEnum<2>; 47 48class SMEMatrixTypeEnum<bits<3> val> { 49 bits<3> Value = val; 50} 51def SMEMatrixNone : SMEMatrixTypeEnum<0>; 52def SMEMatrixTileB : SMEMatrixTypeEnum<1>; 53def SMEMatrixTileH : SMEMatrixTypeEnum<2>; 54def SMEMatrixTileS : SMEMatrixTypeEnum<3>; 55def SMEMatrixTileD : SMEMatrixTypeEnum<4>; 56def SMEMatrixTileQ : SMEMatrixTypeEnum<5>; 57def SMEMatrixArray : SMEMatrixTypeEnum<6>; 58 59// AArch64 Instruction Format 60class AArch64Inst<Format f, string cstr> : Instruction { 61 field bits<32> Inst; // Instruction encoding. 62 // Mask of bits that cause an encoding to be UNPREDICTABLE. 63 // If a bit is set, then if the corresponding bit in the 64 // target encoding differs from its value in the "Inst" field, 65 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 66 field bits<32> Unpredictable = 0; 67 // SoftFail is the generic name for this field, but we alias it so 68 // as to make it more obvious what it means in ARM-land. 69 field bits<32> SoftFail = Unpredictable; 70 let Namespace = "AArch64"; 71 Format F = f; 72 bits<2> Form = F.Value; 73 74 // Defaults 75 bit isWhile = 0; 76 bit isPTestLike = 0; 77 FalseLanesEnum FalseLanes = FalseLanesNone; 78 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 79 SMEMatrixTypeEnum SMEMatrixType = SMEMatrixNone; 80 ElementSizeEnum ElementSize = ElementSizeNone; 81 82 let TSFlags{13-11} = SMEMatrixType.Value; 83 let TSFlags{10} = isPTestLike; 84 let TSFlags{9} = isWhile; 85 let TSFlags{8-7} = FalseLanes.Value; 86 let TSFlags{6-3} = DestructiveInstType.Value; 87 let TSFlags{2-0} = ElementSize.Value; 88 89 let Pattern = []; 90 let Constraints = cstr; 91} 92 93class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 94 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 95 96// Pseudo instructions (don't have encoding information) 97class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 98 : AArch64Inst<PseudoFrm, cstr> { 99 dag OutOperandList = oops; 100 dag InOperandList = iops; 101 let Pattern = pattern; 102 let isCodeGenOnly = 1; 103 let isPseudo = 1; 104} 105 106// Real instructions (have encoding information) 107class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 108 let Pattern = pattern; 109 let Size = 4; 110} 111 112// Normal instructions 113class I<dag oops, dag iops, string asm, string operands, string cstr, 114 list<dag> pattern> 115 : EncodedI<cstr, pattern> { 116 dag OutOperandList = oops; 117 dag InOperandList = iops; 118 let AsmString = !strconcat(asm, operands); 119} 120 121class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 122class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 123class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 124 125// Helper fragment for an extract of the high portion of a 128-bit vector. The 126// ComplexPattern match both extract_subvector and bitcast(extract_subvector(..)). 127def extract_high_v16i8 : 128 ComplexPattern<v8i8, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 129def extract_high_v8i16 : 130 ComplexPattern<v4i16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 131def extract_high_v4i32 : 132 ComplexPattern<v2i32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 133def extract_high_v2i64 : 134 ComplexPattern<v1i64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 135 136def extract_high_dup_v8i16 : 137 BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>; 138def extract_high_dup_v4i32 : 139 BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>; 140 141//===----------------------------------------------------------------------===// 142// Asm Operand Classes. 143// 144 145// Shifter operand for arithmetic shifted encodings. 146def ShifterOperand : AsmOperandClass { 147 let Name = "Shifter"; 148} 149 150// Shifter operand for mov immediate encodings. 151def MovImm32ShifterOperand : AsmOperandClass { 152 let SuperClasses = [ShifterOperand]; 153 let Name = "MovImm32Shifter"; 154 let RenderMethod = "addShifterOperands"; 155 let DiagnosticType = "InvalidMovImm32Shift"; 156} 157def MovImm64ShifterOperand : AsmOperandClass { 158 let SuperClasses = [ShifterOperand]; 159 let Name = "MovImm64Shifter"; 160 let RenderMethod = "addShifterOperands"; 161 let DiagnosticType = "InvalidMovImm64Shift"; 162} 163 164// Shifter operand for arithmetic register shifted encodings. 165class ArithmeticShifterOperand<int width> : AsmOperandClass { 166 let SuperClasses = [ShifterOperand]; 167 let Name = "ArithmeticShifter" # width; 168 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 169 let RenderMethod = "addShifterOperands"; 170 let DiagnosticType = "AddSubRegShift" # width; 171} 172 173def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 174def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 175 176// Shifter operand for logical register shifted encodings. 177class LogicalShifterOperand<int width> : AsmOperandClass { 178 let SuperClasses = [ShifterOperand]; 179 let Name = "LogicalShifter" # width; 180 let PredicateMethod = "isLogicalShifter<" # width # ">"; 181 let RenderMethod = "addShifterOperands"; 182 let DiagnosticType = "AddSubRegShift" # width; 183} 184 185def LogicalShifterOperand32 : LogicalShifterOperand<32>; 186def LogicalShifterOperand64 : LogicalShifterOperand<64>; 187 188// Shifter operand for logical vector 128/64-bit shifted encodings. 189def LogicalVecShifterOperand : AsmOperandClass { 190 let SuperClasses = [ShifterOperand]; 191 let Name = "LogicalVecShifter"; 192 let RenderMethod = "addShifterOperands"; 193} 194def LogicalVecHalfWordShifterOperand : AsmOperandClass { 195 let SuperClasses = [LogicalVecShifterOperand]; 196 let Name = "LogicalVecHalfWordShifter"; 197 let RenderMethod = "addShifterOperands"; 198} 199 200// The "MSL" shifter on the vector MOVI instruction. 201def MoveVecShifterOperand : AsmOperandClass { 202 let SuperClasses = [ShifterOperand]; 203 let Name = "MoveVecShifter"; 204 let RenderMethod = "addShifterOperands"; 205} 206 207// Extend operand for arithmetic encodings. 208def ExtendOperand : AsmOperandClass { 209 let Name = "Extend"; 210 let DiagnosticType = "AddSubRegExtendLarge"; 211} 212def ExtendOperand64 : AsmOperandClass { 213 let SuperClasses = [ExtendOperand]; 214 let Name = "Extend64"; 215 let DiagnosticType = "AddSubRegExtendSmall"; 216} 217// 'extend' that's a lsl of a 64-bit register. 218def ExtendOperandLSL64 : AsmOperandClass { 219 let SuperClasses = [ExtendOperand]; 220 let Name = "ExtendLSL64"; 221 let RenderMethod = "addExtend64Operands"; 222 let DiagnosticType = "AddSubRegExtendLarge"; 223} 224 225// 8-bit floating-point immediate encodings. 226def FPImmOperand : AsmOperandClass { 227 let Name = "FPImm"; 228 let ParserMethod = "tryParseFPImm<true>"; 229 let DiagnosticType = "InvalidFPImm"; 230} 231 232def CondCode : AsmOperandClass { 233 let Name = "CondCode"; 234 let DiagnosticType = "InvalidCondCode"; 235} 236 237// A 32-bit register pasrsed as 64-bit 238def GPR32as64Operand : AsmOperandClass { 239 let Name = "GPR32as64"; 240 let ParserMethod = 241 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 242} 243def GPR32as64 : RegisterOperand<GPR32> { 244 let ParserMatchClass = GPR32as64Operand; 245} 246 247// A 64-bit register pasrsed as 32-bit 248def GPR64as32Operand : AsmOperandClass { 249 let Name = "GPR64as32"; 250 let ParserMethod = 251 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 252} 253def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 254 let ParserMatchClass = GPR64as32Operand; 255} 256 257// 8-bit immediate for AdvSIMD where 64-bit values of the form: 258// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 259// are encoded as the eight bit value 'abcdefgh'. 260def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 261 262class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 263 let Name = "UImm" # Width # "s" # Scale; 264 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 265 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 266 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 267} 268 269class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 270 let Name = "SImm" # Width # "s" # Scale; 271 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 272 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 273 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 274} 275 276//===----------------------------------------------------------------------===// 277// Operand Definitions. 278// 279 280// ADR[P] instruction labels. 281def AdrpOperand : AsmOperandClass { 282 let Name = "AdrpLabel"; 283 let ParserMethod = "tryParseAdrpLabel"; 284 let DiagnosticType = "InvalidLabel"; 285} 286def adrplabel : Operand<i64> { 287 let EncoderMethod = "getAdrLabelOpValue"; 288 let PrintMethod = "printAdrpLabel"; 289 let ParserMatchClass = AdrpOperand; 290 let OperandType = "OPERAND_PCREL"; 291} 292 293def AdrOperand : AsmOperandClass { 294 let Name = "AdrLabel"; 295 let ParserMethod = "tryParseAdrLabel"; 296 let DiagnosticType = "InvalidLabel"; 297} 298def adrlabel : Operand<i64> { 299 let EncoderMethod = "getAdrLabelOpValue"; 300 let ParserMatchClass = AdrOperand; 301} 302 303class SImmOperand<int width> : AsmOperandClass { 304 let Name = "SImm" # width; 305 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 306 let RenderMethod = "addImmOperands"; 307 let PredicateMethod = "isSImm<" # width # ">"; 308} 309 310class AsmImmRange<int Low, int High> : AsmOperandClass { 311 let Name = "Imm" # Low # "_" # High; 312 let DiagnosticType = "InvalidImm" # Low # "_" # High; 313 let RenderMethod = "addImmOperands"; 314 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 315} 316 317// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 318def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 319def simm10Scaled : Operand<i64> { 320 let ParserMatchClass = SImm10s8Operand; 321 let DecoderMethod = "DecodeSImm<10>"; 322 let PrintMethod = "printImmScale<8>"; 323} 324 325def simm9s16 : Operand<i64> { 326 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 327 let DecoderMethod = "DecodeSImm<9>"; 328 let PrintMethod = "printImmScale<16>"; 329} 330 331// uimm6 predicate - True if the immediate is in the range [0, 63]. 332def UImm6Operand : AsmOperandClass { 333 let Name = "UImm6"; 334 let DiagnosticType = "InvalidImm0_63"; 335} 336 337def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 338 let ParserMatchClass = UImm6Operand; 339} 340 341def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 342 let ParserMatchClass = AsmImmRange<0, 65535>; 343} 344 345def SImm9Operand : SImmOperand<9>; 346def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 347 let ParserMatchClass = SImm9Operand; 348 let DecoderMethod = "DecodeSImm<9>"; 349} 350 351// imm0_255 predicate - True if the immediate is in the range [0,255]. 352def Imm0_255Operand : AsmImmRange<0,255>; 353 354def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 355 let ParserMatchClass = Imm0_255Operand; 356} 357def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> { 358 let ParserMatchClass = Imm0_255Operand; 359} 360 361def SImm8Operand : SImmOperand<8>; 362def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 363 let ParserMatchClass = SImm8Operand; 364 let DecoderMethod = "DecodeSImm<8>"; 365} 366def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> { 367 let ParserMatchClass = SImm8Operand; 368 let DecoderMethod = "DecodeSImm<8>"; 369} 370 371def SImm6Operand : SImmOperand<6>; 372def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 373 let ParserMatchClass = SImm6Operand; 374 let DecoderMethod = "DecodeSImm<6>"; 375} 376 377def SImm5Operand : SImmOperand<5>; 378def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 379 let ParserMatchClass = SImm5Operand; 380 let DecoderMethod = "DecodeSImm<5>"; 381} 382 383def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 384 let ParserMatchClass = SImm5Operand; 385 let DecoderMethod = "DecodeSImm<5>"; 386} 387 388def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 389 let ParserMatchClass = SImm5Operand; 390 let DecoderMethod = "DecodeSImm<5>"; 391 let PrintMethod = "printSImm<8>"; 392} 393 394def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 395 let ParserMatchClass = SImm5Operand; 396 let DecoderMethod = "DecodeSImm<5>"; 397 let PrintMethod = "printSImm<16>"; 398} 399 400// simm7sN predicate - True if the immediate is a multiple of N in the range 401// [-64 * N, 63 * N]. 402 403def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 404def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 405def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 406 407def simm7s4 : Operand<i32> { 408 let ParserMatchClass = SImm7s4Operand; 409 let PrintMethod = "printImmScale<4>"; 410} 411 412def simm7s8 : Operand<i32> { 413 let ParserMatchClass = SImm7s8Operand; 414 let PrintMethod = "printImmScale<8>"; 415} 416 417def simm7s16 : Operand<i32> { 418 let ParserMatchClass = SImm7s16Operand; 419 let PrintMethod = "printImmScale<16>"; 420} 421 422def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>; 423 424def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>; 425def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>; 426def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>; 427def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>; 428def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>; 429 430def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>; 431def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>; 432 433def UImmS1XForm : SDNodeXForm<imm, [{ 434 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 435}]>; 436def UImmS2XForm : SDNodeXForm<imm, [{ 437 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 438}]>; 439def UImmS4XForm : SDNodeXForm<imm, [{ 440 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 441}]>; 442def UImmS8XForm : SDNodeXForm<imm, [{ 443 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 444}]>; 445 446// uimm5sN predicate - True if the immediate is a multiple of N in the range 447// [0 * N, 32 * N]. 448def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 449def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 450def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 451 452def uimm5s2 : Operand<i64>, ImmLeaf<i64, 453 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 454 UImmS2XForm> { 455 let ParserMatchClass = UImm5s2Operand; 456 let PrintMethod = "printImmScale<2>"; 457} 458def uimm5s4 : Operand<i64>, ImmLeaf<i64, 459 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 460 UImmS4XForm> { 461 let ParserMatchClass = UImm5s4Operand; 462 let PrintMethod = "printImmScale<4>"; 463} 464def uimm5s8 : Operand<i64>, ImmLeaf<i64, 465 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 466 UImmS8XForm> { 467 let ParserMatchClass = UImm5s8Operand; 468 let PrintMethod = "printImmScale<8>"; 469} 470 471// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 472// instead of ImmLeaf (Constant) 473def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 474 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 475 UImmS2XForm> { 476 let ParserMatchClass = UImm5s2Operand; 477 let PrintMethod = "printImmScale<2>"; 478} 479def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 480 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 481 UImmS4XForm> { 482 let ParserMatchClass = UImm5s4Operand; 483 let PrintMethod = "printImmScale<4>"; 484} 485def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 486 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 487 UImmS8XForm> { 488 let ParserMatchClass = UImm5s8Operand; 489 let PrintMethod = "printImmScale<8>"; 490} 491 492// uimm6sN predicate - True if the immediate is a multiple of N in the range 493// [0 * N, 64 * N]. 494def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 495def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 496def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 497def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 498def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 499 500def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 501 let ParserMatchClass = UImm6s1Operand; 502} 503def uimm6s2 : Operand<i64>, ImmLeaf<i64, 504[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 505 let PrintMethod = "printImmScale<2>"; 506 let ParserMatchClass = UImm6s2Operand; 507} 508def uimm6s4 : Operand<i64>, ImmLeaf<i64, 509[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 510 let PrintMethod = "printImmScale<4>"; 511 let ParserMatchClass = UImm6s4Operand; 512} 513def uimm6s8 : Operand<i64>, ImmLeaf<i64, 514[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 515 let PrintMethod = "printImmScale<8>"; 516 let ParserMatchClass = UImm6s8Operand; 517} 518def uimm6s16 : Operand<i64>, ImmLeaf<i64, 519[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 520 let PrintMethod = "printImmScale<16>"; 521 let ParserMatchClass = UImm6s16Operand; 522} 523 524def SImmS2XForm : SDNodeXForm<imm, [{ 525 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 526}]>; 527def SImmS3XForm : SDNodeXForm<imm, [{ 528 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 529}]>; 530def SImmS4XForm : SDNodeXForm<imm, [{ 531 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 532}]>; 533def SImmS16XForm : SDNodeXForm<imm, [{ 534 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 535}]>; 536def SImmS32XForm : SDNodeXForm<imm, [{ 537 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 538}]>; 539 540// simm6sN predicate - True if the immediate is a multiple of N in the range 541// [-32 * N, 31 * N]. 542def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 543def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 544 let ParserMatchClass = SImm6s1Operand; 545 let DecoderMethod = "DecodeSImm<6>"; 546} 547 548// simm4sN predicate - True if the immediate is a multiple of N in the range 549// [ -8* N, 7 * N]. 550def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 551def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 552def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 553def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 554def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 555def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 556 557def simm4s1 : Operand<i64>, ImmLeaf<i64, 558[{ return Imm >=-8 && Imm <= 7; }]> { 559 let ParserMatchClass = SImm4s1Operand; 560 let DecoderMethod = "DecodeSImm<4>"; 561} 562 563def simm4s2 : Operand<i64>, ImmLeaf<i64, 564[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 565 let PrintMethod = "printImmScale<2>"; 566 let ParserMatchClass = SImm4s2Operand; 567 let DecoderMethod = "DecodeSImm<4>"; 568} 569 570def simm4s3 : Operand<i64>, ImmLeaf<i64, 571[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 572 let PrintMethod = "printImmScale<3>"; 573 let ParserMatchClass = SImm4s3Operand; 574 let DecoderMethod = "DecodeSImm<4>"; 575} 576 577def simm4s4 : Operand<i64>, ImmLeaf<i64, 578[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 579 let PrintMethod = "printImmScale<4>"; 580 let ParserMatchClass = SImm4s4Operand; 581 let DecoderMethod = "DecodeSImm<4>"; 582} 583def simm4s16 : Operand<i64>, ImmLeaf<i64, 584[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 585 let PrintMethod = "printImmScale<16>"; 586 let ParserMatchClass = SImm4s16Operand; 587 let DecoderMethod = "DecodeSImm<4>"; 588} 589def simm4s32 : Operand<i64>, ImmLeaf<i64, 590[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 591 let PrintMethod = "printImmScale<32>"; 592 let ParserMatchClass = SImm4s32Operand; 593 let DecoderMethod = "DecodeSImm<4>"; 594} 595 596def Imm1_8Operand : AsmImmRange<1, 8>; 597def Imm1_16Operand : AsmImmRange<1, 16>; 598def Imm1_32Operand : AsmImmRange<1, 32>; 599def Imm1_64Operand : AsmImmRange<1, 64>; 600 601class BranchTarget<int N> : AsmOperandClass { 602 let Name = "BranchTarget" # N; 603 let DiagnosticType = "InvalidLabel"; 604 let PredicateMethod = "isBranchTarget<" # N # ">"; 605} 606 607class PCRelLabel<int N> : BranchTarget<N> { 608 let Name = "PCRelLabel" # N; 609} 610 611def BranchTarget14Operand : BranchTarget<14>; 612def BranchTarget26Operand : BranchTarget<26>; 613def PCRelLabel19Operand : PCRelLabel<19>; 614 615def MovWSymbolG3AsmOperand : AsmOperandClass { 616 let Name = "MovWSymbolG3"; 617 let RenderMethod = "addImmOperands"; 618} 619 620def movw_symbol_g3 : Operand<i32> { 621 let ParserMatchClass = MovWSymbolG3AsmOperand; 622} 623 624def MovWSymbolG2AsmOperand : AsmOperandClass { 625 let Name = "MovWSymbolG2"; 626 let RenderMethod = "addImmOperands"; 627} 628 629def movw_symbol_g2 : Operand<i32> { 630 let ParserMatchClass = MovWSymbolG2AsmOperand; 631} 632 633def MovWSymbolG1AsmOperand : AsmOperandClass { 634 let Name = "MovWSymbolG1"; 635 let RenderMethod = "addImmOperands"; 636} 637 638def movw_symbol_g1 : Operand<i32> { 639 let ParserMatchClass = MovWSymbolG1AsmOperand; 640} 641 642def MovWSymbolG0AsmOperand : AsmOperandClass { 643 let Name = "MovWSymbolG0"; 644 let RenderMethod = "addImmOperands"; 645} 646 647def movw_symbol_g0 : Operand<i32> { 648 let ParserMatchClass = MovWSymbolG0AsmOperand; 649} 650 651class fixedpoint_i32<ValueType FloatVT> 652 : Operand<FloatVT>, 653 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 654 let EncoderMethod = "getFixedPointScaleOpValue"; 655 let DecoderMethod = "DecodeFixedPointScaleImm32"; 656 let ParserMatchClass = Imm1_32Operand; 657} 658 659class fixedpoint_i64<ValueType FloatVT> 660 : Operand<FloatVT>, 661 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 662 let EncoderMethod = "getFixedPointScaleOpValue"; 663 let DecoderMethod = "DecodeFixedPointScaleImm64"; 664 let ParserMatchClass = Imm1_64Operand; 665} 666 667def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 668def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 669def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 670 671def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 672def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 673def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 674 675def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 676 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 677}]> { 678 let EncoderMethod = "getVecShiftR8OpValue"; 679 let DecoderMethod = "DecodeVecShiftR8Imm"; 680 let ParserMatchClass = Imm1_8Operand; 681} 682def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 683 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 684}]> { 685 let EncoderMethod = "getVecShiftR16OpValue"; 686 let DecoderMethod = "DecodeVecShiftR16Imm"; 687 let ParserMatchClass = Imm1_16Operand; 688} 689def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 690 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 691}]> { 692 let EncoderMethod = "getVecShiftR16OpValue"; 693 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 694 let ParserMatchClass = Imm1_8Operand; 695} 696def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 697 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 698}]> { 699 let EncoderMethod = "getVecShiftR32OpValue"; 700 let DecoderMethod = "DecodeVecShiftR32Imm"; 701 let ParserMatchClass = Imm1_32Operand; 702} 703def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 704 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 705}]> { 706 let EncoderMethod = "getVecShiftR32OpValue"; 707 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 708 let ParserMatchClass = Imm1_16Operand; 709} 710def vecshiftR64 : Operand<i32>, ImmLeaf<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} 717def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 718 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 719}]> { 720 let EncoderMethod = "getVecShiftR64OpValue"; 721 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 722 let ParserMatchClass = Imm1_32Operand; 723} 724 725// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 726// (ImmLeaf) 727def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 728 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 729}]> { 730 let EncoderMethod = "getVecShiftR8OpValue"; 731 let DecoderMethod = "DecodeVecShiftR8Imm"; 732 let ParserMatchClass = Imm1_8Operand; 733} 734def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 735 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 736}]> { 737 let EncoderMethod = "getVecShiftR16OpValue"; 738 let DecoderMethod = "DecodeVecShiftR16Imm"; 739 let ParserMatchClass = Imm1_16Operand; 740} 741def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 742 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 743}]> { 744 let EncoderMethod = "getVecShiftR32OpValue"; 745 let DecoderMethod = "DecodeVecShiftR32Imm"; 746 let ParserMatchClass = Imm1_32Operand; 747} 748def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 749 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 750}]> { 751 let EncoderMethod = "getVecShiftR64OpValue"; 752 let DecoderMethod = "DecodeVecShiftR64Imm"; 753 let ParserMatchClass = Imm1_64Operand; 754} 755 756def Imm0_0Operand : AsmImmRange<0, 0>; 757def Imm0_1Operand : AsmImmRange<0, 1>; 758def Imm0_3Operand : AsmImmRange<0, 3>; 759def Imm0_7Operand : AsmImmRange<0, 7>; 760def Imm0_15Operand : AsmImmRange<0, 15>; 761def Imm0_31Operand : AsmImmRange<0, 31>; 762def Imm0_63Operand : AsmImmRange<0, 63>; 763 764def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 765 return (((uint32_t)Imm) < 8); 766}]> { 767 let EncoderMethod = "getVecShiftL8OpValue"; 768 let DecoderMethod = "DecodeVecShiftL8Imm"; 769 let ParserMatchClass = Imm0_7Operand; 770} 771def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 772 return (((uint32_t)Imm) < 16); 773}]> { 774 let EncoderMethod = "getVecShiftL16OpValue"; 775 let DecoderMethod = "DecodeVecShiftL16Imm"; 776 let ParserMatchClass = Imm0_15Operand; 777} 778def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 779 return (((uint32_t)Imm) < 32); 780}]> { 781 let EncoderMethod = "getVecShiftL32OpValue"; 782 let DecoderMethod = "DecodeVecShiftL32Imm"; 783 let ParserMatchClass = Imm0_31Operand; 784} 785def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 786 return (((uint32_t)Imm) < 64); 787}]> { 788 let EncoderMethod = "getVecShiftL64OpValue"; 789 let DecoderMethod = "DecodeVecShiftL64Imm"; 790 let ParserMatchClass = Imm0_63Operand; 791} 792 793// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 794// (ImmLeaf) 795def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 796 return (((uint32_t)Imm) < 8); 797}]> { 798 let EncoderMethod = "getVecShiftL8OpValue"; 799 let DecoderMethod = "DecodeVecShiftL8Imm"; 800 let ParserMatchClass = Imm0_7Operand; 801} 802def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 803 return (((uint32_t)Imm) < 16); 804}]> { 805 let EncoderMethod = "getVecShiftL16OpValue"; 806 let DecoderMethod = "DecodeVecShiftL16Imm"; 807 let ParserMatchClass = Imm0_15Operand; 808} 809def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 810 return (((uint32_t)Imm) < 32); 811}]> { 812 let EncoderMethod = "getVecShiftL32OpValue"; 813 let DecoderMethod = "DecodeVecShiftL32Imm"; 814 let ParserMatchClass = Imm0_31Operand; 815} 816def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 817 return (((uint32_t)Imm) < 64); 818}]> { 819 let EncoderMethod = "getVecShiftL64OpValue"; 820 let DecoderMethod = "DecodeVecShiftL64Imm"; 821 let ParserMatchClass = Imm0_63Operand; 822} 823 824// Crazy immediate formats used by 32-bit and 64-bit logical immediate 825// instructions for splatting repeating bit patterns across the immediate. 826def logical_imm32_XFORM : SDNodeXForm<imm, [{ 827 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 828 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 829}]>; 830def logical_imm64_XFORM : SDNodeXForm<imm, [{ 831 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 832 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 833}]>; 834 835def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 836 GISDNodeXFormEquiv<logical_imm32_XFORM>; 837def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 838 GISDNodeXFormEquiv<logical_imm64_XFORM>; 839 840let DiagnosticType = "LogicalSecondSource" in { 841 def LogicalImm32Operand : AsmOperandClass { 842 let Name = "LogicalImm32"; 843 let PredicateMethod = "isLogicalImm<int32_t>"; 844 let RenderMethod = "addLogicalImmOperands<int32_t>"; 845 } 846 def LogicalImm64Operand : AsmOperandClass { 847 let Name = "LogicalImm64"; 848 let PredicateMethod = "isLogicalImm<int64_t>"; 849 let RenderMethod = "addLogicalImmOperands<int64_t>"; 850 } 851 def LogicalImm32NotOperand : AsmOperandClass { 852 let Name = "LogicalImm32Not"; 853 let PredicateMethod = "isLogicalImm<int32_t>"; 854 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 855 } 856 def LogicalImm64NotOperand : AsmOperandClass { 857 let Name = "LogicalImm64Not"; 858 let PredicateMethod = "isLogicalImm<int64_t>"; 859 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 860 } 861} 862def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 863 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 864}], logical_imm32_XFORM> { 865 let PrintMethod = "printLogicalImm<int32_t>"; 866 let ParserMatchClass = LogicalImm32Operand; 867} 868def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 869 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 870}], logical_imm64_XFORM> { 871 let PrintMethod = "printLogicalImm<int64_t>"; 872 let ParserMatchClass = LogicalImm64Operand; 873} 874def logical_imm32_not : Operand<i32> { 875 let ParserMatchClass = LogicalImm32NotOperand; 876} 877def logical_imm64_not : Operand<i64> { 878 let ParserMatchClass = LogicalImm64NotOperand; 879} 880 881// immXX_0_65535 predicates - True if the immediate is in the range [0,65535]. 882let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 883def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{ 884 return ((uint32_t)Imm) < 65536; 885}]>; 886 887def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{ 888 return ((uint64_t)Imm) < 65536; 889}]>; 890} 891 892def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 893 return ((uint32_t)Imm) < 256; 894}]> { 895 let ParserMatchClass = Imm0_255Operand; 896 let PrintMethod = "printImm"; 897} 898 899// imm0_127 predicate - True if the immediate is in the range [0,127] 900def Imm0_127Operand : AsmImmRange<0, 127>; 901def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 902 return ((uint32_t)Imm) < 128; 903}]> { 904 let ParserMatchClass = Imm0_127Operand; 905 let PrintMethod = "printImm"; 906} 907 908def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 909 return ((uint64_t)Imm) < 128; 910}]> { 911 let ParserMatchClass = Imm0_127Operand; 912 let PrintMethod = "printImm"; 913} 914 915// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 916// for all shift-amounts. 917 918// imm0_63 predicate - True if the immediate is in the range [0,63] 919def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 920 return ((uint64_t)Imm) < 64; 921}]> { 922 let ParserMatchClass = Imm0_63Operand; 923} 924 925def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 926 return ((uint64_t)Imm) < 64; 927}]> { 928 let ParserMatchClass = Imm0_63Operand; 929} 930 931// imm0_31 predicate - True if the immediate is in the range [0,31] 932def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 933 return ((uint64_t)Imm) < 32; 934}]> { 935 let ParserMatchClass = Imm0_31Operand; 936} 937 938// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 939// instead of Constant (ImmLeaf) 940def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 941 return ((uint64_t)Imm) < 32; 942}]> { 943 let ParserMatchClass = Imm0_31Operand; 944} 945 946// True if the 32-bit immediate is in the range [0,31] 947def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 948 return ((uint64_t)Imm) < 32; 949}]> { 950 let ParserMatchClass = Imm0_31Operand; 951} 952 953// imm0_1 predicate - True if the immediate is in the range [0,1] 954def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 955 return ((uint64_t)Imm) < 2; 956}]> { 957 let ParserMatchClass = Imm0_1Operand; 958} 959 960// timm0_1 - as above, but use TargetConstant (TImmLeaf) 961def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 962 return ((uint64_t)Imm) < 2; 963}]> { 964 let ParserMatchClass = Imm0_1Operand; 965} 966 967// timm32_0_1 predicate - True if the 32-bit immediate is in the range [0,1] 968def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{ 969 return ((uint32_t)Imm) < 2; 970}]> { 971 let ParserMatchClass = Imm0_1Operand; 972} 973 974// imm0_15 predicate - True if the immediate is in the range [0,15] 975def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 976 return ((uint64_t)Imm) < 16; 977}]> { 978 let ParserMatchClass = Imm0_15Operand; 979} 980 981// imm0_7 predicate - True if the immediate is in the range [0,7] 982def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 983 return ((uint64_t)Imm) < 8; 984}]> { 985 let ParserMatchClass = Imm0_7Operand; 986} 987 988// imm0_3 predicate - True if the immediate is in the range [0,3] 989def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 990 return ((uint64_t)Imm) < 4; 991}]> { 992 let ParserMatchClass = Imm0_3Operand; 993} 994 995// timm32_0_3 predicate - True if the 32-bit immediate is in the range [0,3] 996def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{ 997 return ((uint32_t)Imm) < 4; 998}]> { 999 let ParserMatchClass = Imm0_3Operand; 1000} 1001 1002// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 1003def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 1004 return ((uint32_t)Imm) < 8; 1005}]> { 1006 let ParserMatchClass = Imm0_7Operand; 1007} 1008 1009// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1010def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 1011 return ((uint32_t)Imm) < 16; 1012}]> { 1013 let ParserMatchClass = Imm0_15Operand; 1014} 1015 1016// timm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1017def timm32_0_15 : Operand<i32>, TImmLeaf<i32, [{ 1018 return ((uint32_t)Imm) < 16; 1019}]> { 1020 let ParserMatchClass = Imm0_15Operand; 1021} 1022 1023// timm32_0_31 predicate - True if the 32-bit immediate is in the range [0,31] 1024def timm32_0_31 : Operand<i32>, TImmLeaf<i32, [{ 1025 return ((uint32_t)Imm) < 32; 1026}]> { 1027 let ParserMatchClass = Imm0_31Operand; 1028} 1029 1030// timm32_0_255 predicate - True if the 32-bit immediate is in the range [0,255] 1031def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{ 1032 return ((uint32_t)Imm) < 256; 1033}]> { 1034 let ParserMatchClass = Imm0_255Operand; 1035} 1036 1037// An arithmetic shifter operand: 1038// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 1039// {5-0} - imm6 1040class arith_shift<ValueType Ty, int width> : Operand<Ty> { 1041 let PrintMethod = "printShifter"; 1042 let ParserMatchClass = !cast<AsmOperandClass>( 1043 "ArithmeticShifterOperand" # width); 1044} 1045 1046def arith_shift32 : arith_shift<i32, 32>; 1047def arith_shift64 : arith_shift<i64, 64>; 1048 1049class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 1050 : Operand<Ty>, 1051 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 1052 let PrintMethod = "printShiftedRegister"; 1053 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 1054} 1055 1056def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 1057def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 1058 1059def gi_arith_shifted_reg32 : 1060 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 1061 GIComplexPatternEquiv<arith_shifted_reg32>; 1062 1063def gi_arith_shifted_reg64 : 1064 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1065 GIComplexPatternEquiv<arith_shifted_reg64>; 1066 1067// An arithmetic shifter operand: 1068// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1069// {5-0} - imm6 1070class logical_shift<int width> : Operand<i32> { 1071 let PrintMethod = "printShifter"; 1072 let ParserMatchClass = !cast<AsmOperandClass>( 1073 "LogicalShifterOperand" # width); 1074} 1075 1076def logical_shift32 : logical_shift<32>; 1077def logical_shift64 : logical_shift<64>; 1078 1079class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1080 : Operand<Ty>, 1081 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1082 let PrintMethod = "printShiftedRegister"; 1083 let MIOperandInfo = (ops regclass, shiftop); 1084} 1085 1086def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1087def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1088 1089def gi_logical_shifted_reg32 : 1090 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1091 GIComplexPatternEquiv<logical_shifted_reg32>; 1092 1093def gi_logical_shifted_reg64 : 1094 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1095 GIComplexPatternEquiv<logical_shifted_reg64>; 1096 1097// A logical vector shifter operand: 1098// {7-6} - shift type: 00 = lsl 1099// {5-0} - imm6: #0, #8, #16, or #24 1100def logical_vec_shift : Operand<i32> { 1101 let PrintMethod = "printShifter"; 1102 let EncoderMethod = "getVecShifterOpValue"; 1103 let ParserMatchClass = LogicalVecShifterOperand; 1104} 1105 1106// A logical vector half-word shifter operand: 1107// {7-6} - shift type: 00 = lsl 1108// {5-0} - imm6: #0 or #8 1109def logical_vec_hw_shift : Operand<i32> { 1110 let PrintMethod = "printShifter"; 1111 let EncoderMethod = "getVecShifterOpValue"; 1112 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1113} 1114 1115// A vector move shifter operand: 1116// {0} - imm1: #8 or #16 1117def move_vec_shift : Operand<i32> { 1118 let PrintMethod = "printShifter"; 1119 let EncoderMethod = "getMoveVecShifterOpValue"; 1120 let ParserMatchClass = MoveVecShifterOperand; 1121} 1122 1123let DiagnosticType = "AddSubSecondSource" in { 1124 def AddSubImmOperand : AsmOperandClass { 1125 let Name = "AddSubImm"; 1126 let ParserMethod = "tryParseImmWithOptionalShift"; 1127 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1128 } 1129 def AddSubImmNegOperand : AsmOperandClass { 1130 let Name = "AddSubImmNeg"; 1131 let ParserMethod = "tryParseImmWithOptionalShift"; 1132 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1133 } 1134} 1135// An ADD/SUB immediate shifter operand: 1136// second operand: 1137// {7-6} - shift type: 00 = lsl 1138// {5-0} - imm6: #0 or #12 1139class addsub_shifted_imm<ValueType Ty> 1140 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1141 let PrintMethod = "printAddSubImm"; 1142 let EncoderMethod = "getAddSubImmOpValue"; 1143 let ParserMatchClass = AddSubImmOperand; 1144 let MIOperandInfo = (ops i32imm, i32imm); 1145} 1146 1147class addsub_shifted_imm_neg<ValueType Ty> 1148 : Operand<Ty> { 1149 let EncoderMethod = "getAddSubImmOpValue"; 1150 let ParserMatchClass = AddSubImmNegOperand; 1151 let MIOperandInfo = (ops i32imm, i32imm); 1152} 1153 1154def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1155def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1156def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1157def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1158 1159def gi_addsub_shifted_imm32 : 1160 GIComplexOperandMatcher<s32, "selectArithImmed">, 1161 GIComplexPatternEquiv<addsub_shifted_imm32>; 1162 1163def gi_addsub_shifted_imm64 : 1164 GIComplexOperandMatcher<s64, "selectArithImmed">, 1165 GIComplexPatternEquiv<addsub_shifted_imm64>; 1166 1167class neg_addsub_shifted_imm<ValueType Ty> 1168 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1169 let PrintMethod = "printAddSubImm"; 1170 let EncoderMethod = "getAddSubImmOpValue"; 1171 let ParserMatchClass = AddSubImmOperand; 1172 let MIOperandInfo = (ops i32imm, i32imm); 1173} 1174 1175def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1176def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1177 1178def gi_neg_addsub_shifted_imm32 : 1179 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1180 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1181 1182def gi_neg_addsub_shifted_imm64 : 1183 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1184 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1185 1186// An extend operand: 1187// {5-3} - extend type 1188// {2-0} - imm3 1189def arith_extend : Operand<i32> { 1190 let PrintMethod = "printArithExtend"; 1191 let ParserMatchClass = ExtendOperand; 1192} 1193def arith_extend64 : Operand<i32> { 1194 let PrintMethod = "printArithExtend"; 1195 let ParserMatchClass = ExtendOperand64; 1196} 1197 1198// 'extend' that's a lsl of a 64-bit register. 1199def arith_extendlsl64 : Operand<i32> { 1200 let PrintMethod = "printArithExtend"; 1201 let ParserMatchClass = ExtendOperandLSL64; 1202} 1203 1204class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1205 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1206 let PrintMethod = "printExtendedRegister"; 1207 let MIOperandInfo = (ops GPR32, arith_extend); 1208} 1209 1210class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1211 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1212 let PrintMethod = "printExtendedRegister"; 1213 let MIOperandInfo = (ops GPR32, arith_extend64); 1214} 1215 1216def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1217def gi_arith_extended_reg32_i32 : 1218 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1219 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1220 1221def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1222def gi_arith_extended_reg32_i64 : 1223 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1224 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1225 1226def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1227def gi_arith_extended_reg32to64_i64 : 1228 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1229 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1230 1231def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>; 1232 1233// Floating-point immediate. 1234 1235def fpimm16XForm : SDNodeXForm<fpimm, [{ 1236 APFloat InVal = N->getValueAPF(); 1237 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1238 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1239 }]>; 1240 1241def fpimm32XForm : SDNodeXForm<fpimm, [{ 1242 APFloat InVal = N->getValueAPF(); 1243 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1244 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1245 }]>; 1246 1247def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{ 1248 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF() 1249 .bitcastToAPInt() 1250 .getZExtValue()); 1251 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1252 }]>; 1253 1254def fpimm64XForm : SDNodeXForm<fpimm, [{ 1255 APFloat InVal = N->getValueAPF(); 1256 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1257 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1258 }]>; 1259 1260def fpimm16 : Operand<f16>, 1261 FPImmLeaf<f16, [{ 1262 return AArch64_AM::getFP16Imm(Imm) != -1; 1263 }], fpimm16XForm> { 1264 let ParserMatchClass = FPImmOperand; 1265 let PrintMethod = "printFPImmOperand"; 1266} 1267 1268def fpimm32 : Operand<f32>, 1269 FPImmLeaf<f32, [{ 1270 return AArch64_AM::getFP32Imm(Imm) != -1; 1271 }], fpimm32XForm> { 1272 let ParserMatchClass = FPImmOperand; 1273 let PrintMethod = "printFPImmOperand"; 1274} 1275 1276def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{ 1277 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue(); 1278 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc); 1279 }], fpimm32SIMDModImmType4XForm> { 1280} 1281 1282def fpimm64 : Operand<f64>, 1283 FPImmLeaf<f64, [{ 1284 return AArch64_AM::getFP64Imm(Imm) != -1; 1285 }], fpimm64XForm> { 1286 let ParserMatchClass = FPImmOperand; 1287 let PrintMethod = "printFPImmOperand"; 1288} 1289 1290def fpimm8 : Operand<i32> { 1291 let ParserMatchClass = FPImmOperand; 1292 let PrintMethod = "printFPImmOperand"; 1293} 1294 1295def fpimm0 : FPImmLeaf<fAny, [{ 1296 return Imm.isExactlyValue(+0.0); 1297}]>; 1298 1299def fpimm_minus0 : FPImmLeaf<fAny, [{ 1300 return Imm.isExactlyValue(-0.0); 1301}]>; 1302 1303def fpimm_half : FPImmLeaf<fAny, [{ 1304 return Imm.isExactlyValue(+0.5); 1305}]>; 1306 1307def fpimm_one : FPImmLeaf<fAny, [{ 1308 return Imm.isExactlyValue(+1.0); 1309}]>; 1310 1311def fpimm_two : FPImmLeaf<fAny, [{ 1312 return Imm.isExactlyValue(+2.0); 1313}]>; 1314 1315def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1316 GISDNodeXFormEquiv<fpimm16XForm>; 1317def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1318 GISDNodeXFormEquiv<fpimm32XForm>; 1319def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1320 GISDNodeXFormEquiv<fpimm64XForm>; 1321def gi_fpimm32SIMDModImmType4 : 1322 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1323 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1324 1325// Vector lane operands 1326class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1327 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1328 let DiagnosticType = "Invalid" # Name; 1329 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1330 let RenderMethod = "addVectorIndexOperands"; 1331} 1332 1333class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1334 : Operand<ty> { 1335 let ParserMatchClass = mc; 1336 let PrintMethod = "printVectorIndex"; 1337} 1338 1339multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1340 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1341 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1342} 1343 1344def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1345def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1346def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1347def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1348def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1349def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1350 1351let OperandNamespace = "AArch64" in { 1352 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1353 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1354 [{ return ((uint64_t)Imm) == 0; }]>; 1355 } 1356} 1357defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1358 [{ return ((uint64_t)Imm) == 1; }]>; 1359defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1360 [{ return ((uint64_t)Imm) < 16; }]>; 1361defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1362 [{ return ((uint64_t)Imm) < 8; }]>; 1363defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1364 [{ return ((uint64_t)Imm) < 4; }]>; 1365defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1366 [{ return ((uint64_t)Imm) < 2; }]>; 1367 1368defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1369 [{ return ((uint64_t)Imm) == 1; }]>; 1370defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1371 [{ return ((uint64_t)Imm) < 16; }]>; 1372defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1373 [{ return ((uint64_t)Imm) < 8; }]>; 1374defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1375 [{ return ((uint64_t)Imm) < 4; }]>; 1376defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1377 [{ return ((uint64_t)Imm) < 2; }]>; 1378 1379def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1380def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1381def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1382def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1383def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1384 1385defm sve_elm_idx_extdup_b 1386 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1387 [{ return ((uint64_t)Imm) < 64; }]>; 1388defm sve_elm_idx_extdup_h 1389 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1390 [{ return ((uint64_t)Imm) < 32; }]>; 1391defm sve_elm_idx_extdup_s 1392 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1393 [{ return ((uint64_t)Imm) < 16; }]>; 1394defm sve_elm_idx_extdup_d 1395 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1396 [{ return ((uint64_t)Imm) < 8; }]>; 1397defm sve_elm_idx_extdup_q 1398 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1399 [{ return ((uint64_t)Imm) < 4; }]>; 1400 1401def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{ 1402 return ((uint32_t)Imm) == 0; 1403}]> { 1404 let ParserMatchClass = Imm0_0Operand; 1405 let PrintMethod = "printMatrixIndex"; 1406 let OperandNamespace = "AArch64"; 1407 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1408} 1409def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{ 1410 return ((uint32_t)Imm) <= 1; 1411}]> { 1412 let ParserMatchClass = Imm0_1Operand; 1413 let PrintMethod = "printMatrixIndex"; 1414} 1415def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{ 1416 return ((uint32_t)Imm) <= 3; 1417}]> { 1418 let ParserMatchClass = Imm0_3Operand; 1419 let PrintMethod = "printMatrixIndex"; 1420} 1421def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{ 1422 return ((uint32_t)Imm) <= 7; 1423}]> { 1424 let ParserMatchClass = Imm0_7Operand; 1425 let PrintMethod = "printMatrixIndex"; 1426} 1427def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{ 1428 return ((uint32_t)Imm) <= 15; 1429}]> { 1430 let ParserMatchClass = Imm0_15Operand; 1431 let PrintMethod = "printMatrixIndex"; 1432} 1433 1434// SME2 vector select offset operands 1435 1436// uimm3s8 predicate 1437// True if the immediate is a multiple of 8 in the range [0,56]. 1438def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>; 1439 1440def uimm3s8 : Operand<i64>, ImmLeaf<i64, 1441[{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> { 1442 let PrintMethod = "printVectorIndex<8>"; 1443 let ParserMatchClass = UImm3s8Operand; 1444} 1445 1446class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass { 1447 let Name = "UImm" # Width # "s" # Scale # "Range"; 1448 let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width; 1449 let RenderMethod = "addImmScaledRangeOperands<" # Scale # ">"; 1450 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ", " # OffsetVal # ", /*IsRange=*/true>"; 1451 let ParserMethod = "tryParseImmRange"; 1452} 1453 1454// Implicit immediate ranges 0:1 and 0:3, scale has no meaning 1455// since the immediate is zero 1456def UImm0s2RangeOperand : UImmScaledMemoryIndexedRange<0, 2, 1>; 1457def UImm0s4RangeOperand : UImmScaledMemoryIndexedRange<0, 4, 3>; 1458 1459def UImm1s2RangeOperand : UImmScaledMemoryIndexedRange<1, 2, 1>; 1460def UImm1s4RangeOperand : UImmScaledMemoryIndexedRange<1, 4, 3>; 1461def UImm2s2RangeOperand : UImmScaledMemoryIndexedRange<2, 2, 1>; 1462def UImm2s4RangeOperand : UImmScaledMemoryIndexedRange<2, 4, 3>; 1463def UImm3s2RangeOperand : UImmScaledMemoryIndexedRange<3, 2, 1>; 1464 1465def uimm0s2range : Operand<i64>, ImmLeaf<i64, 1466[{ return Imm == 0; }], UImmS1XForm> { 1467 let PrintMethod = "printImmRangeScale<2, 1>"; 1468 let ParserMatchClass = UImm0s2RangeOperand; 1469 let OperandNamespace = "AArch64"; 1470 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1471} 1472 1473def uimm0s4range : Operand<i64>, ImmLeaf<i64, 1474[{ return Imm == 0; }], UImmS1XForm> { 1475 let PrintMethod = "printImmRangeScale<4, 3>"; 1476 let ParserMatchClass = UImm0s4RangeOperand; 1477 let OperandNamespace = "AArch64"; 1478 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1479} 1480 1481def uimm1s2range : Operand<i64>, ImmLeaf<i64, 1482[{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> { 1483 let PrintMethod = "printImmRangeScale<2, 1>"; 1484 let ParserMatchClass = UImm1s2RangeOperand; 1485} 1486 1487def uimm1s4range : Operand<i64>, ImmLeaf<i64, 1488[{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> { 1489 let PrintMethod = "printImmRangeScale<4, 3>"; 1490 let ParserMatchClass = UImm1s4RangeOperand; 1491} 1492 1493def uimm2s2range : Operand<i64>, ImmLeaf<i64, 1494[{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> { 1495 let PrintMethod = "printImmRangeScale<2, 1>"; 1496 let ParserMatchClass = UImm2s2RangeOperand; 1497} 1498 1499def uimm2s4range : Operand<i64>, ImmLeaf<i64, 1500[{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> { 1501 let PrintMethod = "printImmRangeScale<4, 3>"; 1502 let ParserMatchClass = UImm2s4RangeOperand; 1503} 1504 1505def uimm3s2range : Operand<i64>, ImmLeaf<i64, 1506[{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> { 1507 let PrintMethod = "printImmRangeScale<2, 1>"; 1508 let ParserMatchClass = UImm3s2RangeOperand; 1509} 1510 1511 1512// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1513// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1514// are encoded as the eight bit value 'abcdefgh'. 1515def simdimmtype10 : Operand<i32>, 1516 FPImmLeaf<f64, [{ 1517 return AArch64_AM::isAdvSIMDModImmType10( 1518 Imm.bitcastToAPInt().getZExtValue()); 1519 }], SDNodeXForm<fpimm, [{ 1520 APFloat InVal = N->getValueAPF(); 1521 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1522 .bitcastToAPInt() 1523 .getZExtValue()); 1524 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1525 }]>> { 1526 let ParserMatchClass = SIMDImmType10Operand; 1527 let PrintMethod = "printSIMDType10Operand"; 1528} 1529 1530 1531//--- 1532// System management 1533//--- 1534 1535// Base encoding for system instruction operands. 1536let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1537class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1538 list<dag> pattern = []> 1539 : I<oops, iops, asm, operands, "", pattern> { 1540 let Inst{31-22} = 0b1101010100; 1541 let Inst{21} = L; 1542} 1543 1544// System instructions which do not have an Rt register. 1545class SimpleSystemI<bit L, dag iops, string asm, string operands, 1546 list<dag> pattern = []> 1547 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1548 let Inst{4-0} = 0b11111; 1549} 1550 1551// System instructions which have an Rt register. 1552class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1553 list<dag> pattern = []> 1554 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1555 Sched<[WriteSys]> { 1556 bits<5> Rt; 1557 let Inst{4-0} = Rt; 1558} 1559 1560// System instructions for transactional memory extension 1561class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1562 string asm, string operands, list<dag> pattern> 1563 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1564 Sched<[WriteSys]> { 1565 let Inst{20-12} = 0b000110011; 1566 let Inst{11-8} = CRm; 1567 let Inst{7-5} = op2; 1568 let DecoderMethod = ""; 1569 1570 let mayLoad = 1; 1571 let mayStore = 1; 1572} 1573 1574// System instructions for transactional memory - single input operand 1575class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1576 : TMBaseSystemI<0b1, CRm, 0b011, 1577 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1578 bits<5> Rt; 1579 let Inst{4-0} = Rt; 1580} 1581 1582// System instructions that pass a register argument 1583// This class assumes the register is for input rather than output. 1584class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1585 list<dag> pattern = []> 1586 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1587 let Inst{20-12} = 0b000110001; 1588 let Inst{11-8} = CRm; 1589 let Inst{7-5} = Op2; 1590} 1591 1592// System instructions for transactional memory - no operand 1593class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1594 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1595 let Inst{4-0} = 0b11111; 1596} 1597 1598// System instructions for exit from transactions 1599class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1600 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1601 Sched<[WriteSys]> { 1602 bits<16> imm; 1603 let Inst{31-24} = 0b11010100; 1604 let Inst{23-21} = op1; 1605 let Inst{20-5} = imm; 1606 let Inst{4-0} = 0b00000; 1607} 1608 1609// Hint instructions that take both a CRm and a 3-bit immediate. 1610// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1611// model patterns with sufficiently fine granularity 1612let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1613 class HintI<string mnemonic> 1614 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1615 [(int_aarch64_hint imm0_127:$imm)]>, 1616 Sched<[WriteHint]> { 1617 bits <7> imm; 1618 let Inst{20-12} = 0b000110010; 1619 let Inst{11-5} = imm; 1620 } 1621 1622// System instructions taking a single literal operand which encodes into 1623// CRm. op2 differentiates the opcodes. 1624def BarrierAsmOperand : AsmOperandClass { 1625 let Name = "Barrier"; 1626 let ParserMethod = "tryParseBarrierOperand"; 1627} 1628def barrier_op : Operand<i32> { 1629 let PrintMethod = "printBarrierOption"; 1630 let ParserMatchClass = BarrierAsmOperand; 1631} 1632def BarriernXSAsmOperand : AsmOperandClass { 1633 let Name = "BarriernXS"; 1634 let ParserMethod = "tryParseBarriernXSOperand"; 1635} 1636def barrier_nxs_op : Operand<i32> { 1637 let PrintMethod = "printBarriernXSOption"; 1638 let ParserMatchClass = BarriernXSAsmOperand; 1639} 1640class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1641 list<dag> pattern = []> 1642 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1643 Sched<[WriteBarrier]> { 1644 bits<4> CRm; 1645 let Inst{20-12} = 0b000110011; 1646 let Inst{11-8} = CRm; 1647 let Inst{7-5} = opc; 1648} 1649 1650class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1651 : SimpleSystemI<0, (ins), asm, "", pattern>, 1652 Sched<[WriteHint]> { 1653 bits<4> CRm; 1654 let CRm = 0b0011; 1655 let Inst{31-12} = 0b11010101000000110010; 1656 let Inst{11-8} = CRm; 1657 let Inst{7-5} = op2; 1658 let Inst{4-0} = 0b11111; 1659} 1660 1661// MRS/MSR system instructions. These have different operand classes because 1662// a different subset of registers can be accessed through each instruction. 1663def MRSSystemRegisterOperand : AsmOperandClass { 1664 let Name = "MRSSystemRegister"; 1665 let ParserMethod = "tryParseSysReg"; 1666 let DiagnosticType = "MRS"; 1667} 1668// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1669def mrs_sysreg_op : Operand<i32> { 1670 let ParserMatchClass = MRSSystemRegisterOperand; 1671 let DecoderMethod = "DecodeMRSSystemRegister"; 1672 let PrintMethod = "printMRSSystemRegister"; 1673} 1674 1675def MSRSystemRegisterOperand : AsmOperandClass { 1676 let Name = "MSRSystemRegister"; 1677 let ParserMethod = "tryParseSysReg"; 1678 let DiagnosticType = "MSR"; 1679} 1680def msr_sysreg_op : Operand<i32> { 1681 let ParserMatchClass = MSRSystemRegisterOperand; 1682 let DecoderMethod = "DecodeMSRSystemRegister"; 1683 let PrintMethod = "printMSRSystemRegister"; 1684} 1685 1686def PSBHintOperand : AsmOperandClass { 1687 let Name = "PSBHint"; 1688 let ParserMethod = "tryParsePSBHint"; 1689} 1690def psbhint_op : Operand<i32> { 1691 let ParserMatchClass = PSBHintOperand; 1692 let PrintMethod = "printPSBHintOp"; 1693 let MCOperandPredicate = [{ 1694 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1695 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1696 if (!MCOp.isImm()) 1697 return false; 1698 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1699 }]; 1700} 1701 1702def BTIHintOperand : AsmOperandClass { 1703 let Name = "BTIHint"; 1704 let ParserMethod = "tryParseBTIHint"; 1705} 1706def btihint_op : Operand<i32> { 1707 let ParserMatchClass = BTIHintOperand; 1708 let PrintMethod = "printBTIHintOp"; 1709 let MCOperandPredicate = [{ 1710 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1711 if (!MCOp.isImm()) 1712 return false; 1713 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1714 }]; 1715} 1716 1717class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1718 "mrs", "\t$Rt, $systemreg"> { 1719 bits<16> systemreg; 1720 let Inst{20-5} = systemreg; 1721 let DecoderNamespace = "Fallback"; 1722 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1723 // require doing this. The alternative was to explicitly model each one, but 1724 // it feels like it is unnecessary because it seems there are no negative 1725 // consequences setting these flags for all. 1726 let Defs = [NZCV]; 1727} 1728 1729// FIXME: Some of these def NZCV, others don't. Best way to model that? 1730// Explicitly modeling each of the system register as a register class 1731// would do it, but feels like overkill at this point. 1732class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1733 "msr", "\t$systemreg, $Rt"> { 1734 bits<16> systemreg; 1735 let Inst{20-5} = systemreg; 1736 let DecoderNamespace = "Fallback"; 1737} 1738 1739def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1740 let Name = "SystemPStateFieldWithImm0_15"; 1741 let ParserMethod = "tryParseSysReg"; 1742} 1743def pstatefield4_op : Operand<i32> { 1744 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1745 let PrintMethod = "printSystemPStateField"; 1746 let MCOperandPredicate = [{ 1747 if (!MCOp.isImm()) 1748 return false; 1749 return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr; 1750 }]; 1751} 1752 1753// Instructions to modify PSTATE, no input reg 1754let Defs = [NZCV] in 1755class PstateWriteSimple<dag iops, string asm, string operands> 1756 : SimpleSystemI<0, iops, asm, operands> { 1757 1758 let Inst{20-19} = 0b00; 1759 let Inst{15-12} = 0b0100; 1760} 1761 1762class MSRpstateImm0_15 1763 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1764 "\t$pstatefield, $imm">, 1765 Sched<[WriteSys]> { 1766 1767 bits<6> pstatefield; 1768 bits<4> imm; 1769 let Inst{18-16} = pstatefield{5-3}; 1770 let Inst{11-8} = imm; 1771 let Inst{7-5} = pstatefield{2-0}; 1772 1773 let DecoderMethod = "DecodeSystemPStateImm0_15Instruction"; 1774 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1775 // Fail the decoder should attempt to decode the instruction as MSRI. 1776 let hasCompleteDecoder = false; 1777} 1778 1779def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1780 let Name = "SystemPStateFieldWithImm0_1"; 1781 let ParserMethod = "tryParseSysReg"; 1782} 1783def pstatefield1_op : Operand<i32> { 1784 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1785 let PrintMethod = "printSystemPStateField"; 1786 let MCOperandPredicate = [{ 1787 if (!MCOp.isImm()) 1788 return false; 1789 return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr; 1790 }]; 1791} 1792 1793class MSRpstateImm0_1 1794 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1795 "\t$pstatefield, $imm">, 1796 Sched<[WriteSys]> { 1797 1798 bits<9> pstatefield; 1799 bit imm; 1800 let Inst{18-16} = pstatefield{5-3}; 1801 let Inst{11-9} = pstatefield{8-6}; 1802 let Inst{8} = imm; 1803 let Inst{7-5} = pstatefield{2-0}; 1804 1805 let DecoderMethod = "DecodeSystemPStateImm0_1Instruction"; 1806 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1807 // Fail the decoder should attempt to decode the instruction as MSRI. 1808 let hasCompleteDecoder = false; 1809 let DecoderNamespace = "Fallback"; 1810} 1811 1812// SYS and SYSL generic system instructions. 1813def SysCRAsmOperand : AsmOperandClass { 1814 let Name = "SysCR"; 1815 let ParserMethod = "tryParseSysCROperand"; 1816} 1817 1818def sys_cr_op : Operand<i32> { 1819 let PrintMethod = "printSysCROperand"; 1820 let ParserMatchClass = SysCRAsmOperand; 1821} 1822 1823class SystemXtI<bit L, string asm> 1824 : RtSystemI<L, (outs), 1825 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1826 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1827 bits<3> op1; 1828 bits<4> Cn; 1829 bits<4> Cm; 1830 bits<3> op2; 1831 let Inst{20-19} = 0b01; 1832 let Inst{18-16} = op1; 1833 let Inst{15-12} = Cn; 1834 let Inst{11-8} = Cm; 1835 let Inst{7-5} = op2; 1836} 1837 1838class SystemLXtI<bit L, string asm> 1839 : RtSystemI<L, (outs), 1840 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1841 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1842 bits<3> op1; 1843 bits<4> Cn; 1844 bits<4> Cm; 1845 bits<3> op2; 1846 let Inst{20-19} = 0b01; 1847 let Inst{18-16} = op1; 1848 let Inst{15-12} = Cn; 1849 let Inst{11-8} = Cm; 1850 let Inst{7-5} = op2; 1851} 1852 1853def RangePrefetchOperand : AsmOperandClass { 1854 let Name = "RangePrefetch"; 1855 let ParserMethod = "tryParseRPRFMOperand"; 1856 let PredicateMethod = "isPrefetch"; 1857 let RenderMethod = "addPrefetchOperands"; 1858} 1859 1860def rprfop : Operand<i32>, TImmLeaf<i32, [{ 1861 return (((uint32_t)Imm) <= 63); 1862 }]> { 1863 let PrintMethod = "printRPRFMOperand"; 1864 let ParserMatchClass = RangePrefetchOperand; 1865} 1866 1867// Branch (register) instructions: 1868// 1869// case opc of 1870// 0001 blr 1871// 0000 br 1872// 0101 dret 1873// 0100 eret 1874// 0010 ret 1875// otherwise UNDEFINED 1876class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1877 string operands, list<dag> pattern> 1878 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1879 let Inst{31-25} = 0b1101011; 1880 let Inst{24-21} = opc; 1881 let Inst{20-16} = 0b11111; 1882 let Inst{15-10} = 0b000000; 1883 let Inst{4-0} = 0b00000; 1884} 1885 1886class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1887 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1888 bits<5> Rn; 1889 let Inst{9-5} = Rn; 1890} 1891 1892let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1893class SpecialReturn<bits<4> opc, string asm> 1894 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1895 let Inst{9-5} = 0b11111; 1896} 1897 1898let mayLoad = 1 in 1899class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1900 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1901 Sched<[]> { 1902 bits<5> Rn; 1903 bits<5> Rt; 1904 let Inst{31-30} = sz; 1905 let Inst{29-10} = 0b11100010111111110000; 1906 let Inst{9-5} = Rn; 1907 let Inst{4-0} = Rt; 1908} 1909 1910class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1911 list<dag> pattern> 1912 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1913 let isAuthenticated = 1; 1914 let Inst{31-25} = 0b1101011; 1915 let Inst{20-11} = 0b1111100001; 1916 let Inst{10} = M; 1917 let Inst{4-0} = 0b11111; 1918} 1919 1920class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1921 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1922 bits<5> Rn; 1923 bits<5> Rm; 1924 let Inst{24-22} = 0b100; 1925 let Inst{21} = op; 1926 let Inst{9-5} = Rn; 1927 let Inst{4-0} = Rm; 1928} 1929 1930class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1931 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1932 bits<5> Rn; 1933 let Inst{24} = 0; 1934 let Inst{23-21} = opc; 1935 let Inst{9-5} = Rn; 1936} 1937 1938let Uses = [LR,SP] in 1939class AuthReturn<bits<3> op, bits<1> M, string asm> 1940 : AuthBase<M, (outs), (ins), asm, "", []> { 1941 let Inst{24} = 0; 1942 let Inst{23-21} = op; 1943 let Inst{9-0} = 0b1111111111; 1944} 1945 1946let mayLoad = 1 in 1947class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1948 string operands, string cstr> 1949 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1950 bits<10> offset; 1951 bits<5> Rn; 1952 bits<5> Rt; 1953 let isAuthenticated = 1; 1954 let Inst{31-24} = 0b11111000; 1955 let Inst{23} = M; 1956 let Inst{22} = offset{9}; 1957 let Inst{21} = 1; 1958 let Inst{20-12} = offset{8-0}; 1959 let Inst{11} = W; 1960 let Inst{10} = 1; 1961 let Inst{9-5} = Rn; 1962 let Inst{4-0} = Rt; 1963 1964 let DecoderMethod = "DecodeAuthLoadInstruction"; 1965} 1966 1967multiclass AuthLoad<bit M, string asm, Operand opr> { 1968 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1969 (ins GPR64sp:$Rn, opr:$offset), 1970 asm, "\t$Rt, [$Rn, $offset]", "">; 1971 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1972 (ins GPR64sp:$Rn, opr:$offset), 1973 asm, "\t$Rt, [$Rn, $offset]!", 1974 "$Rn = $wback,@earlyclobber $wback">; 1975 1976 def : InstAlias<asm # "\t$Rt, [$Rn]", 1977 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1978 1979 def : InstAlias<asm # "\t$Rt, [$wback]!", 1980 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 1981} 1982 1983//--- 1984// Conditional branch instruction. 1985//--- 1986 1987// Condition code. 1988// 4-bit immediate. Pretty-printed as <cc> 1989def ccode : Operand<i32> { 1990 let PrintMethod = "printCondCode"; 1991 let ParserMatchClass = CondCode; 1992} 1993def inv_ccode : Operand<i32> { 1994 // AL and NV are invalid in the aliases which use inv_ccode 1995 let PrintMethod = "printInverseCondCode"; 1996 let ParserMatchClass = CondCode; 1997 let MCOperandPredicate = [{ 1998 return MCOp.isImm() && 1999 MCOp.getImm() != AArch64CC::AL && 2000 MCOp.getImm() != AArch64CC::NV; 2001 }]; 2002} 2003 2004// Conditional branch target. 19-bit immediate. The low two bits of the target 2005// offset are implied zero and so are not part of the immediate. 2006def am_brcond : Operand<OtherVT> { 2007 let EncoderMethod = "getCondBranchTargetOpValue"; 2008 let DecoderMethod = "DecodePCRelLabel19"; 2009 let PrintMethod = "printAlignedLabel"; 2010 let ParserMatchClass = PCRelLabel19Operand; 2011 let OperandType = "OPERAND_PCREL"; 2012} 2013 2014class BranchCond<bit bit4, string mnemonic> 2015 : I<(outs), (ins ccode:$cond, am_brcond:$target), 2016 mnemonic, ".$cond\t$target", "", 2017 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 2018 let isBranch = 1; 2019 let isTerminator = 1; 2020 let Uses = [NZCV]; 2021 2022 bits<4> cond; 2023 bits<19> target; 2024 let Inst{31-24} = 0b01010100; 2025 let Inst{23-5} = target; 2026 let Inst{4} = bit4; 2027 let Inst{3-0} = cond; 2028} 2029 2030//--- 2031// Compare-and-branch instructions. 2032//--- 2033class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 2034 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 2035 asm, "\t$Rt, $target", "", 2036 [(node regtype:$Rt, bb:$target)]>, 2037 Sched<[WriteBr]> { 2038 let isBranch = 1; 2039 let isTerminator = 1; 2040 2041 bits<5> Rt; 2042 bits<19> target; 2043 let Inst{30-25} = 0b011010; 2044 let Inst{24} = op; 2045 let Inst{23-5} = target; 2046 let Inst{4-0} = Rt; 2047} 2048 2049multiclass CmpBranch<bit op, string asm, SDNode node> { 2050 def W : BaseCmpBranch<GPR32, op, asm, node> { 2051 let Inst{31} = 0; 2052 } 2053 def X : BaseCmpBranch<GPR64, op, asm, node> { 2054 let Inst{31} = 1; 2055 } 2056} 2057 2058//--- 2059// Test-bit-and-branch instructions. 2060//--- 2061// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 2062// the target offset are implied zero and so are not part of the immediate. 2063def am_tbrcond : Operand<OtherVT> { 2064 let EncoderMethod = "getTestBranchTargetOpValue"; 2065 let PrintMethod = "printAlignedLabel"; 2066 let ParserMatchClass = BranchTarget14Operand; 2067 let OperandType = "OPERAND_PCREL"; 2068} 2069 2070// AsmOperand classes to emit (or not) special diagnostics 2071def TBZImm0_31Operand : AsmOperandClass { 2072 let Name = "TBZImm0_31"; 2073 let PredicateMethod = "isImmInRange<0,31>"; 2074 let RenderMethod = "addImmOperands"; 2075} 2076def TBZImm32_63Operand : AsmOperandClass { 2077 let Name = "Imm32_63"; 2078 let PredicateMethod = "isImmInRange<32,63>"; 2079 let DiagnosticType = "InvalidImm0_63"; 2080 let RenderMethod = "addImmOperands"; 2081} 2082 2083class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 2084 return (((uint32_t)Imm) < 32); 2085}]> { 2086 let ParserMatchClass = matcher; 2087} 2088 2089def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 2090def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 2091 2092def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 2093 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 2094}]> { 2095 let ParserMatchClass = TBZImm32_63Operand; 2096} 2097 2098class BaseTestBranch<RegisterClass regtype, Operand immtype, 2099 bit op, string asm, SDNode node> 2100 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 2101 asm, "\t$Rt, $bit_off, $target", "", 2102 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 2103 Sched<[WriteBr]> { 2104 let isBranch = 1; 2105 let isTerminator = 1; 2106 2107 bits<5> Rt; 2108 bits<6> bit_off; 2109 bits<14> target; 2110 2111 let Inst{30-25} = 0b011011; 2112 let Inst{24} = op; 2113 let Inst{23-19} = bit_off{4-0}; 2114 let Inst{18-5} = target; 2115 let Inst{4-0} = Rt; 2116 2117 let DecoderMethod = "DecodeTestAndBranch"; 2118} 2119 2120multiclass TestBranch<bit op, string asm, SDNode node> { 2121 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 2122 let Inst{31} = 0; 2123 } 2124 2125 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 2126 let Inst{31} = 1; 2127 } 2128 2129 // Alias X-reg with 0-31 imm to W-Reg. 2130 def : InstAlias<asm # "\t$Rd, $imm, $target", 2131 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 2132 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 2133 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 2134 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 2135 tbz_imm0_31_diag:$imm, bb:$target)>; 2136} 2137 2138//--- 2139// Unconditional branch (immediate) instructions. 2140//--- 2141def am_b_target : Operand<OtherVT> { 2142 let EncoderMethod = "getBranchTargetOpValue"; 2143 let PrintMethod = "printAlignedLabel"; 2144 let ParserMatchClass = BranchTarget26Operand; 2145 let OperandType = "OPERAND_PCREL"; 2146} 2147def am_bl_target : Operand<i64> { 2148 let EncoderMethod = "getBranchTargetOpValue"; 2149 let PrintMethod = "printAlignedLabel"; 2150 let ParserMatchClass = BranchTarget26Operand; 2151 let OperandType = "OPERAND_PCREL"; 2152} 2153 2154class BImm<bit op, dag iops, string asm, list<dag> pattern> 2155 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 2156 bits<26> addr; 2157 let Inst{31} = op; 2158 let Inst{30-26} = 0b00101; 2159 let Inst{25-0} = addr; 2160 2161 let DecoderMethod = "DecodeUnconditionalBranch"; 2162} 2163 2164class BranchImm<bit op, string asm, list<dag> pattern> 2165 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 2166class CallImm<bit op, string asm, list<dag> pattern> 2167 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2168 2169//--- 2170// Basic one-operand data processing instructions. 2171//--- 2172 2173let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2174class BaseOneOperandData<bit sf, bit S, bits<5> opc2, bits<6> opc, 2175 RegisterClass regtype, string asm, 2176 SDPatternOperator node> 2177 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2178 [(set regtype:$Rd, (node regtype:$Rn))]>, 2179 Sched<[WriteI, ReadI]> { 2180 bits<5> Rd; 2181 bits<5> Rn; 2182 2183 let Inst{31} = sf; 2184 let Inst{30} = 0b1; 2185 let Inst{29} = S; 2186 let Inst{28-21} = 0b11010110; 2187 let Inst{20-16} = opc2; 2188 let Inst{15-10} = opc; 2189 let Inst{9-5} = Rn; 2190 let Inst{4-0} = Rd; 2191} 2192 2193let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2194multiclass OneOperandData<bits<6> opc, string asm, 2195 SDPatternOperator node = null_frag> { 2196 def Wr : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2197 2198 def Xr : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2199} 2200 2201class OneWRegData<bits<6> opc, string asm, SDPatternOperator node> 2202 : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2203 2204class OneXRegData<bits<6> opc, string asm, SDPatternOperator node> 2205 : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2206 2207class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2208 SDPatternOperator op> 2209 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2210 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2211 Sched<[WriteI, ReadI]> { 2212 bits<5> Rd; 2213 bits<5> Rn; 2214 let Inst{31-15} = 0b11011010110000010; 2215 let Inst{14-12} = opcode_prefix; 2216 let Inst{11-10} = opcode; 2217 let Inst{9-5} = Rn; 2218 let Inst{4-0} = Rd; 2219} 2220 2221class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2222 SDPatternOperator op> 2223 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2224 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2225 Sched<[]> { 2226 bits<5> Rd; 2227 let Inst{31-15} = 0b11011010110000010; 2228 let Inst{14-12} = opcode_prefix; 2229 let Inst{11-10} = opcode; 2230 let Inst{9-5} = 0b11111; 2231 let Inst{4-0} = Rd; 2232} 2233 2234class SignAuthTwoOperand<bits<4> opc, string asm, 2235 SDPatternOperator OpNode> 2236 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2237 asm, "\t$Rd, $Rn, $Rm", "", 2238 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2239 Sched<[WriteI, ReadI, ReadI]> { 2240 bits<5> Rd; 2241 bits<5> Rn; 2242 bits<5> Rm; 2243 let Inst{31-21} = 0b10011010110; 2244 let Inst{20-16} = Rm; 2245 let Inst{15-14} = 0b00; 2246 let Inst{13-10} = opc; 2247 let Inst{9-5} = Rn; 2248 let Inst{4-0} = Rd; 2249} 2250 2251class ClearAuth<bits<1> data, string asm> 2252 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2253 bits<5> Rd; 2254 let Inst{31-11} = 0b110110101100000101000; 2255 let Inst{10} = data; 2256 let Inst{9-5} = 0b11111; 2257 let Inst{4-0} = Rd; 2258} 2259 2260// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2261class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2262 : I<(outs), iops, asm, ops, "", []>, 2263 Sched<[WriteI, ReadI, ReadI]> { 2264 let Uses = [NZCV]; 2265 let Defs = [NZCV]; 2266 bits<5> Rn; 2267 let Inst{31} = sf; 2268 let Inst{30-15} = 0b0111010000000000; 2269 let Inst{14} = sz; 2270 let Inst{13-10} = 0b0010; 2271 let Inst{9-5} = Rn; 2272 let Inst{4-0} = 0b01101; 2273} 2274 2275class FlagRotate<dag iops, string asm, string ops> 2276 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2277 bits<6> imm; 2278 bits<4> mask; 2279 let Inst{20-15} = imm; 2280 let Inst{13-10} = 0b0001; 2281 let Inst{4} = 0b0; 2282 let Inst{3-0} = mask; 2283} 2284 2285//--- 2286// Basic two-operand data processing instructions. 2287//--- 2288class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2289 list<dag> pattern> 2290 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2291 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2292 Sched<[WriteI, ReadI, ReadI]> { 2293 let Uses = [NZCV]; 2294 bits<5> Rd; 2295 bits<5> Rn; 2296 bits<5> Rm; 2297 let Inst{30} = isSub; 2298 let Inst{28-21} = 0b11010000; 2299 let Inst{20-16} = Rm; 2300 let Inst{15-10} = 0; 2301 let Inst{9-5} = Rn; 2302 let Inst{4-0} = Rd; 2303} 2304 2305class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2306 SDNode OpNode> 2307 : BaseBaseAddSubCarry<isSub, regtype, asm, 2308 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2309 2310class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2311 SDNode OpNode> 2312 : BaseBaseAddSubCarry<isSub, regtype, asm, 2313 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2314 (implicit NZCV)]> { 2315 let Defs = [NZCV]; 2316} 2317 2318multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2319 SDNode OpNode, SDNode OpNode_setflags> { 2320 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2321 let Inst{31} = 0; 2322 let Inst{29} = 0; 2323 } 2324 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2325 let Inst{31} = 1; 2326 let Inst{29} = 0; 2327 } 2328 2329 // Sets flags. 2330 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2331 OpNode_setflags> { 2332 let Inst{31} = 0; 2333 let Inst{29} = 1; 2334 } 2335 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2336 OpNode_setflags> { 2337 let Inst{31} = 1; 2338 let Inst{29} = 1; 2339 } 2340} 2341 2342class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype, 2343 string asm, SDPatternOperator OpNode, 2344 RegisterClass in1regtype = regtype, 2345 RegisterClass in2regtype = regtype> 2346 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2347 asm, "\t$Rd, $Rn, $Rm", "", 2348 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2349 bits<5> Rd; 2350 bits<5> Rn; 2351 bits<5> Rm; 2352 let Inst{31} = sf; 2353 let Inst{30} = 0b0; 2354 let Inst{29} = S; 2355 let Inst{28-21} = 0b11010110; 2356 let Inst{20-16} = Rm; 2357 let Inst{15-10} = opc; 2358 let Inst{9-5} = Rn; 2359 let Inst{4-0} = Rd; 2360} 2361 2362class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm, 2363 SDPatternOperator OpNode> 2364 : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> { 2365 let Inst{10} = isSigned; 2366} 2367 2368multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2369 def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>, 2370 Sched<[WriteID32, ReadID, ReadID]>; 2371 2372 def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>, 2373 Sched<[WriteID64, ReadID, ReadID]>; 2374} 2375 2376class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm, 2377 SDPatternOperator OpNode = null_frag> 2378 : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>, 2379 Sched<[WriteIS, ReadI]> { 2380 let Inst{11-10} = shift_type; 2381} 2382 2383multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2384 def Wr : BaseShift<0b0, shift_type, GPR32, asm>; 2385 2386 def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>; 2387 2388 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2389 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2390 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2391 2392 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2393 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2394 2395 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2396 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2397 2398 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2399 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2400 2401 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2402 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2403 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2404 2405 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2406 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2407 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2408} 2409 2410class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2411 : InstAlias<asm#"\t$dst, $src1, $src2", 2412 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2413 2414class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2415 RegisterClass addtype, string asm, 2416 list<dag> pattern> 2417 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2418 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2419 bits<5> Rd; 2420 bits<5> Rn; 2421 bits<5> Rm; 2422 bits<5> Ra; 2423 let Inst{30-24} = 0b0011011; 2424 let Inst{23-21} = opc; 2425 let Inst{20-16} = Rm; 2426 let Inst{15} = isSub; 2427 let Inst{14-10} = Ra; 2428 let Inst{9-5} = Rn; 2429 let Inst{4-0} = Rd; 2430} 2431 2432multiclass MulAccum<bit isSub, string asm> { 2433 // MADD/MSUB generation is decided by MachineCombiner.cpp 2434 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2435 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2436 let Inst{31} = 0; 2437 } 2438 2439 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2440 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2441 let Inst{31} = 1; 2442 } 2443} 2444 2445class WideMulAccum<bit isSub, bits<3> opc, string asm, 2446 SDNode AccNode, SDNode ExtNode> 2447 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2448 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2449 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2450 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2451 let Inst{31} = 1; 2452} 2453 2454class MulHi<bits<3> opc, string asm, SDNode OpNode> 2455 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2456 asm, "\t$Rd, $Rn, $Rm", "", 2457 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2458 Sched<[WriteIM64, ReadIM, ReadIM]> { 2459 bits<5> Rd; 2460 bits<5> Rn; 2461 bits<5> Rm; 2462 let Inst{31-24} = 0b10011011; 2463 let Inst{23-21} = opc; 2464 let Inst{20-16} = Rm; 2465 let Inst{15} = 0; 2466 let Inst{9-5} = Rn; 2467 let Inst{4-0} = Rd; 2468 2469 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2470 // (i.e. all bits 1) but is ignored by the processor. 2471 let PostEncoderMethod = "fixMulHigh"; 2472} 2473 2474class MulAccumWAlias<string asm, Instruction inst> 2475 : InstAlias<asm#"\t$dst, $src1, $src2", 2476 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2477class MulAccumXAlias<string asm, Instruction inst> 2478 : InstAlias<asm#"\t$dst, $src1, $src2", 2479 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2480class WideMulAccumAlias<string asm, Instruction inst> 2481 : InstAlias<asm#"\t$dst, $src1, $src2", 2482 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2483 2484class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2485 SDPatternOperator OpNode, string asm> 2486 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2487 asm, "\t$Rd, $Rn, $Rm", "", 2488 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2489 Sched<[WriteISReg, ReadI, ReadISReg]> { 2490 bits<5> Rd; 2491 bits<5> Rn; 2492 bits<5> Rm; 2493 2494 let Inst{31} = sf; 2495 let Inst{30-21} = 0b0011010110; 2496 let Inst{20-16} = Rm; 2497 let Inst{15-13} = 0b010; 2498 let Inst{12} = C; 2499 let Inst{11-10} = sz; 2500 let Inst{9-5} = Rn; 2501 let Inst{4-0} = Rd; 2502 let Predicates = [HasCRC]; 2503} 2504 2505//--- 2506// Address generation. 2507//--- 2508 2509class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2510 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2511 pattern>, 2512 Sched<[WriteI]> { 2513 bits<5> Xd; 2514 bits<21> label; 2515 let Inst{31} = page; 2516 let Inst{30-29} = label{1-0}; 2517 let Inst{28-24} = 0b10000; 2518 let Inst{23-5} = label{20-2}; 2519 let Inst{4-0} = Xd; 2520 2521 let DecoderMethod = "DecodeAdrInstruction"; 2522} 2523 2524//--- 2525// Move immediate. 2526//--- 2527 2528def movimm32_imm : Operand<i32> { 2529 let ParserMatchClass = AsmImmRange<0, 65535>; 2530 let EncoderMethod = "getMoveWideImmOpValue"; 2531 let PrintMethod = "printImm"; 2532} 2533def movimm32_shift : Operand<i32> { 2534 let PrintMethod = "printShifter"; 2535 let ParserMatchClass = MovImm32ShifterOperand; 2536} 2537def movimm64_shift : Operand<i32> { 2538 let PrintMethod = "printShifter"; 2539 let ParserMatchClass = MovImm64ShifterOperand; 2540} 2541 2542let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2543class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2544 string asm> 2545 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2546 asm, "\t$Rd, $imm$shift", "", []>, 2547 Sched<[WriteImm]> { 2548 bits<5> Rd; 2549 bits<16> imm; 2550 bits<6> shift; 2551 let Inst{30-29} = opc; 2552 let Inst{28-23} = 0b100101; 2553 let Inst{22-21} = shift{5-4}; 2554 let Inst{20-5} = imm; 2555 let Inst{4-0} = Rd; 2556 2557 let DecoderMethod = "DecodeMoveImmInstruction"; 2558} 2559 2560multiclass MoveImmediate<bits<2> opc, string asm> { 2561 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2562 let Inst{31} = 0; 2563 } 2564 2565 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2566 let Inst{31} = 1; 2567 } 2568} 2569 2570let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2571class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2572 string asm> 2573 : I<(outs regtype:$Rd), 2574 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2575 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2576 Sched<[WriteI, ReadI]> { 2577 bits<5> Rd; 2578 bits<16> imm; 2579 bits<6> shift; 2580 let Inst{30-29} = opc; 2581 let Inst{28-23} = 0b100101; 2582 let Inst{22-21} = shift{5-4}; 2583 let Inst{20-5} = imm; 2584 let Inst{4-0} = Rd; 2585 2586 let DecoderMethod = "DecodeMoveImmInstruction"; 2587} 2588 2589multiclass InsertImmediate<bits<2> opc, string asm> { 2590 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2591 let Inst{31} = 0; 2592 } 2593 2594 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2595 let Inst{31} = 1; 2596 } 2597} 2598 2599//--- 2600// Add/Subtract 2601//--- 2602 2603class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2604 string asm_inst, string asm_ops, 2605 dag inputs, dag pattern> 2606 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2607 Sched<[WriteI, ReadI]> { 2608 bits<5> Rd; 2609 bits<5> Rn; 2610 let Inst{30} = isSub; 2611 let Inst{29} = setFlags; 2612 let Inst{28-24} = 0b10001; 2613 let Inst{9-5} = Rn; 2614 let Inst{4-0} = Rd; 2615} 2616 2617class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2618 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2619 string asm_inst, SDPatternOperator OpNode> 2620 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2621 (ins srcRegtype:$Rn, immtype:$imm), 2622 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2623 bits<14> imm; 2624 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2625 let Inst{21-10} = imm{11-0}; 2626 let DecoderMethod = "DecodeAddSubImmShift"; 2627} 2628 2629class BaseAddSubRegPseudo<RegisterClass regtype, 2630 SDPatternOperator OpNode> 2631 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2632 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2633 Sched<[WriteI, ReadI, ReadI]>; 2634 2635class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2636 arith_shifted_reg shifted_regtype, string asm, 2637 SDPatternOperator OpNode> 2638 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 2639 asm, "\t$Rd, $Rn, $Rm_and_shift", "", 2640 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>, 2641 Sched<[WriteISReg, ReadI, ReadISReg]> { 2642 bits<5> Rd; 2643 bits<5> Rn; 2644 bits<5> Rm; 2645 bits<8> shift; 2646 let Inst{30} = isSub; 2647 let Inst{29} = setFlags; 2648 let Inst{28-24} = 0b01011; 2649 let Inst{23-22} = shift{7-6}; 2650 let Inst{21} = 0; 2651 let Inst{20-16} = Rm; 2652 let Inst{15-10} = shift{5-0}; 2653 let Inst{9-5} = Rn; 2654 let Inst{4-0} = Rd; 2655 2656 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2657} 2658 2659class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2660 RegisterClass src1Regtype, Operand src2Regtype, 2661 string asm, SDPatternOperator OpNode> 2662 : I<(outs dstRegtype:$Rd), 2663 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend), 2664 asm, "\t$Rd, $Rn, $Rm_and_extend", "", 2665 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>, 2666 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2667 bits<5> Rd; 2668 bits<5> Rn; 2669 bits<5> Rm; 2670 bits<6> extend; 2671 let Inst{30} = isSub; 2672 let Inst{29} = setFlags; 2673 let Inst{28-24} = 0b01011; 2674 let Inst{23-21} = 0b001; 2675 let Inst{20-16} = Rm; 2676 let Inst{15-13} = extend{5-3}; 2677 let Inst{12-10} = extend{2-0}; 2678 let Inst{9-5} = Rn; 2679 let Inst{4-0} = Rd; 2680 2681 let DecoderMethod = "DecodeAddSubERegInstruction"; 2682} 2683 2684let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2685class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2686 RegisterClass src1Regtype, RegisterClass src2Regtype, 2687 Operand ext_op, string asm> 2688 : I<(outs dstRegtype:$Rd), 2689 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2690 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2691 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2692 bits<5> Rd; 2693 bits<5> Rn; 2694 bits<5> Rm; 2695 bits<6> ext; 2696 let Inst{30} = isSub; 2697 let Inst{29} = setFlags; 2698 let Inst{28-24} = 0b01011; 2699 let Inst{23-21} = 0b001; 2700 let Inst{20-16} = Rm; 2701 let Inst{15} = ext{5}; 2702 let Inst{12-10} = ext{2-0}; 2703 let Inst{9-5} = Rn; 2704 let Inst{4-0} = Rd; 2705 2706 let DecoderMethod = "DecodeAddSubERegInstruction"; 2707} 2708 2709// Aliases for register+register add/subtract. 2710class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2711 RegisterClass src1Regtype, RegisterClass src2Regtype, 2712 int shiftExt> 2713 : InstAlias<asm#"\t$dst, $src1, $src2", 2714 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2715 shiftExt)>; 2716 2717multiclass AddSub<bit isSub, string mnemonic, string alias, 2718 SDPatternOperator OpNode = null_frag> { 2719 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2720 // Add/Subtract immediate 2721 // Increase the weight of the immediate variant to try to match it before 2722 // the extended register variant. 2723 // We used to match the register variant before the immediate when the 2724 // register argument could be implicitly zero-extended. 2725 let AddedComplexity = 6 in 2726 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2727 mnemonic, OpNode> { 2728 let Inst{31} = 0; 2729 } 2730 let AddedComplexity = 6 in 2731 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2732 mnemonic, OpNode> { 2733 let Inst{31} = 1; 2734 } 2735 2736 // Add/Subtract register - Only used for CodeGen 2737 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2738 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2739 2740 // Add/Subtract shifted register 2741 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2742 OpNode> { 2743 let Inst{31} = 0; 2744 } 2745 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2746 OpNode> { 2747 let Inst{31} = 1; 2748 } 2749 } 2750 2751 // Add/Subtract extended register 2752 let AddedComplexity = 1, hasSideEffects = 0 in { 2753 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2754 arith_extended_reg32_i32, mnemonic, OpNode> { 2755 let Inst{31} = 0; 2756 } 2757 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2758 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2759 let Inst{31} = 1; 2760 } 2761 } 2762 2763 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2764 arith_extendlsl64, mnemonic> { 2765 // UXTX and SXTX only. 2766 let Inst{14-13} = 0b11; 2767 let Inst{31} = 1; 2768 } 2769 2770 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2771 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2772 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2773 addsub_shifted_imm32_neg:$imm), 0>; 2774 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2775 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2776 addsub_shifted_imm64_neg:$imm), 0>; 2777 2778 // Register/register aliases with no shift when SP is not used. 2779 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2780 GPR32, GPR32, GPR32, 0>; 2781 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2782 GPR64, GPR64, GPR64, 0>; 2783 2784 // Register/register aliases with no shift when either the destination or 2785 // first source register is SP. 2786 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2787 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2788 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2789 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2790 def : AddSubRegAlias<mnemonic, 2791 !cast<Instruction>(NAME#"Xrx64"), 2792 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2793 def : AddSubRegAlias<mnemonic, 2794 !cast<Instruction>(NAME#"Xrx64"), 2795 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2796} 2797 2798multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2799 string alias, string cmpAlias> { 2800 let isCompare = 1, Defs = [NZCV] in { 2801 // Add/Subtract immediate 2802 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2803 mnemonic, OpNode> { 2804 let Inst{31} = 0; 2805 } 2806 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2807 mnemonic, OpNode> { 2808 let Inst{31} = 1; 2809 } 2810 2811 // Add/Subtract register 2812 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2813 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2814 2815 // Add/Subtract shifted register 2816 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2817 OpNode> { 2818 let Inst{31} = 0; 2819 } 2820 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2821 OpNode> { 2822 let Inst{31} = 1; 2823 } 2824 2825 // Add/Subtract extended register 2826 let AddedComplexity = 1 in { 2827 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2828 arith_extended_reg32_i32, mnemonic, OpNode> { 2829 let Inst{31} = 0; 2830 } 2831 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2832 arith_extended_reg32_i64, mnemonic, OpNode> { 2833 let Inst{31} = 1; 2834 } 2835 } 2836 2837 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2838 arith_extendlsl64, mnemonic> { 2839 // UXTX and SXTX only. 2840 let Inst{14-13} = 0b11; 2841 let Inst{31} = 1; 2842 } 2843 } // Defs = [NZCV] 2844 2845 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2846 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2847 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2848 addsub_shifted_imm32_neg:$imm), 0>; 2849 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2850 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2851 addsub_shifted_imm64_neg:$imm), 0>; 2852 2853 // Compare aliases 2854 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2855 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2856 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2857 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2858 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2859 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2860 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2861 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2862 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2863 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2864 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2865 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2866 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2867 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2868 2869 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2870 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2871 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2872 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2873 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2874 2875 // Compare shorthands 2876 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2877 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2878 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2879 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2880 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2881 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2882 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2883 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2884 2885 // Register/register aliases with no shift when SP is not used. 2886 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2887 GPR32, GPR32, GPR32, 0>; 2888 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2889 GPR64, GPR64, GPR64, 0>; 2890 2891 // Register/register aliases with no shift when the first source register 2892 // is SP. 2893 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2894 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2895 def : AddSubRegAlias<mnemonic, 2896 !cast<Instruction>(NAME#"Xrx64"), 2897 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2898} 2899 2900class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2901 : BaseAddSubImm< 2902 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2903 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2904 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2905 bits<6> imm6; 2906 bits<4> imm4; 2907 let Inst{31} = 1; 2908 let Inst{23-22} = 0b10; 2909 let Inst{21-16} = imm6; 2910 let Inst{15-14} = 0b00; 2911 let Inst{13-10} = imm4; 2912 let Unpredictable{15-14} = 0b11; 2913} 2914 2915class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2916 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode, 2917 GPR64sp, GPR64sp>; 2918 2919//--- 2920// Extract 2921//--- 2922def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2923 SDTCisPtrTy<3>]>; 2924def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2925 2926class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2927 list<dag> patterns> 2928 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2929 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2930 Sched<[WriteExtr, ReadExtrHi]> { 2931 bits<5> Rd; 2932 bits<5> Rn; 2933 bits<5> Rm; 2934 bits<6> imm; 2935 2936 let Inst{30-23} = 0b00100111; 2937 let Inst{21} = 0; 2938 let Inst{20-16} = Rm; 2939 let Inst{15-10} = imm; 2940 let Inst{9-5} = Rn; 2941 let Inst{4-0} = Rd; 2942} 2943 2944multiclass ExtractImm<string asm> { 2945 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2946 [(set GPR32:$Rd, 2947 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2948 let Inst{31} = 0; 2949 let Inst{22} = 0; 2950 // imm<5> must be zero. 2951 let imm{5} = 0; 2952 } 2953 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2954 [(set GPR64:$Rd, 2955 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2956 2957 let Inst{31} = 1; 2958 let Inst{22} = 1; 2959 } 2960} 2961 2962//--- 2963// Bitfield 2964//--- 2965 2966let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2967class BaseBitfieldImm<bits<2> opc, 2968 RegisterClass regtype, Operand imm_type, string asm> 2969 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2970 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2971 Sched<[WriteIS, ReadI]> { 2972 bits<5> Rd; 2973 bits<5> Rn; 2974 bits<6> immr; 2975 bits<6> imms; 2976 2977 let Inst{30-29} = opc; 2978 let Inst{28-23} = 0b100110; 2979 let Inst{21-16} = immr; 2980 let Inst{15-10} = imms; 2981 let Inst{9-5} = Rn; 2982 let Inst{4-0} = Rd; 2983} 2984 2985multiclass BitfieldImm<bits<2> opc, string asm> { 2986 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2987 let Inst{31} = 0; 2988 let Inst{22} = 0; 2989 // imms<5> and immr<5> must be zero, else ReservedValue(). 2990 let Inst{21} = 0; 2991 let Inst{15} = 0; 2992 } 2993 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2994 let Inst{31} = 1; 2995 let Inst{22} = 1; 2996 } 2997} 2998 2999let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3000class BaseBitfieldImmWith2RegArgs<bits<2> opc, 3001 RegisterClass regtype, Operand imm_type, string asm> 3002 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 3003 imm_type:$imms), 3004 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 3005 Sched<[WriteIS, ReadI]> { 3006 bits<5> Rd; 3007 bits<5> Rn; 3008 bits<6> immr; 3009 bits<6> imms; 3010 3011 let Inst{30-29} = opc; 3012 let Inst{28-23} = 0b100110; 3013 let Inst{21-16} = immr; 3014 let Inst{15-10} = imms; 3015 let Inst{9-5} = Rn; 3016 let Inst{4-0} = Rd; 3017} 3018 3019multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 3020 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 3021 let Inst{31} = 0; 3022 let Inst{22} = 0; 3023 // imms<5> and immr<5> must be zero, else ReservedValue(). 3024 let Inst{21} = 0; 3025 let Inst{15} = 0; 3026 } 3027 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 3028 let Inst{31} = 1; 3029 let Inst{22} = 1; 3030 } 3031} 3032 3033//--- 3034// Logical 3035//--- 3036 3037// Logical (immediate) 3038class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 3039 RegisterClass sregtype, Operand imm_type, string asm, 3040 list<dag> pattern> 3041 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 3042 asm, "\t$Rd, $Rn, $imm", "", pattern>, 3043 Sched<[WriteI, ReadI]> { 3044 bits<5> Rd; 3045 bits<5> Rn; 3046 bits<13> imm; 3047 let Inst{30-29} = opc; 3048 let Inst{28-23} = 0b100100; 3049 let Inst{22} = imm{12}; 3050 let Inst{21-16} = imm{11-6}; 3051 let Inst{15-10} = imm{5-0}; 3052 let Inst{9-5} = Rn; 3053 let Inst{4-0} = Rd; 3054 3055 let DecoderMethod = "DecodeLogicalImmInstruction"; 3056} 3057 3058// Logical (shifted register) 3059class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 3060 logical_shifted_reg shifted_regtype, string asm, 3061 list<dag> pattern> 3062 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 3063 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>, 3064 Sched<[WriteISReg, ReadI, ReadISReg]> { 3065 bits<5> Rd; 3066 bits<5> Rn; 3067 bits<5> Rm; 3068 bits<8> shift; 3069 let Inst{30-29} = opc; 3070 let Inst{28-24} = 0b01010; 3071 let Inst{23-22} = shift{7-6}; 3072 let Inst{21} = N; 3073 let Inst{20-16} = Rm; 3074 let Inst{15-10} = shift{5-0}; 3075 let Inst{9-5} = Rn; 3076 let Inst{4-0} = Rd; 3077 3078 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 3079} 3080 3081// Aliases for register+register logical instructions. 3082class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 3083 : InstAlias<asm#"\t$dst, $src1, $src2", 3084 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 3085 3086multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 3087 string Alias> { 3088 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3089 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 3090 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 3091 logical_imm32:$imm))]> { 3092 let Inst{31} = 0; 3093 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3094 } 3095 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3096 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 3097 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 3098 logical_imm64:$imm))]> { 3099 let Inst{31} = 1; 3100 } 3101 3102 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3103 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 3104 logical_imm32_not:$imm), 0>; 3105 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3106 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 3107 logical_imm64_not:$imm), 0>; 3108} 3109 3110multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 3111 string Alias> { 3112 let isCompare = 1, Defs = [NZCV] in { 3113 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 3114 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 3115 let Inst{31} = 0; 3116 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3117 } 3118 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 3119 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 3120 let Inst{31} = 1; 3121 } 3122 } // end Defs = [NZCV] 3123 3124 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3125 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 3126 logical_imm32_not:$imm), 0>; 3127 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3128 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 3129 logical_imm64_not:$imm), 0>; 3130} 3131 3132class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 3133 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3134 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 3135 Sched<[WriteI, ReadI, ReadI]>; 3136 3137// Split from LogicalImm as not all instructions have both. 3138multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 3139 SDPatternOperator OpNode, int AddedComplexityVal = 0> { 3140 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in { 3141 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3142 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3143 } 3144 3145 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3146 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3147 logical_shifted_reg32:$Rm_and_shift))]> { 3148 let Inst{31} = 0; 3149 } 3150 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3151 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3152 logical_shifted_reg64:$Rm_and_shift))]> { 3153 let Inst{31} = 1; 3154 } 3155 3156 def : LogicalRegAlias<mnemonic, 3157 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3158 def : LogicalRegAlias<mnemonic, 3159 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3160} 3161 3162// Split from LogicalReg to allow setting NZCV Defs 3163multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3164 SDPatternOperator OpNode = null_frag> { 3165 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3166 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3167 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3168 3169 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3170 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> { 3171 let Inst{31} = 0; 3172 } 3173 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3174 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> { 3175 let Inst{31} = 1; 3176 } 3177 } // Defs = [NZCV] 3178 3179 def : LogicalRegAlias<mnemonic, 3180 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3181 def : LogicalRegAlias<mnemonic, 3182 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3183} 3184 3185//--- 3186// Conditionally set flags 3187//--- 3188 3189let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3190class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3191 string mnemonic, SDNode OpNode> 3192 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3193 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3194 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3195 (i32 imm:$cond), NZCV))]>, 3196 Sched<[WriteI, ReadI]> { 3197 let Uses = [NZCV]; 3198 let Defs = [NZCV]; 3199 3200 bits<5> Rn; 3201 bits<5> imm; 3202 bits<4> nzcv; 3203 bits<4> cond; 3204 3205 let Inst{30} = op; 3206 let Inst{29-21} = 0b111010010; 3207 let Inst{20-16} = imm; 3208 let Inst{15-12} = cond; 3209 let Inst{11-10} = 0b10; 3210 let Inst{9-5} = Rn; 3211 let Inst{4} = 0b0; 3212 let Inst{3-0} = nzcv; 3213} 3214 3215let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3216class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3217 SDNode OpNode> 3218 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3219 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3220 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3221 (i32 imm:$cond), NZCV))]>, 3222 Sched<[WriteI, ReadI, ReadI]> { 3223 let Uses = [NZCV]; 3224 let Defs = [NZCV]; 3225 3226 bits<5> Rn; 3227 bits<5> Rm; 3228 bits<4> nzcv; 3229 bits<4> cond; 3230 3231 let Inst{30} = op; 3232 let Inst{29-21} = 0b111010010; 3233 let Inst{20-16} = Rm; 3234 let Inst{15-12} = cond; 3235 let Inst{11-10} = 0b00; 3236 let Inst{9-5} = Rn; 3237 let Inst{4} = 0b0; 3238 let Inst{3-0} = nzcv; 3239} 3240 3241multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3242 // immediate operand variants 3243 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3244 let Inst{31} = 0; 3245 } 3246 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3247 let Inst{31} = 1; 3248 } 3249 // register operand variants 3250 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3251 let Inst{31} = 0; 3252 } 3253 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3254 let Inst{31} = 1; 3255 } 3256} 3257 3258//--- 3259// Conditional select 3260//--- 3261 3262class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3263 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3264 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3265 [(set regtype:$Rd, 3266 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3267 Sched<[WriteI, ReadI, ReadI]> { 3268 let Uses = [NZCV]; 3269 3270 bits<5> Rd; 3271 bits<5> Rn; 3272 bits<5> Rm; 3273 bits<4> cond; 3274 3275 let Inst{30} = op; 3276 let Inst{29-21} = 0b011010100; 3277 let Inst{20-16} = Rm; 3278 let Inst{15-12} = cond; 3279 let Inst{11-10} = op2; 3280 let Inst{9-5} = Rn; 3281 let Inst{4-0} = Rd; 3282} 3283 3284multiclass CondSelect<bit op, bits<2> op2, string asm> { 3285 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3286 let Inst{31} = 0; 3287 } 3288 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3289 let Inst{31} = 1; 3290 } 3291} 3292 3293class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3294 PatFrag frag> 3295 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3296 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3297 [(set regtype:$Rd, 3298 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3299 (i32 imm:$cond), NZCV))]>, 3300 Sched<[WriteI, ReadI, ReadI]> { 3301 let Uses = [NZCV]; 3302 3303 bits<5> Rd; 3304 bits<5> Rn; 3305 bits<5> Rm; 3306 bits<4> cond; 3307 3308 let Inst{30} = op; 3309 let Inst{29-21} = 0b011010100; 3310 let Inst{20-16} = Rm; 3311 let Inst{15-12} = cond; 3312 let Inst{11-10} = op2; 3313 let Inst{9-5} = Rn; 3314 let Inst{4-0} = Rd; 3315} 3316 3317def inv_cond_XFORM : SDNodeXForm<imm, [{ 3318 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3319 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3320 MVT::i32); 3321}]>; 3322 3323multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3324 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3325 let Inst{31} = 0; 3326 } 3327 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3328 let Inst{31} = 1; 3329 } 3330 3331 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3332 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3333 (inv_cond_XFORM imm:$cond))>; 3334 3335 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3336 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3337 (inv_cond_XFORM imm:$cond))>; 3338} 3339 3340//--- 3341// Special Mask Value 3342//--- 3343def maski8_or_more : Operand<i32>, 3344 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3345} 3346def maski16_or_more : Operand<i32>, 3347 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3348} 3349 3350 3351//--- 3352// Load/store 3353//--- 3354 3355// (unsigned immediate) 3356// Indexed for 8-bit registers. offset is in range [0,4095]. 3357def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3358def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3359def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3360def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3361def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3362 3363// (unsigned immediate) 3364// Indexed for 8-bit registers. offset is in range [0,63]. 3365def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3366def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3367def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3368def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3369 3370def gi_am_indexed8 : 3371 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3372 GIComplexPatternEquiv<am_indexed8>; 3373def gi_am_indexed16 : 3374 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3375 GIComplexPatternEquiv<am_indexed16>; 3376def gi_am_indexed32 : 3377 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3378 GIComplexPatternEquiv<am_indexed32>; 3379def gi_am_indexed64 : 3380 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3381 GIComplexPatternEquiv<am_indexed64>; 3382def gi_am_indexed128 : 3383 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3384 GIComplexPatternEquiv<am_indexed128>; 3385 3386class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3387 let Name = "UImm12Offset" # Scale; 3388 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3389 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3390 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3391} 3392 3393def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3394def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3395def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3396def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3397def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3398 3399class uimm12_scaled<int Scale> : Operand<i64> { 3400 let ParserMatchClass 3401 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3402 let EncoderMethod 3403 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3404 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3405} 3406 3407def uimm12s1 : uimm12_scaled<1>; 3408def uimm12s2 : uimm12_scaled<2>; 3409def uimm12s4 : uimm12_scaled<4>; 3410def uimm12s8 : uimm12_scaled<8>; 3411def uimm12s16 : uimm12_scaled<16>; 3412 3413class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3414 string asm, list<dag> pattern> 3415 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3416 bits<5> Rt; 3417 3418 bits<5> Rn; 3419 bits<12> offset; 3420 3421 let Inst{31-30} = sz; 3422 let Inst{29-27} = 0b111; 3423 let Inst{26} = V; 3424 let Inst{25-24} = 0b01; 3425 let Inst{23-22} = opc; 3426 let Inst{21-10} = offset; 3427 let Inst{9-5} = Rn; 3428 let Inst{4-0} = Rt; 3429 3430 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3431} 3432 3433multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3434 Operand indextype, string asm, list<dag> pattern> { 3435 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3436 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3437 (ins GPR64sp:$Rn, indextype:$offset), 3438 asm, pattern>, 3439 Sched<[WriteLD]>; 3440 3441 def : InstAlias<asm # "\t$Rt, [$Rn]", 3442 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3443} 3444 3445multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3446 Operand indextype, string asm, list<dag> pattern> { 3447 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3448 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3449 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3450 asm, pattern>, 3451 Sched<[WriteST]>; 3452 3453 def : InstAlias<asm # "\t$Rt, [$Rn]", 3454 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3455} 3456 3457// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3458// substitute zero-registers automatically. 3459// 3460// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3461// into StoreUI. 3462multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3463 Operand indextype, string asm, list<dag> pattern> { 3464 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3465 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3466 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3467 asm, pattern>, 3468 Sched<[WriteST]>; 3469 3470 def : InstAlias<asm # "\t$Rt, [$Rn]", 3471 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3472} 3473 3474def PrefetchOperand : AsmOperandClass { 3475 let Name = "Prefetch"; 3476 let ParserMethod = "tryParsePrefetch"; 3477} 3478def prfop : Operand<i32> { 3479 let PrintMethod = "printPrefetchOp"; 3480 let ParserMatchClass = PrefetchOperand; 3481} 3482 3483let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3484class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3485 : BaseLoadStoreUI<sz, V, opc, 3486 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3487 asm, pat>, 3488 Sched<[WriteLD]>; 3489 3490//--- 3491// Load literal 3492//--- 3493 3494// Load literal address: 19-bit immediate. The low two bits of the target 3495// offset are implied zero and so are not part of the immediate. 3496def am_ldrlit : Operand<iPTR> { 3497 let EncoderMethod = "getLoadLiteralOpValue"; 3498 let DecoderMethod = "DecodePCRelLabel19"; 3499 let PrintMethod = "printAlignedLabel"; 3500 let ParserMatchClass = PCRelLabel19Operand; 3501 let OperandType = "OPERAND_PCREL"; 3502} 3503 3504let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3505class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3506 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3507 asm, "\t$Rt, $label", "", pat>, 3508 Sched<[WriteLD]> { 3509 bits<5> Rt; 3510 bits<19> label; 3511 let Inst{31-30} = opc; 3512 let Inst{29-27} = 0b011; 3513 let Inst{26} = V; 3514 let Inst{25-24} = 0b00; 3515 let Inst{23-5} = label; 3516 let Inst{4-0} = Rt; 3517} 3518 3519let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3520class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3521 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3522 asm, "\t$Rt, $label", "", pat>, 3523 Sched<[WriteLD]> { 3524 bits<5> Rt; 3525 bits<19> label; 3526 let Inst{31-30} = opc; 3527 let Inst{29-27} = 0b011; 3528 let Inst{26} = V; 3529 let Inst{25-24} = 0b00; 3530 let Inst{23-5} = label; 3531 let Inst{4-0} = Rt; 3532} 3533 3534//--- 3535// Load/store register offset 3536//--- 3537 3538def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3539def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3540def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3541def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3542def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3543 3544def gi_ro_Xindexed8 : 3545 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3546 GIComplexPatternEquiv<ro_Xindexed8>; 3547def gi_ro_Xindexed16 : 3548 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3549 GIComplexPatternEquiv<ro_Xindexed16>; 3550def gi_ro_Xindexed32 : 3551 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3552 GIComplexPatternEquiv<ro_Xindexed32>; 3553def gi_ro_Xindexed64 : 3554 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3555 GIComplexPatternEquiv<ro_Xindexed64>; 3556def gi_ro_Xindexed128 : 3557 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3558 GIComplexPatternEquiv<ro_Xindexed128>; 3559 3560def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3561def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3562def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3563def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3564def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3565 3566def gi_ro_Windexed8 : 3567 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3568 GIComplexPatternEquiv<ro_Windexed8>; 3569def gi_ro_Windexed16 : 3570 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3571 GIComplexPatternEquiv<ro_Windexed16>; 3572def gi_ro_Windexed32 : 3573 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3574 GIComplexPatternEquiv<ro_Windexed32>; 3575def gi_ro_Windexed64 : 3576 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3577 GIComplexPatternEquiv<ro_Windexed64>; 3578def gi_ro_Windexed128 : 3579 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3580 GIComplexPatternEquiv<ro_Windexed128>; 3581 3582class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3583 let Name = "Mem" # Reg # "Extend" # Width; 3584 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3585 let RenderMethod = "addMemExtendOperands"; 3586 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3587} 3588 3589def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3590 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3591 // the trivial shift. 3592 let RenderMethod = "addMemExtend8Operands"; 3593} 3594def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3595def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3596def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3597def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3598 3599def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3600 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3601 // the trivial shift. 3602 let RenderMethod = "addMemExtend8Operands"; 3603} 3604def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3605def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3606def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3607def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3608 3609class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3610 : Operand<i32> { 3611 let ParserMatchClass = ParserClass; 3612 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3613 let DecoderMethod = "DecodeMemExtend"; 3614 let EncoderMethod = "getMemExtendOpValue"; 3615 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3616} 3617 3618def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3619def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3620def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3621def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3622def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3623 3624def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3625def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3626def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3627def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3628def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3629 3630class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3631 Operand wextend, Operand xextend> { 3632 // CodeGen-level pattern covering the entire addressing mode. 3633 ComplexPattern Wpat = windex; 3634 ComplexPattern Xpat = xindex; 3635 3636 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3637 Operand Wext = wextend; 3638 Operand Xext = xextend; 3639} 3640 3641def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3642def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3643def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3644def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3645def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3646 ro_Xextend128>; 3647 3648class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3649 dag outs, list<dag> pat> 3650 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3651 bits<5> Rt; 3652 bits<5> Rn; 3653 bits<5> Rm; 3654 bits<2> extend; 3655 let Inst{31-30} = sz; 3656 let Inst{29-27} = 0b111; 3657 let Inst{26} = V; 3658 let Inst{25-24} = 0b00; 3659 let Inst{23-22} = opc; 3660 let Inst{21} = 1; 3661 let Inst{20-16} = Rm; 3662 let Inst{15} = extend{1}; // sign extend Rm? 3663 let Inst{14} = 1; 3664 let Inst{12} = extend{0}; // do shift? 3665 let Inst{11-10} = 0b10; 3666 let Inst{9-5} = Rn; 3667 let Inst{4-0} = Rt; 3668} 3669 3670class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3671 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3672 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3673 3674multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3675 string asm, ValueType Ty, SDPatternOperator loadop> { 3676 let AddedComplexity = 10 in 3677 def roW : LoadStore8RO<sz, V, opc, asm, 3678 (outs regtype:$Rt), 3679 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3680 [(set (Ty regtype:$Rt), 3681 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3682 ro_Wextend8:$extend)))]>, 3683 Sched<[WriteLDIdx, ReadAdrBase]> { 3684 let Inst{13} = 0b0; 3685 } 3686 3687 let AddedComplexity = 10 in 3688 def roX : LoadStore8RO<sz, V, opc, asm, 3689 (outs regtype:$Rt), 3690 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3691 [(set (Ty regtype:$Rt), 3692 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3693 ro_Xextend8:$extend)))]>, 3694 Sched<[WriteLDIdx, ReadAdrBase]> { 3695 let Inst{13} = 0b1; 3696 } 3697 3698 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3699} 3700 3701multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3702 string asm, ValueType Ty, SDPatternOperator storeop> { 3703 let AddedComplexity = 10 in 3704 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3705 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3706 [(storeop (Ty regtype:$Rt), 3707 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3708 ro_Wextend8:$extend))]>, 3709 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3710 let Inst{13} = 0b0; 3711 } 3712 3713 let AddedComplexity = 10 in 3714 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3715 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3716 [(storeop (Ty regtype:$Rt), 3717 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3718 ro_Xextend8:$extend))]>, 3719 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3720 let Inst{13} = 0b1; 3721 } 3722 3723 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3724} 3725 3726class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3727 dag outs, list<dag> pat> 3728 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3729 bits<5> Rt; 3730 bits<5> Rn; 3731 bits<5> Rm; 3732 bits<2> extend; 3733 let Inst{31-30} = sz; 3734 let Inst{29-27} = 0b111; 3735 let Inst{26} = V; 3736 let Inst{25-24} = 0b00; 3737 let Inst{23-22} = opc; 3738 let Inst{21} = 1; 3739 let Inst{20-16} = Rm; 3740 let Inst{15} = extend{1}; // sign extend Rm? 3741 let Inst{14} = 1; 3742 let Inst{12} = extend{0}; // do shift? 3743 let Inst{11-10} = 0b10; 3744 let Inst{9-5} = Rn; 3745 let Inst{4-0} = Rt; 3746} 3747 3748multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3749 string asm, ValueType Ty, SDPatternOperator loadop> { 3750 let AddedComplexity = 10 in 3751 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3752 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3753 [(set (Ty regtype:$Rt), 3754 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3755 ro_Wextend16:$extend)))]>, 3756 Sched<[WriteLDIdx, ReadAdrBase]> { 3757 let Inst{13} = 0b0; 3758 } 3759 3760 let AddedComplexity = 10 in 3761 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3762 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3763 [(set (Ty regtype:$Rt), 3764 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3765 ro_Xextend16:$extend)))]>, 3766 Sched<[WriteLDIdx, ReadAdrBase]> { 3767 let Inst{13} = 0b1; 3768 } 3769 3770 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3771} 3772 3773multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3774 string asm, ValueType Ty, SDPatternOperator storeop> { 3775 let AddedComplexity = 10 in 3776 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3777 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3778 [(storeop (Ty regtype:$Rt), 3779 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3780 ro_Wextend16:$extend))]>, 3781 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3782 let Inst{13} = 0b0; 3783 } 3784 3785 let AddedComplexity = 10 in 3786 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3787 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3788 [(storeop (Ty regtype:$Rt), 3789 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3790 ro_Xextend16:$extend))]>, 3791 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3792 let Inst{13} = 0b1; 3793 } 3794 3795 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3796} 3797 3798class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3799 dag outs, list<dag> pat> 3800 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3801 bits<5> Rt; 3802 bits<5> Rn; 3803 bits<5> Rm; 3804 bits<2> extend; 3805 let Inst{31-30} = sz; 3806 let Inst{29-27} = 0b111; 3807 let Inst{26} = V; 3808 let Inst{25-24} = 0b00; 3809 let Inst{23-22} = opc; 3810 let Inst{21} = 1; 3811 let Inst{20-16} = Rm; 3812 let Inst{15} = extend{1}; // sign extend Rm? 3813 let Inst{14} = 1; 3814 let Inst{12} = extend{0}; // do shift? 3815 let Inst{11-10} = 0b10; 3816 let Inst{9-5} = Rn; 3817 let Inst{4-0} = Rt; 3818} 3819 3820multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3821 string asm, ValueType Ty, SDPatternOperator loadop> { 3822 let AddedComplexity = 10 in 3823 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3824 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3825 [(set (Ty regtype:$Rt), 3826 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3827 ro_Wextend32:$extend)))]>, 3828 Sched<[WriteLDIdx, ReadAdrBase]> { 3829 let Inst{13} = 0b0; 3830 } 3831 3832 let AddedComplexity = 10 in 3833 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3834 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3835 [(set (Ty regtype:$Rt), 3836 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3837 ro_Xextend32:$extend)))]>, 3838 Sched<[WriteLDIdx, ReadAdrBase]> { 3839 let Inst{13} = 0b1; 3840 } 3841 3842 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3843} 3844 3845multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3846 string asm, ValueType Ty, SDPatternOperator storeop> { 3847 let AddedComplexity = 10 in 3848 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3849 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3850 [(storeop (Ty regtype:$Rt), 3851 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3852 ro_Wextend32:$extend))]>, 3853 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3854 let Inst{13} = 0b0; 3855 } 3856 3857 let AddedComplexity = 10 in 3858 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3859 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3860 [(storeop (Ty regtype:$Rt), 3861 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3862 ro_Xextend32:$extend))]>, 3863 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3864 let Inst{13} = 0b1; 3865 } 3866 3867 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3868} 3869 3870class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3871 dag outs, list<dag> pat> 3872 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3873 bits<5> Rt; 3874 bits<5> Rn; 3875 bits<5> Rm; 3876 bits<2> extend; 3877 let Inst{31-30} = sz; 3878 let Inst{29-27} = 0b111; 3879 let Inst{26} = V; 3880 let Inst{25-24} = 0b00; 3881 let Inst{23-22} = opc; 3882 let Inst{21} = 1; 3883 let Inst{20-16} = Rm; 3884 let Inst{15} = extend{1}; // sign extend Rm? 3885 let Inst{14} = 1; 3886 let Inst{12} = extend{0}; // do shift? 3887 let Inst{11-10} = 0b10; 3888 let Inst{9-5} = Rn; 3889 let Inst{4-0} = Rt; 3890} 3891 3892multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3893 string asm, ValueType Ty, SDPatternOperator loadop> { 3894 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3895 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3896 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3897 [(set (Ty regtype:$Rt), 3898 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3899 ro_Wextend64:$extend)))]>, 3900 Sched<[WriteLDIdx, ReadAdrBase]> { 3901 let Inst{13} = 0b0; 3902 } 3903 3904 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3905 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3906 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3907 [(set (Ty regtype:$Rt), 3908 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3909 ro_Xextend64:$extend)))]>, 3910 Sched<[WriteLDIdx, ReadAdrBase]> { 3911 let Inst{13} = 0b1; 3912 } 3913 3914 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3915} 3916 3917multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3918 string asm, ValueType Ty, SDPatternOperator storeop> { 3919 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3920 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 3921 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3922 [(storeop (Ty regtype:$Rt), 3923 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3924 ro_Wextend64:$extend))]>, 3925 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3926 let Inst{13} = 0b0; 3927 } 3928 3929 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3930 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 3931 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3932 [(storeop (Ty regtype:$Rt), 3933 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3934 ro_Xextend64:$extend))]>, 3935 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3936 let Inst{13} = 0b1; 3937 } 3938 3939 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3940} 3941 3942class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3943 dag outs, list<dag> pat> 3944 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3945 bits<5> Rt; 3946 bits<5> Rn; 3947 bits<5> Rm; 3948 bits<2> extend; 3949 let Inst{31-30} = sz; 3950 let Inst{29-27} = 0b111; 3951 let Inst{26} = V; 3952 let Inst{25-24} = 0b00; 3953 let Inst{23-22} = opc; 3954 let Inst{21} = 1; 3955 let Inst{20-16} = Rm; 3956 let Inst{15} = extend{1}; // sign extend Rm? 3957 let Inst{14} = 1; 3958 let Inst{12} = extend{0}; // do shift? 3959 let Inst{11-10} = 0b10; 3960 let Inst{9-5} = Rn; 3961 let Inst{4-0} = Rt; 3962} 3963 3964multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3965 string asm, ValueType Ty, SDPatternOperator loadop> { 3966 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3967 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3968 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3969 [(set (Ty regtype:$Rt), 3970 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3971 ro_Wextend128:$extend)))]>, 3972 Sched<[WriteLDIdx, ReadAdrBase]> { 3973 let Inst{13} = 0b0; 3974 } 3975 3976 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3977 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 3978 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3979 [(set (Ty regtype:$Rt), 3980 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3981 ro_Xextend128:$extend)))]>, 3982 Sched<[WriteLDIdx, ReadAdrBase]> { 3983 let Inst{13} = 0b1; 3984 } 3985 3986 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3987} 3988 3989multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3990 string asm> { 3991 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3992 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 3993 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3994 []>, 3995 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3996 let Inst{13} = 0b0; 3997 } 3998 3999 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4000 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 4001 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4002 []>, 4003 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4004 let Inst{13} = 0b1; 4005 } 4006 4007 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4008} 4009 4010let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4011class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 4012 string asm, list<dag> pat> 4013 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 4014 Sched<[WriteLD]> { 4015 bits<5> Rt; 4016 bits<5> Rn; 4017 bits<5> Rm; 4018 bits<2> extend; 4019 let Inst{31-30} = sz; 4020 let Inst{29-27} = 0b111; 4021 let Inst{26} = V; 4022 let Inst{25-24} = 0b00; 4023 let Inst{23-22} = opc; 4024 let Inst{21} = 1; 4025 let Inst{20-16} = Rm; 4026 let Inst{15} = extend{1}; // sign extend Rm? 4027 let Inst{14} = 1; 4028 let Inst{12} = extend{0}; // do shift? 4029 let Inst{11-10} = 0b10; 4030 let Inst{9-5} = Rn; 4031 let Inst{4-0} = Rt; 4032 let DecoderMethod = "DecodePRFMRegInstruction"; 4033 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When 4034 // the decoder method returns Fail, the decoder should attempt to decode the 4035 // instruction as RPRFM. 4036 let hasCompleteDecoder = 0; 4037} 4038 4039multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 4040 def roW : BasePrefetchRO<sz, V, opc, (outs), 4041 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4042 asm, [(AArch64Prefetch timm:$Rt, 4043 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4044 ro_Wextend64:$extend))]> { 4045 let Inst{13} = 0b0; 4046 } 4047 4048 def roX : BasePrefetchRO<sz, V, opc, (outs), 4049 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4050 asm, [(AArch64Prefetch timm:$Rt, 4051 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4052 ro_Xextend64:$extend))]> { 4053 let Inst{13} = 0b1; 4054 } 4055 4056 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 4057 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 4058 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 4059} 4060 4061//--- 4062// Load/store unscaled immediate 4063//--- 4064 4065def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 4066def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 4067def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 4068def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 4069def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 4070 4071def gi_am_unscaled8 : 4072 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 4073 GIComplexPatternEquiv<am_unscaled8>; 4074def gi_am_unscaled16 : 4075 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 4076 GIComplexPatternEquiv<am_unscaled16>; 4077def gi_am_unscaled32 : 4078 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 4079 GIComplexPatternEquiv<am_unscaled32>; 4080def gi_am_unscaled64 : 4081 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 4082 GIComplexPatternEquiv<am_unscaled64>; 4083def gi_am_unscaled128 : 4084 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 4085 GIComplexPatternEquiv<am_unscaled128>; 4086 4087 4088class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4089 string asm, list<dag> pattern> 4090 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 4091 bits<5> Rt; 4092 bits<5> Rn; 4093 bits<9> offset; 4094 let Inst{31-30} = sz; 4095 let Inst{29-27} = 0b111; 4096 let Inst{26} = V; 4097 let Inst{25-24} = 0b00; 4098 let Inst{23-22} = opc; 4099 let Inst{21} = 0; 4100 let Inst{20-12} = offset; 4101 let Inst{11-10} = 0b00; 4102 let Inst{9-5} = Rn; 4103 let Inst{4-0} = Rt; 4104 4105 let DecoderMethod = "DecodeSignedLdStInstruction"; 4106} 4107 4108// Armv8.4 LDAPR & STLR with Immediate Offset instruction 4109multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4110 DAGOperand regtype > { 4111 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 4112 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 4113 Sched<[WriteST]> { 4114 let Inst{29} = 0; 4115 let Inst{24} = 1; 4116 } 4117 def : InstAlias<asm # "\t$Rt, [$Rn]", 4118 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4119} 4120 4121multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4122 DAGOperand regtype > { 4123 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 4124 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4125 asm, []>, 4126 Sched<[WriteST]> { 4127 let Inst{29} = 0; 4128 let Inst{24} = 1; 4129 } 4130 def : InstAlias<asm # "\t$Rt, [$Rn]", 4131 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4132} 4133 4134multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4135 string asm, list<dag> pattern> { 4136 let AddedComplexity = 1 in // try this before LoadUI 4137 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 4138 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 4139 Sched<[WriteLD]>; 4140 4141 def : InstAlias<asm # "\t$Rt, [$Rn]", 4142 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4143} 4144 4145multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4146 string asm, list<dag> pattern> { 4147 let AddedComplexity = 1 in // try this before StoreUI 4148 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4149 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4150 asm, pattern>, 4151 Sched<[WriteST]>; 4152 4153 def : InstAlias<asm # "\t$Rt, [$Rn]", 4154 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4155} 4156 4157multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4158 list<dag> pat> { 4159 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4160 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4161 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4162 asm, pat>, 4163 Sched<[WriteLD]>; 4164 4165 def : InstAlias<asm # "\t$Rt, [$Rn]", 4166 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4167} 4168 4169//--- 4170// Load/store unscaled immediate, unprivileged 4171//--- 4172 4173class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4174 dag oops, dag iops, string asm> 4175 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4176 bits<5> Rt; 4177 bits<5> Rn; 4178 bits<9> offset; 4179 let Inst{31-30} = sz; 4180 let Inst{29-27} = 0b111; 4181 let Inst{26} = V; 4182 let Inst{25-24} = 0b00; 4183 let Inst{23-22} = opc; 4184 let Inst{21} = 0; 4185 let Inst{20-12} = offset; 4186 let Inst{11-10} = 0b10; 4187 let Inst{9-5} = Rn; 4188 let Inst{4-0} = Rt; 4189 4190 let DecoderMethod = "DecodeSignedLdStInstruction"; 4191} 4192 4193multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4194 RegisterClass regtype, string asm> { 4195 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4196 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4197 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4198 Sched<[WriteLD]>; 4199 4200 def : InstAlias<asm # "\t$Rt, [$Rn]", 4201 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4202} 4203 4204multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4205 RegisterClass regtype, string asm> { 4206 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4207 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4208 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4209 asm>, 4210 Sched<[WriteST]>; 4211 4212 def : InstAlias<asm # "\t$Rt, [$Rn]", 4213 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4214} 4215 4216//--- 4217// Load/store pre-indexed 4218//--- 4219 4220class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4221 string asm, string cstr, list<dag> pat> 4222 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4223 bits<5> Rt; 4224 bits<5> Rn; 4225 bits<9> offset; 4226 let Inst{31-30} = sz; 4227 let Inst{29-27} = 0b111; 4228 let Inst{26} = V; 4229 let Inst{25-24} = 0; 4230 let Inst{23-22} = opc; 4231 let Inst{21} = 0; 4232 let Inst{20-12} = offset; 4233 let Inst{11-10} = 0b11; 4234 let Inst{9-5} = Rn; 4235 let Inst{4-0} = Rt; 4236 4237 let DecoderMethod = "DecodeSignedLdStInstruction"; 4238} 4239 4240let hasSideEffects = 0 in { 4241let mayStore = 0, mayLoad = 1 in 4242class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4243 string asm> 4244 : BaseLoadStorePreIdx<sz, V, opc, 4245 (outs GPR64sp:$wback, regtype:$Rt), 4246 (ins GPR64sp:$Rn, simm9:$offset), asm, 4247 "$Rn = $wback,@earlyclobber $wback", []>, 4248 Sched<[WriteAdr, WriteLD]>; 4249 4250let mayStore = 1, mayLoad = 0 in 4251class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4252 string asm, SDPatternOperator storeop, ValueType Ty> 4253 : BaseLoadStorePreIdx<sz, V, opc, 4254 (outs GPR64sp:$wback), 4255 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4256 asm, "$Rn = $wback,@earlyclobber $wback", 4257 [(set GPR64sp:$wback, 4258 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4259 Sched<[WriteAdr, WriteST]>; 4260} // hasSideEffects = 0 4261 4262//--- 4263// Load/store post-indexed 4264//--- 4265 4266class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4267 string asm, string cstr, list<dag> pat> 4268 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4269 bits<5> Rt; 4270 bits<5> Rn; 4271 bits<9> offset; 4272 let Inst{31-30} = sz; 4273 let Inst{29-27} = 0b111; 4274 let Inst{26} = V; 4275 let Inst{25-24} = 0b00; 4276 let Inst{23-22} = opc; 4277 let Inst{21} = 0b0; 4278 let Inst{20-12} = offset; 4279 let Inst{11-10} = 0b01; 4280 let Inst{9-5} = Rn; 4281 let Inst{4-0} = Rt; 4282 4283 let DecoderMethod = "DecodeSignedLdStInstruction"; 4284} 4285 4286let hasSideEffects = 0 in { 4287let mayStore = 0, mayLoad = 1 in 4288class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4289 string asm> 4290 : BaseLoadStorePostIdx<sz, V, opc, 4291 (outs GPR64sp:$wback, regtype:$Rt), 4292 (ins GPR64sp:$Rn, simm9:$offset), 4293 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4294 Sched<[WriteAdr, WriteLD]>; 4295 4296let mayStore = 1, mayLoad = 0 in 4297class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4298 string asm, SDPatternOperator storeop, ValueType Ty> 4299 : BaseLoadStorePostIdx<sz, V, opc, 4300 (outs GPR64sp:$wback), 4301 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4302 asm, "$Rn = $wback,@earlyclobber $wback", 4303 [(set GPR64sp:$wback, 4304 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4305 Sched<[WriteAdr, WriteST]>; 4306} // hasSideEffects = 0 4307 4308 4309//--- 4310// Load/store pair 4311//--- 4312 4313// (indexed, offset) 4314 4315class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4316 string asm> 4317 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4318 bits<5> Rt; 4319 bits<5> Rt2; 4320 bits<5> Rn; 4321 bits<7> offset; 4322 let Inst{31-30} = opc; 4323 let Inst{29-27} = 0b101; 4324 let Inst{26} = V; 4325 let Inst{25-23} = 0b010; 4326 let Inst{22} = L; 4327 let Inst{21-15} = offset; 4328 let Inst{14-10} = Rt2; 4329 let Inst{9-5} = Rn; 4330 let Inst{4-0} = Rt; 4331 4332 let DecoderMethod = "DecodePairLdStInstruction"; 4333} 4334 4335multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4336 Operand indextype, string asm> { 4337 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4338 def i : BaseLoadStorePairOffset<opc, V, 1, 4339 (outs regtype:$Rt, regtype:$Rt2), 4340 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4341 Sched<[WriteLD, WriteLDHi]>; 4342 4343 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4344 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4345 GPR64sp:$Rn, 0)>; 4346} 4347 4348 4349multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4350 Operand indextype, string asm> { 4351 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4352 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4353 (ins regtype:$Rt, regtype:$Rt2, 4354 GPR64sp:$Rn, indextype:$offset), 4355 asm>, 4356 Sched<[WriteSTP]>; 4357 4358 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4359 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4360 GPR64sp:$Rn, 0)>; 4361} 4362 4363// (pre-indexed) 4364class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4365 string asm> 4366 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4367 bits<5> Rt; 4368 bits<5> Rt2; 4369 bits<5> Rn; 4370 bits<7> offset; 4371 let Inst{31-30} = opc; 4372 let Inst{29-27} = 0b101; 4373 let Inst{26} = V; 4374 let Inst{25-23} = 0b011; 4375 let Inst{22} = L; 4376 let Inst{21-15} = offset; 4377 let Inst{14-10} = Rt2; 4378 let Inst{9-5} = Rn; 4379 let Inst{4-0} = Rt; 4380 4381 let DecoderMethod = "DecodePairLdStInstruction"; 4382} 4383 4384let hasSideEffects = 0 in { 4385let mayStore = 0, mayLoad = 1 in 4386class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4387 Operand indextype, string asm> 4388 : BaseLoadStorePairPreIdx<opc, V, 1, 4389 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4390 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4391 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4392 4393let mayStore = 1, mayLoad = 0 in 4394class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4395 Operand indextype, string asm> 4396 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4397 (ins regtype:$Rt, regtype:$Rt2, 4398 GPR64sp:$Rn, indextype:$offset), 4399 asm>, 4400 Sched<[WriteAdr, WriteSTP]>; 4401} // hasSideEffects = 0 4402 4403// (post-indexed) 4404 4405class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4406 string asm> 4407 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4408 bits<5> Rt; 4409 bits<5> Rt2; 4410 bits<5> Rn; 4411 bits<7> offset; 4412 let Inst{31-30} = opc; 4413 let Inst{29-27} = 0b101; 4414 let Inst{26} = V; 4415 let Inst{25-23} = 0b001; 4416 let Inst{22} = L; 4417 let Inst{21-15} = offset; 4418 let Inst{14-10} = Rt2; 4419 let Inst{9-5} = Rn; 4420 let Inst{4-0} = Rt; 4421 4422 let DecoderMethod = "DecodePairLdStInstruction"; 4423} 4424 4425let hasSideEffects = 0 in { 4426let mayStore = 0, mayLoad = 1 in 4427class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4428 Operand idxtype, string asm> 4429 : BaseLoadStorePairPostIdx<opc, V, 1, 4430 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4431 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4432 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4433 4434let mayStore = 1, mayLoad = 0 in 4435class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4436 Operand idxtype, string asm> 4437 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4438 (ins regtype:$Rt, regtype:$Rt2, 4439 GPR64sp:$Rn, idxtype:$offset), 4440 asm>, 4441 Sched<[WriteAdr, WriteSTP]>; 4442} // hasSideEffects = 0 4443 4444// (no-allocate) 4445 4446class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4447 string asm> 4448 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4449 bits<5> Rt; 4450 bits<5> Rt2; 4451 bits<5> Rn; 4452 bits<7> offset; 4453 let Inst{31-30} = opc; 4454 let Inst{29-27} = 0b101; 4455 let Inst{26} = V; 4456 let Inst{25-23} = 0b000; 4457 let Inst{22} = L; 4458 let Inst{21-15} = offset; 4459 let Inst{14-10} = Rt2; 4460 let Inst{9-5} = Rn; 4461 let Inst{4-0} = Rt; 4462 4463 let DecoderMethod = "DecodePairLdStInstruction"; 4464} 4465 4466multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4467 Operand indextype, string asm> { 4468 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4469 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4470 (outs regtype:$Rt, regtype:$Rt2), 4471 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4472 Sched<[WriteLD, WriteLDHi]>; 4473 4474 4475 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4476 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4477 GPR64sp:$Rn, 0)>; 4478} 4479 4480multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4481 Operand indextype, string asm> { 4482 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4483 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4484 (ins regtype:$Rt, regtype:$Rt2, 4485 GPR64sp:$Rn, indextype:$offset), 4486 asm>, 4487 Sched<[WriteSTP]>; 4488 4489 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4490 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4491 GPR64sp:$Rn, 0)>; 4492} 4493 4494//--- 4495// Load/store exclusive 4496//--- 4497 4498// True exclusive operations write to and/or read from the system's exclusive 4499// monitors, which as far as a compiler is concerned can be modelled as a 4500// random shared memory address. Hence LoadExclusive mayStore. 4501// 4502// Since these instructions have the undefined register bits set to 1 in 4503// their canonical form, we need a post encoder method to set those bits 4504// to 1 when encoding these instructions. We do this using the 4505// fixLoadStoreExclusive function. This function has template parameters: 4506// 4507// fixLoadStoreExclusive<int hasRs, int hasRt2> 4508// 4509// hasRs indicates that the instruction uses the Rs field, so we won't set 4510// it to 1 (and the same for Rt2). We don't need template parameters for 4511// the other register fields since Rt and Rn are always used. 4512// 4513let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4514class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4515 dag oops, dag iops, string asm, string operands> 4516 : I<oops, iops, asm, operands, "", []> { 4517 let Inst{31-30} = sz; 4518 let Inst{29-24} = 0b001000; 4519 let Inst{23} = o2; 4520 let Inst{22} = L; 4521 let Inst{21} = o1; 4522 let Inst{15} = o0; 4523 4524 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4525} 4526 4527// Neither Rs nor Rt2 operands. 4528class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4529 dag oops, dag iops, string asm, string operands> 4530 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4531 bits<5> Rt; 4532 bits<5> Rn; 4533 let Inst{20-16} = 0b11111; 4534 let Unpredictable{20-16} = 0b11111; 4535 let Inst{14-10} = 0b11111; 4536 let Unpredictable{14-10} = 0b11111; 4537 let Inst{9-5} = Rn; 4538 let Inst{4-0} = Rt; 4539 4540 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4541} 4542 4543// Simple load acquires don't set the exclusive monitor 4544let mayLoad = 1, mayStore = 0 in 4545class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4546 RegisterClass regtype, string asm> 4547 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4548 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4549 Sched<[WriteLD]>; 4550 4551class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4552 RegisterClass regtype, string asm> 4553 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4554 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4555 Sched<[WriteLD]>; 4556 4557class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4558 RegisterClass regtype, string asm> 4559 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4560 (outs regtype:$Rt, regtype:$Rt2), 4561 (ins GPR64sp0:$Rn), asm, 4562 "\t$Rt, $Rt2, [$Rn]">, 4563 Sched<[WriteLD, WriteLDHi]> { 4564 bits<5> Rt; 4565 bits<5> Rt2; 4566 bits<5> Rn; 4567 let Inst{14-10} = Rt2; 4568 let Inst{9-5} = Rn; 4569 let Inst{4-0} = Rt; 4570 4571 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4572} 4573 4574// Simple store release operations do not check the exclusive monitor. 4575let mayLoad = 0, mayStore = 1 in 4576class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4577 RegisterClass regtype, string asm> 4578 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4579 (ins regtype:$Rt, GPR64sp:$Rn), 4580 asm, "\t$Rt, [$Rn]">, 4581 Sched<[WriteST]>; 4582 4583let mayLoad = 1, mayStore = 1 in 4584class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4585 RegisterClass regtype, string asm> 4586 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4587 (ins regtype:$Rt, GPR64sp0:$Rn), 4588 asm, "\t$Ws, $Rt, [$Rn]">, 4589 Sched<[WriteSTX]> { 4590 bits<5> Ws; 4591 bits<5> Rt; 4592 bits<5> Rn; 4593 let Inst{20-16} = Ws; 4594 let Inst{9-5} = Rn; 4595 let Inst{4-0} = Rt; 4596 4597 let Constraints = "@earlyclobber $Ws"; 4598 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4599} 4600 4601class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4602 RegisterClass regtype, string asm> 4603 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4604 (outs GPR32:$Ws), 4605 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4606 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4607 Sched<[WriteSTX]> { 4608 bits<5> Ws; 4609 bits<5> Rt; 4610 bits<5> Rt2; 4611 bits<5> Rn; 4612 let Inst{20-16} = Ws; 4613 let Inst{14-10} = Rt2; 4614 let Inst{9-5} = Rn; 4615 let Inst{4-0} = Rt; 4616 4617 let Constraints = "@earlyclobber $Ws"; 4618} 4619 4620// Armv8.5-A Memory Tagging Extension 4621class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4622 string asm_opnds, string cstr, dag oops, dag iops> 4623 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4624 Sched<[]> { 4625 bits<5> Rn; 4626 4627 let Inst{31-24} = 0b11011001; 4628 let Inst{23-22} = opc1; 4629 let Inst{21} = 1; 4630 // Inst{20-12} defined by subclass 4631 let Inst{11-10} = opc2; 4632 let Inst{9-5} = Rn; 4633 // Inst{4-0} defined by subclass 4634} 4635 4636class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4637 dag oops, dag iops> 4638 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4639 "", oops, iops> { 4640 bits<5> Rt; 4641 4642 let Inst{20-12} = 0b000000000; 4643 let Inst{4-0} = Rt; 4644 4645 let mayLoad = Load; 4646} 4647 4648class MemTagLoad<string asm_insn, string asm_opnds> 4649 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4650 (outs GPR64:$wback), 4651 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4652 bits<5> Rt; 4653 bits<9> offset; 4654 4655 let Inst{20-12} = offset; 4656 let Inst{4-0} = Rt; 4657 4658 let mayLoad = 1; 4659} 4660 4661class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4662 string asm_opnds, string cstr, dag oops, dag iops> 4663 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4664 bits<5> Rt; 4665 bits<9> offset; 4666 4667 let Inst{20-12} = offset; 4668 let Inst{4-0} = Rt; 4669 4670 let mayStore = 1; 4671} 4672 4673multiclass MemTagStore<bits<2> opc1, string insn> { 4674 def Offset : 4675 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4676 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4677 def PreIndex : 4678 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4679 "$Rn = $wback", 4680 (outs GPR64sp:$wback), 4681 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4682 def PostIndex : 4683 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4684 "$Rn = $wback", 4685 (outs GPR64sp:$wback), 4686 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4687 4688 def : InstAlias<insn # "\t$Rt, [$Rn]", 4689 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4690} 4691 4692//--- 4693// Exception generation 4694//--- 4695 4696let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4697class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4698 list<dag> pattern = []> 4699 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4700 Sched<[WriteSys]> { 4701 bits<16> imm; 4702 let Inst{31-24} = 0b11010100; 4703 let Inst{23-21} = op1; 4704 let Inst{20-5} = imm; 4705 let Inst{4-2} = 0b000; 4706 let Inst{1-0} = ll; 4707} 4708 4709//--- 4710// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4711//-- 4712let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4713class UDFType<bits<16> opc, string asm> 4714 : I<(outs), (ins uimm16:$imm), 4715 asm, "\t$imm", "", []>, 4716 Sched<[]> { 4717 bits<16> imm; 4718 let Inst{31-16} = opc; 4719 let Inst{15-0} = imm; 4720} 4721} 4722let Predicates = [HasFPARMv8] in { 4723 4724//--- 4725// Floating point to integer conversion 4726//--- 4727 4728let mayRaiseFPException = 1, Uses = [FPCR] in 4729class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4730 RegisterClass srcType, RegisterClass dstType, 4731 string asm, list<dag> pattern> 4732 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4733 asm, "\t$Rd, $Rn", "", pattern>, 4734 Sched<[WriteFCvt]> { 4735 bits<5> Rd; 4736 bits<5> Rn; 4737 let Inst{30-29} = 0b00; 4738 let Inst{28-24} = 0b11110; 4739 let Inst{23-22} = type; 4740 let Inst{21} = 1; 4741 let Inst{20-19} = rmode; 4742 let Inst{18-16} = opcode; 4743 let Inst{15-10} = 0; 4744 let Inst{9-5} = Rn; 4745 let Inst{4-0} = Rd; 4746} 4747 4748let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4749class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4750 RegisterClass srcType, RegisterClass dstType, 4751 Operand immType, string asm, list<dag> pattern> 4752 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4753 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4754 Sched<[WriteFCvt]> { 4755 bits<5> Rd; 4756 bits<5> Rn; 4757 bits<6> scale; 4758 let Inst{30-29} = 0b00; 4759 let Inst{28-24} = 0b11110; 4760 let Inst{23-22} = type; 4761 let Inst{21} = 0; 4762 let Inst{20-19} = rmode; 4763 let Inst{18-16} = opcode; 4764 let Inst{15-10} = scale; 4765 let Inst{9-5} = Rn; 4766 let Inst{4-0} = Rd; 4767} 4768 4769multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4770 SDPatternOperator OpN> { 4771 // Unscaled half-precision to 32-bit 4772 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4773 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4774 let Inst{31} = 0; // 32-bit GPR flag 4775 let Predicates = [HasFullFP16]; 4776 } 4777 4778 // Unscaled half-precision to 64-bit 4779 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4780 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4781 let Inst{31} = 1; // 64-bit GPR flag 4782 let Predicates = [HasFullFP16]; 4783 } 4784 4785 // Unscaled single-precision to 32-bit 4786 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4787 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4788 let Inst{31} = 0; // 32-bit GPR flag 4789 } 4790 4791 // Unscaled single-precision to 64-bit 4792 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4793 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4794 let Inst{31} = 1; // 64-bit GPR flag 4795 } 4796 4797 // Unscaled double-precision to 32-bit 4798 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4799 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4800 let Inst{31} = 0; // 32-bit GPR flag 4801 } 4802 4803 // Unscaled double-precision to 64-bit 4804 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4805 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4806 let Inst{31} = 1; // 64-bit GPR flag 4807 } 4808} 4809 4810multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4811 SDPatternOperator OpN> { 4812 // Scaled half-precision to 32-bit 4813 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4814 fixedpoint_f16_i32, asm, 4815 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4816 fixedpoint_f16_i32:$scale)))]> { 4817 let Inst{31} = 0; // 32-bit GPR flag 4818 let scale{5} = 1; 4819 let Predicates = [HasFullFP16]; 4820 } 4821 4822 // Scaled half-precision to 64-bit 4823 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4824 fixedpoint_f16_i64, asm, 4825 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4826 fixedpoint_f16_i64:$scale)))]> { 4827 let Inst{31} = 1; // 64-bit GPR flag 4828 let Predicates = [HasFullFP16]; 4829 } 4830 4831 // Scaled single-precision to 32-bit 4832 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4833 fixedpoint_f32_i32, asm, 4834 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4835 fixedpoint_f32_i32:$scale)))]> { 4836 let Inst{31} = 0; // 32-bit GPR flag 4837 let scale{5} = 1; 4838 } 4839 4840 // Scaled single-precision to 64-bit 4841 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4842 fixedpoint_f32_i64, asm, 4843 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4844 fixedpoint_f32_i64:$scale)))]> { 4845 let Inst{31} = 1; // 64-bit GPR flag 4846 } 4847 4848 // Scaled double-precision to 32-bit 4849 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4850 fixedpoint_f64_i32, asm, 4851 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4852 fixedpoint_f64_i32:$scale)))]> { 4853 let Inst{31} = 0; // 32-bit GPR flag 4854 let scale{5} = 1; 4855 } 4856 4857 // Scaled double-precision to 64-bit 4858 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4859 fixedpoint_f64_i64, asm, 4860 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4861 fixedpoint_f64_i64:$scale)))]> { 4862 let Inst{31} = 1; // 64-bit GPR flag 4863 } 4864} 4865 4866//--- 4867// Integer to floating point conversion 4868//--- 4869 4870let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4871class BaseIntegerToFP<bit isUnsigned, 4872 RegisterClass srcType, RegisterClass dstType, 4873 Operand immType, string asm, list<dag> pattern> 4874 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4875 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4876 Sched<[WriteFCvt]> { 4877 bits<5> Rd; 4878 bits<5> Rn; 4879 bits<6> scale; 4880 let Inst{30-24} = 0b0011110; 4881 let Inst{21-17} = 0b00001; 4882 let Inst{16} = isUnsigned; 4883 let Inst{15-10} = scale; 4884 let Inst{9-5} = Rn; 4885 let Inst{4-0} = Rd; 4886} 4887 4888let mayRaiseFPException = 1, Uses = [FPCR] in 4889class BaseIntegerToFPUnscaled<bit isUnsigned, 4890 RegisterClass srcType, RegisterClass dstType, 4891 ValueType dvt, string asm, SDPatternOperator node> 4892 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4893 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4894 Sched<[WriteFCvt]> { 4895 bits<5> Rd; 4896 bits<5> Rn; 4897 bits<6> scale; 4898 let Inst{30-24} = 0b0011110; 4899 let Inst{21-17} = 0b10001; 4900 let Inst{16} = isUnsigned; 4901 let Inst{15-10} = 0b000000; 4902 let Inst{9-5} = Rn; 4903 let Inst{4-0} = Rd; 4904} 4905 4906multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4907 // Unscaled 4908 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4909 let Inst{31} = 0; // 32-bit GPR flag 4910 let Inst{23-22} = 0b11; // 16-bit FPR flag 4911 let Predicates = [HasFullFP16]; 4912 } 4913 4914 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4915 let Inst{31} = 0; // 32-bit GPR flag 4916 let Inst{23-22} = 0b00; // 32-bit FPR flag 4917 } 4918 4919 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4920 let Inst{31} = 0; // 32-bit GPR flag 4921 let Inst{23-22} = 0b01; // 64-bit FPR flag 4922 } 4923 4924 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4925 let Inst{31} = 1; // 64-bit GPR flag 4926 let Inst{23-22} = 0b11; // 16-bit FPR flag 4927 let Predicates = [HasFullFP16]; 4928 } 4929 4930 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4931 let Inst{31} = 1; // 64-bit GPR flag 4932 let Inst{23-22} = 0b00; // 32-bit FPR flag 4933 } 4934 4935 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4936 let Inst{31} = 1; // 64-bit GPR flag 4937 let Inst{23-22} = 0b01; // 64-bit FPR flag 4938 } 4939 4940 // Scaled 4941 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4942 [(set (f16 FPR16:$Rd), 4943 (fdiv (node GPR32:$Rn), 4944 fixedpoint_f16_i32:$scale))]> { 4945 let Inst{31} = 0; // 32-bit GPR flag 4946 let Inst{23-22} = 0b11; // 16-bit FPR flag 4947 let scale{5} = 1; 4948 let Predicates = [HasFullFP16]; 4949 } 4950 4951 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4952 [(set FPR32:$Rd, 4953 (fdiv (node GPR32:$Rn), 4954 fixedpoint_f32_i32:$scale))]> { 4955 let Inst{31} = 0; // 32-bit GPR flag 4956 let Inst{23-22} = 0b00; // 32-bit FPR flag 4957 let scale{5} = 1; 4958 } 4959 4960 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4961 [(set FPR64:$Rd, 4962 (fdiv (node GPR32:$Rn), 4963 fixedpoint_f64_i32:$scale))]> { 4964 let Inst{31} = 0; // 32-bit GPR flag 4965 let Inst{23-22} = 0b01; // 64-bit FPR flag 4966 let scale{5} = 1; 4967 } 4968 4969 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4970 [(set (f16 FPR16:$Rd), 4971 (fdiv (node GPR64:$Rn), 4972 fixedpoint_f16_i64:$scale))]> { 4973 let Inst{31} = 1; // 64-bit GPR flag 4974 let Inst{23-22} = 0b11; // 16-bit FPR flag 4975 let Predicates = [HasFullFP16]; 4976 } 4977 4978 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4979 [(set FPR32:$Rd, 4980 (fdiv (node GPR64:$Rn), 4981 fixedpoint_f32_i64:$scale))]> { 4982 let Inst{31} = 1; // 64-bit GPR flag 4983 let Inst{23-22} = 0b00; // 32-bit FPR flag 4984 } 4985 4986 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4987 [(set FPR64:$Rd, 4988 (fdiv (node GPR64:$Rn), 4989 fixedpoint_f64_i64:$scale))]> { 4990 let Inst{31} = 1; // 64-bit GPR flag 4991 let Inst{23-22} = 0b01; // 64-bit FPR flag 4992 } 4993} 4994 4995//--- 4996// Unscaled integer <-> floating point conversion (i.e. FMOV) 4997//--- 4998 4999let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5000class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 5001 RegisterClass srcType, RegisterClass dstType, 5002 string asm> 5003 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 5004 // We use COPY_TO_REGCLASS for these bitconvert operations. 5005 // copyPhysReg() expands the resultant COPY instructions after 5006 // regalloc is done. This gives greater freedom for the allocator 5007 // and related passes (coalescing, copy propagation, et. al.) to 5008 // be more effective. 5009 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 5010 Sched<[WriteFCopy]> { 5011 bits<5> Rd; 5012 bits<5> Rn; 5013 let Inst{30-24} = 0b0011110; 5014 let Inst{21} = 1; 5015 let Inst{20-19} = rmode; 5016 let Inst{18-16} = opcode; 5017 let Inst{15-10} = 0b000000; 5018 let Inst{9-5} = Rn; 5019 let Inst{4-0} = Rd; 5020} 5021 5022let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5023class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 5024 RegisterClass srcType, RegisterOperand dstType, string asm, 5025 string kind> 5026 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5027 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 5028 Sched<[WriteFCopy]> { 5029 bits<5> Rd; 5030 bits<5> Rn; 5031 let Inst{30-23} = 0b00111101; 5032 let Inst{21} = 1; 5033 let Inst{20-19} = rmode; 5034 let Inst{18-16} = opcode; 5035 let Inst{15-10} = 0b000000; 5036 let Inst{9-5} = Rn; 5037 let Inst{4-0} = Rd; 5038 5039 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5040} 5041 5042let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5043class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 5044 RegisterOperand srcType, RegisterClass dstType, string asm, 5045 string kind> 5046 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5047 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 5048 Sched<[WriteFCopy]> { 5049 bits<5> Rd; 5050 bits<5> Rn; 5051 let Inst{30-23} = 0b00111101; 5052 let Inst{21} = 1; 5053 let Inst{20-19} = rmode; 5054 let Inst{18-16} = opcode; 5055 let Inst{15-10} = 0b000000; 5056 let Inst{9-5} = Rn; 5057 let Inst{4-0} = Rd; 5058 5059 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5060} 5061 5062 5063multiclass UnscaledConversion<string asm> { 5064 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 5065 let Inst{31} = 0; // 32-bit GPR flag 5066 let Inst{23-22} = 0b11; // 16-bit FPR flag 5067 let Predicates = [HasFullFP16]; 5068 } 5069 5070 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 5071 let Inst{31} = 1; // 64-bit GPR flag 5072 let Inst{23-22} = 0b11; // 16-bit FPR flag 5073 let Predicates = [HasFullFP16]; 5074 } 5075 5076 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 5077 let Inst{31} = 0; // 32-bit GPR flag 5078 let Inst{23-22} = 0b00; // 32-bit FPR flag 5079 } 5080 5081 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 5082 let Inst{31} = 1; // 64-bit GPR flag 5083 let Inst{23-22} = 0b01; // 64-bit FPR flag 5084 } 5085 5086 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 5087 let Inst{31} = 0; // 32-bit GPR flag 5088 let Inst{23-22} = 0b11; // 16-bit FPR flag 5089 let Predicates = [HasFullFP16]; 5090 } 5091 5092 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 5093 let Inst{31} = 1; // 64-bit GPR flag 5094 let Inst{23-22} = 0b11; // 16-bit FPR flag 5095 let Predicates = [HasFullFP16]; 5096 } 5097 5098 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 5099 let Inst{31} = 0; // 32-bit GPR flag 5100 let Inst{23-22} = 0b00; // 32-bit FPR flag 5101 } 5102 5103 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 5104 let Inst{31} = 1; // 64-bit GPR flag 5105 let Inst{23-22} = 0b01; // 64-bit FPR flag 5106 } 5107 5108 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 5109 asm, ".d"> { 5110 let Inst{31} = 1; 5111 let Inst{22} = 0; 5112 } 5113 5114 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 5115 asm, ".d"> { 5116 let Inst{31} = 1; 5117 let Inst{22} = 0; 5118 } 5119} 5120 5121//--- 5122// Floating point conversion 5123//--- 5124 5125let mayRaiseFPException = 1, Uses = [FPCR] in 5126class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 5127 RegisterClass srcType, string asm, list<dag> pattern> 5128 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 5129 Sched<[WriteFCvt]> { 5130 bits<5> Rd; 5131 bits<5> Rn; 5132 let Inst{31-24} = 0b00011110; 5133 let Inst{23-22} = type; 5134 let Inst{21-17} = 0b10001; 5135 let Inst{16-15} = opcode; 5136 let Inst{14-10} = 0b10000; 5137 let Inst{9-5} = Rn; 5138 let Inst{4-0} = Rd; 5139} 5140 5141multiclass FPConversion<string asm> { 5142 // Double-precision to Half-precision 5143 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 5144 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 5145 5146 // Double-precision to Single-precision 5147 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 5148 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5149 5150 // Half-precision to Double-precision 5151 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5152 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5153 5154 // Half-precision to Single-precision 5155 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5156 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5157 5158 // Single-precision to Double-precision 5159 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5160 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5161 5162 // Single-precision to Half-precision 5163 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5164 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5165} 5166 5167//--- 5168// Single operand floating point data processing 5169//--- 5170 5171let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5172class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5173 ValueType vt, string asm, SDPatternOperator node> 5174 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5175 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5176 Sched<[WriteF]> { 5177 bits<5> Rd; 5178 bits<5> Rn; 5179 let Inst{31-24} = 0b00011110; 5180 let Inst{21} = 0b1; 5181 let Inst{20-15} = opcode; 5182 let Inst{14-10} = 0b10000; 5183 let Inst{9-5} = Rn; 5184 let Inst{4-0} = Rd; 5185} 5186 5187multiclass SingleOperandFPData<bits<4> opcode, string asm, 5188 SDPatternOperator node = null_frag, 5189 int fpexceptions = 1> { 5190 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 5191 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5192 let Inst{23-22} = 0b11; // 16-bit size flag 5193 let Predicates = [HasFullFP16]; 5194 } 5195 5196 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5197 let Inst{23-22} = 0b00; // 32-bit size flag 5198 } 5199 5200 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5201 let Inst{23-22} = 0b01; // 64-bit size flag 5202 } 5203 } 5204} 5205 5206multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5207 SDPatternOperator node = null_frag> 5208 : SingleOperandFPData<opcode, asm, node, 0>; 5209 5210let mayRaiseFPException = 1, Uses = [FPCR] in 5211multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5212 SDPatternOperator node = null_frag>{ 5213 5214 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5215 let Inst{23-22} = 0b00; // 32-bit registers 5216 } 5217 5218 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5219 let Inst{23-22} = 0b01; // 64-bit registers 5220 } 5221} 5222 5223// FRInt[32|64][Z|N] instructions 5224multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5225 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5226 5227//--- 5228// Two operand floating point data processing 5229//--- 5230 5231let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5232class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5233 string asm, list<dag> pat> 5234 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5235 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5236 Sched<[WriteF]> { 5237 bits<5> Rd; 5238 bits<5> Rn; 5239 bits<5> Rm; 5240 let Inst{31-24} = 0b00011110; 5241 let Inst{21} = 1; 5242 let Inst{20-16} = Rm; 5243 let Inst{15-12} = opcode; 5244 let Inst{11-10} = 0b10; 5245 let Inst{9-5} = Rn; 5246 let Inst{4-0} = Rd; 5247} 5248 5249multiclass TwoOperandFPData<bits<4> opcode, string asm, 5250 SDPatternOperator node = null_frag> { 5251 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5252 [(set (f16 FPR16:$Rd), 5253 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5254 let Inst{23-22} = 0b11; // 16-bit size flag 5255 let Predicates = [HasFullFP16]; 5256 } 5257 5258 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5259 [(set (f32 FPR32:$Rd), 5260 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5261 let Inst{23-22} = 0b00; // 32-bit size flag 5262 } 5263 5264 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5265 [(set (f64 FPR64:$Rd), 5266 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5267 let Inst{23-22} = 0b01; // 64-bit size flag 5268 } 5269} 5270 5271multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5272 SDPatternOperator node> { 5273 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5274 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5275 let Inst{23-22} = 0b11; // 16-bit size flag 5276 let Predicates = [HasFullFP16]; 5277 } 5278 5279 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5280 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5281 let Inst{23-22} = 0b00; // 32-bit size flag 5282 } 5283 5284 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5285 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5286 let Inst{23-22} = 0b01; // 64-bit size flag 5287 } 5288} 5289 5290 5291//--- 5292// Three operand floating point data processing 5293//--- 5294 5295let mayRaiseFPException = 1, Uses = [FPCR] in 5296class BaseThreeOperandFPData<bit isNegated, bit isSub, 5297 RegisterClass regtype, string asm, list<dag> pat> 5298 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5299 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5300 Sched<[WriteFMul]> { 5301 bits<5> Rd; 5302 bits<5> Rn; 5303 bits<5> Rm; 5304 bits<5> Ra; 5305 let Inst{31-24} = 0b00011111; 5306 let Inst{21} = isNegated; 5307 let Inst{20-16} = Rm; 5308 let Inst{15} = isSub; 5309 let Inst{14-10} = Ra; 5310 let Inst{9-5} = Rn; 5311 let Inst{4-0} = Rd; 5312} 5313 5314multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5315 SDPatternOperator node> { 5316 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5317 [(set (f16 FPR16:$Rd), 5318 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5319 let Inst{23-22} = 0b11; // 16-bit size flag 5320 let Predicates = [HasFullFP16]; 5321 } 5322 5323 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5324 [(set FPR32:$Rd, 5325 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5326 let Inst{23-22} = 0b00; // 32-bit size flag 5327 } 5328 5329 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5330 [(set FPR64:$Rd, 5331 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5332 let Inst{23-22} = 0b01; // 64-bit size flag 5333 } 5334} 5335 5336//--- 5337// Floating point data comparisons 5338//--- 5339 5340let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5341class BaseOneOperandFPComparison<bit signalAllNans, 5342 RegisterClass regtype, string asm, 5343 list<dag> pat> 5344 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5345 Sched<[WriteFCmp]> { 5346 bits<5> Rn; 5347 let Inst{31-24} = 0b00011110; 5348 let Inst{21} = 1; 5349 5350 let Inst{15-10} = 0b001000; 5351 let Inst{9-5} = Rn; 5352 let Inst{4} = signalAllNans; 5353 let Inst{3-0} = 0b1000; 5354 5355 // Rm should be 0b00000 canonically, but we need to accept any value. 5356 let PostEncoderMethod = "fixOneOperandFPComparison"; 5357} 5358 5359let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5360class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5361 string asm, list<dag> pat> 5362 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5363 Sched<[WriteFCmp]> { 5364 bits<5> Rm; 5365 bits<5> Rn; 5366 let Inst{31-24} = 0b00011110; 5367 let Inst{21} = 1; 5368 let Inst{20-16} = Rm; 5369 let Inst{15-10} = 0b001000; 5370 let Inst{9-5} = Rn; 5371 let Inst{4} = signalAllNans; 5372 let Inst{3-0} = 0b0000; 5373} 5374 5375multiclass FPComparison<bit signalAllNans, string asm, 5376 SDPatternOperator OpNode = null_frag> { 5377 let Defs = [NZCV] in { 5378 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5379 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5380 let Inst{23-22} = 0b11; 5381 let Predicates = [HasFullFP16]; 5382 } 5383 5384 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5385 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5386 let Inst{23-22} = 0b11; 5387 let Predicates = [HasFullFP16]; 5388 } 5389 5390 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5391 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5392 let Inst{23-22} = 0b00; 5393 } 5394 5395 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5396 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5397 let Inst{23-22} = 0b00; 5398 } 5399 5400 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5401 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5402 let Inst{23-22} = 0b01; 5403 } 5404 5405 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5406 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5407 let Inst{23-22} = 0b01; 5408 } 5409 } // Defs = [NZCV] 5410} 5411 5412//--- 5413// Floating point conditional comparisons 5414//--- 5415 5416let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5417class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5418 string mnemonic, list<dag> pat> 5419 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5420 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5421 Sched<[WriteFCmp]> { 5422 let Uses = [NZCV]; 5423 let Defs = [NZCV]; 5424 5425 bits<5> Rn; 5426 bits<5> Rm; 5427 bits<4> nzcv; 5428 bits<4> cond; 5429 5430 let Inst{31-24} = 0b00011110; 5431 let Inst{21} = 1; 5432 let Inst{20-16} = Rm; 5433 let Inst{15-12} = cond; 5434 let Inst{11-10} = 0b01; 5435 let Inst{9-5} = Rn; 5436 let Inst{4} = signalAllNans; 5437 let Inst{3-0} = nzcv; 5438} 5439 5440multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5441 SDPatternOperator OpNode = null_frag> { 5442 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5443 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5444 (i32 imm:$cond), NZCV))]> { 5445 let Inst{23-22} = 0b11; 5446 let Predicates = [HasFullFP16]; 5447 } 5448 5449 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5450 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5451 (i32 imm:$cond), NZCV))]> { 5452 let Inst{23-22} = 0b00; 5453 } 5454 5455 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5456 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5457 (i32 imm:$cond), NZCV))]> { 5458 let Inst{23-22} = 0b01; 5459 } 5460} 5461 5462//--- 5463// Floating point conditional select 5464//--- 5465 5466class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5467 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5468 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5469 [(set regtype:$Rd, 5470 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5471 (i32 imm:$cond), NZCV))]>, 5472 Sched<[WriteF]> { 5473 bits<5> Rd; 5474 bits<5> Rn; 5475 bits<5> Rm; 5476 bits<4> cond; 5477 5478 let Inst{31-24} = 0b00011110; 5479 let Inst{21} = 1; 5480 let Inst{20-16} = Rm; 5481 let Inst{15-12} = cond; 5482 let Inst{11-10} = 0b11; 5483 let Inst{9-5} = Rn; 5484 let Inst{4-0} = Rd; 5485} 5486 5487multiclass FPCondSelect<string asm> { 5488 let Uses = [NZCV] in { 5489 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5490 let Inst{23-22} = 0b11; 5491 let Predicates = [HasFullFP16]; 5492 } 5493 5494 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5495 let Inst{23-22} = 0b00; 5496 } 5497 5498 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5499 let Inst{23-22} = 0b01; 5500 } 5501 } // Uses = [NZCV] 5502} 5503 5504//--- 5505// Floating move immediate 5506//--- 5507 5508class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5509 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5510 [(set regtype:$Rd, fpimmtype:$imm)]>, 5511 Sched<[WriteFImm]> { 5512 bits<5> Rd; 5513 bits<8> imm; 5514 let Inst{31-24} = 0b00011110; 5515 let Inst{21} = 1; 5516 let Inst{20-13} = imm; 5517 let Inst{12-5} = 0b10000000; 5518 let Inst{4-0} = Rd; 5519} 5520 5521multiclass FPMoveImmediate<string asm> { 5522 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5523 let Inst{23-22} = 0b11; 5524 let Predicates = [HasFullFP16]; 5525 } 5526 5527 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5528 let Inst{23-22} = 0b00; 5529 } 5530 5531 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5532 let Inst{23-22} = 0b01; 5533 } 5534} 5535} // end of 'let Predicates = [HasFPARMv8]' 5536 5537//---------------------------------------------------------------------------- 5538// AdvSIMD 5539//---------------------------------------------------------------------------- 5540 5541let Predicates = [HasNEON] in { 5542 5543//---------------------------------------------------------------------------- 5544// AdvSIMD three register vector instructions 5545//---------------------------------------------------------------------------- 5546 5547let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5548class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5549 RegisterOperand regtype, string asm, string kind, 5550 list<dag> pattern> 5551 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5552 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5553 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5554 Sched<[!if(Q, WriteVq, WriteVd)]> { 5555 bits<5> Rd; 5556 bits<5> Rn; 5557 bits<5> Rm; 5558 let Inst{31} = 0; 5559 let Inst{30} = Q; 5560 let Inst{29} = U; 5561 let Inst{28-24} = 0b01110; 5562 let Inst{23-21} = size; 5563 let Inst{20-16} = Rm; 5564 let Inst{15-11} = opcode; 5565 let Inst{10} = 1; 5566 let Inst{9-5} = Rn; 5567 let Inst{4-0} = Rd; 5568} 5569 5570let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5571class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5572 RegisterOperand regtype, string asm, string kind, 5573 list<dag> pattern> 5574 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5575 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5576 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5577 Sched<[!if(Q, WriteVq, WriteVd)]> { 5578 bits<5> Rd; 5579 bits<5> Rn; 5580 bits<5> Rm; 5581 let Inst{31} = 0; 5582 let Inst{30} = Q; 5583 let Inst{29} = U; 5584 let Inst{28-24} = 0b01110; 5585 let Inst{23-21} = size; 5586 let Inst{20-16} = Rm; 5587 let Inst{15-11} = opcode; 5588 let Inst{10} = 1; 5589 let Inst{9-5} = Rn; 5590 let Inst{4-0} = Rd; 5591} 5592 5593let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5594class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5595 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5596 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5597 5598multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5599 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5600 [(set (v8i8 V64:$dst), 5601 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5602 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5603 [(set (v16i8 V128:$dst), 5604 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5605 (v16i8 V128:$Rm)))]>; 5606 5607 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5608 (v4i16 V64:$RHS))), 5609 (!cast<Instruction>(NAME#"v8i8") 5610 V64:$LHS, V64:$MHS, V64:$RHS)>; 5611 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5612 (v2i32 V64:$RHS))), 5613 (!cast<Instruction>(NAME#"v8i8") 5614 V64:$LHS, V64:$MHS, V64:$RHS)>; 5615 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5616 (v1i64 V64:$RHS))), 5617 (!cast<Instruction>(NAME#"v8i8") 5618 V64:$LHS, V64:$MHS, V64:$RHS)>; 5619 5620 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5621 (v8i16 V128:$RHS))), 5622 (!cast<Instruction>(NAME#"v16i8") 5623 V128:$LHS, V128:$MHS, V128:$RHS)>; 5624 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5625 (v4i32 V128:$RHS))), 5626 (!cast<Instruction>(NAME#"v16i8") 5627 V128:$LHS, V128:$MHS, V128:$RHS)>; 5628 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5629 (v2i64 V128:$RHS))), 5630 (!cast<Instruction>(NAME#"v16i8") 5631 V128:$LHS, V128:$MHS, V128:$RHS)>; 5632} 5633 5634// All operand sizes distinguished in the encoding. 5635multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5636 SDPatternOperator OpNode> { 5637 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5638 asm, ".8b", 5639 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5640 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5641 asm, ".16b", 5642 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5643 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5644 asm, ".4h", 5645 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5646 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5647 asm, ".8h", 5648 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5649 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5650 asm, ".2s", 5651 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5652 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5653 asm, ".4s", 5654 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5655 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5656 asm, ".2d", 5657 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5658} 5659 5660multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5661 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5662 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5663 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5664 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5665 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5666 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5667 5668 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5669 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5670 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5671 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5672 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5673 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5674 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5675 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5676} 5677 5678// As above, but D sized elements unsupported. 5679multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5680 SDPatternOperator OpNode> { 5681 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5682 asm, ".8b", 5683 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5684 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5685 asm, ".16b", 5686 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5687 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5688 asm, ".4h", 5689 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5690 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5691 asm, ".8h", 5692 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5693 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5694 asm, ".2s", 5695 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5696 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5697 asm, ".4s", 5698 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5699} 5700 5701multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5702 SDPatternOperator OpNode> { 5703 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5704 asm, ".8b", 5705 [(set (v8i8 V64:$dst), 5706 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5707 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5708 asm, ".16b", 5709 [(set (v16i8 V128:$dst), 5710 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5711 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5712 asm, ".4h", 5713 [(set (v4i16 V64:$dst), 5714 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5715 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5716 asm, ".8h", 5717 [(set (v8i16 V128:$dst), 5718 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5719 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5720 asm, ".2s", 5721 [(set (v2i32 V64:$dst), 5722 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5723 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5724 asm, ".4s", 5725 [(set (v4i32 V128:$dst), 5726 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5727} 5728 5729// As above, but only B sized elements supported. 5730multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5731 SDPatternOperator OpNode> { 5732 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5733 asm, ".8b", 5734 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5735 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5736 asm, ".16b", 5737 [(set (v16i8 V128:$Rd), 5738 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5739} 5740 5741// As above, but only floating point elements supported. 5742let mayRaiseFPException = 1, Uses = [FPCR] in 5743multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5744 string asm, SDPatternOperator OpNode> { 5745 let Predicates = [HasNEON, HasFullFP16] in { 5746 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5747 asm, ".4h", 5748 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5749 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5750 asm, ".8h", 5751 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5752 } // Predicates = [HasNEON, HasFullFP16] 5753 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5754 asm, ".2s", 5755 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5756 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5757 asm, ".4s", 5758 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5759 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5760 asm, ".2d", 5761 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5762} 5763 5764let mayRaiseFPException = 1, Uses = [FPCR] in 5765multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5766 string asm, 5767 SDPatternOperator OpNode> { 5768 let Predicates = [HasNEON, HasFullFP16] in { 5769 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5770 asm, ".4h", 5771 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5772 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5773 asm, ".8h", 5774 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5775 } // Predicates = [HasNEON, HasFullFP16] 5776 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5777 asm, ".2s", 5778 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5779 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5780 asm, ".4s", 5781 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5782 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5783 asm, ".2d", 5784 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5785} 5786 5787let mayRaiseFPException = 1, Uses = [FPCR] in 5788multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5789 string asm, SDPatternOperator OpNode> { 5790 let Predicates = [HasNEON, HasFullFP16] in { 5791 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5792 asm, ".4h", 5793 [(set (v4f16 V64:$dst), 5794 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5795 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5796 asm, ".8h", 5797 [(set (v8f16 V128:$dst), 5798 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5799 } // Predicates = [HasNEON, HasFullFP16] 5800 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5801 asm, ".2s", 5802 [(set (v2f32 V64:$dst), 5803 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5804 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5805 asm, ".4s", 5806 [(set (v4f32 V128:$dst), 5807 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5808 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5809 asm, ".2d", 5810 [(set (v2f64 V128:$dst), 5811 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5812} 5813 5814// As above, but D and B sized elements unsupported. 5815let mayRaiseFPException = 1, Uses = [FPCR] in 5816multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5817 SDPatternOperator OpNode> { 5818 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5819 asm, ".4h", 5820 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5821 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5822 asm, ".8h", 5823 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5824 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5825 asm, ".2s", 5826 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5827 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5828 asm, ".4s", 5829 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5830} 5831 5832// Logical three vector ops share opcode bits, and only use B sized elements. 5833multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5834 SDPatternOperator OpNode = null_frag> { 5835 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5836 asm, ".8b", 5837 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5838 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5839 asm, ".16b", 5840 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5841 5842 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5843 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5844 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5845 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5846 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5847 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5848 5849 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5850 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5851 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5852 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5853 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5854 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5855} 5856 5857multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5858 string asm, SDPatternOperator OpNode = null_frag> { 5859 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5860 asm, ".8b", 5861 [(set (v8i8 V64:$dst), 5862 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5863 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5864 asm, ".16b", 5865 [(set (v16i8 V128:$dst), 5866 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5867 (v16i8 V128:$Rm)))]>; 5868 5869 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5870 (v4i16 V64:$RHS))), 5871 (!cast<Instruction>(NAME#"v8i8") 5872 V64:$LHS, V64:$MHS, V64:$RHS)>; 5873 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5874 (v2i32 V64:$RHS))), 5875 (!cast<Instruction>(NAME#"v8i8") 5876 V64:$LHS, V64:$MHS, V64:$RHS)>; 5877 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5878 (v1i64 V64:$RHS))), 5879 (!cast<Instruction>(NAME#"v8i8") 5880 V64:$LHS, V64:$MHS, V64:$RHS)>; 5881 5882 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5883 (v8i16 V128:$RHS))), 5884 (!cast<Instruction>(NAME#"v16i8") 5885 V128:$LHS, V128:$MHS, V128:$RHS)>; 5886 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5887 (v4i32 V128:$RHS))), 5888 (!cast<Instruction>(NAME#"v16i8") 5889 V128:$LHS, V128:$MHS, V128:$RHS)>; 5890 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5891 (v2i64 V128:$RHS))), 5892 (!cast<Instruction>(NAME#"v16i8") 5893 V128:$LHS, V128:$MHS, V128:$RHS)>; 5894} 5895 5896// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5897// bytes from S-sized elements. 5898class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5899 string kind2, RegisterOperand RegType, 5900 ValueType AccumType, ValueType InputType, 5901 SDPatternOperator OpNode> : 5902 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5903 [(set (AccumType RegType:$dst), 5904 (OpNode (AccumType RegType:$Rd), 5905 (InputType RegType:$Rn), 5906 (InputType RegType:$Rm)))]> { 5907 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5908} 5909 5910multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5911 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5912 v2i32, v8i8, OpNode>; 5913 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5914 v4i32, v16i8, OpNode>; 5915} 5916 5917// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5918// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5919// 8H to 4S, when Q=1). 5920let mayRaiseFPException = 1, Uses = [FPCR] in 5921class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5922 string kind2, RegisterOperand RegType, 5923 ValueType AccumType, ValueType InputType, 5924 SDPatternOperator OpNode> : 5925 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5926 [(set (AccumType RegType:$dst), 5927 (OpNode (AccumType RegType:$Rd), 5928 (InputType RegType:$Rn), 5929 (InputType RegType:$Rm)))]> { 5930 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5931 let Inst{13} = b13; 5932} 5933 5934multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5935 SDPatternOperator OpNode> { 5936 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5937 v2f32, v4f16, OpNode>; 5938 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5939 v4f32, v8f16, OpNode>; 5940} 5941 5942 5943//---------------------------------------------------------------------------- 5944// AdvSIMD two register vector instructions. 5945//---------------------------------------------------------------------------- 5946 5947let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5948class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5949 bits<2> size2, RegisterOperand regtype, string asm, 5950 string dstkind, string srckind, list<dag> pattern> 5951 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5952 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5953 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5954 Sched<[!if(Q, WriteVq, WriteVd)]> { 5955 bits<5> Rd; 5956 bits<5> Rn; 5957 let Inst{31} = 0; 5958 let Inst{30} = Q; 5959 let Inst{29} = U; 5960 let Inst{28-24} = 0b01110; 5961 let Inst{23-22} = size; 5962 let Inst{21} = 0b1; 5963 let Inst{20-19} = size2; 5964 let Inst{18-17} = 0b00; 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 5971let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5972class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5973 bits<2> size2, RegisterOperand regtype, 5974 string asm, string dstkind, string srckind, 5975 list<dag> pattern> 5976 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5977 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5978 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5979 Sched<[!if(Q, WriteVq, WriteVd)]> { 5980 bits<5> Rd; 5981 bits<5> Rn; 5982 let Inst{31} = 0; 5983 let Inst{30} = Q; 5984 let Inst{29} = U; 5985 let Inst{28-24} = 0b01110; 5986 let Inst{23-22} = size; 5987 let Inst{21} = 0b1; 5988 let Inst{20-19} = size2; 5989 let Inst{18-17} = 0b00; 5990 let Inst{16-12} = opcode; 5991 let Inst{11-10} = 0b10; 5992 let Inst{9-5} = Rn; 5993 let Inst{4-0} = Rd; 5994} 5995 5996// Supports B, H, and S element sizes. 5997multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5998 SDPatternOperator OpNode> { 5999 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6000 asm, ".8b", ".8b", 6001 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6002 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6003 asm, ".16b", ".16b", 6004 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6005 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6006 asm, ".4h", ".4h", 6007 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6008 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6009 asm, ".8h", ".8h", 6010 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6011 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6012 asm, ".2s", ".2s", 6013 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6014 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6015 asm, ".4s", ".4s", 6016 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6017} 6018 6019class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 6020 RegisterOperand regtype, string asm, string dstkind, 6021 string srckind, string amount> 6022 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 6023 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 6024 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 6025 Sched<[WriteVq]> { 6026 bits<5> Rd; 6027 bits<5> Rn; 6028 let Inst{31} = 0; 6029 let Inst{30} = Q; 6030 let Inst{29-24} = 0b101110; 6031 let Inst{23-22} = size; 6032 let Inst{21-10} = 0b100001001110; 6033 let Inst{9-5} = Rn; 6034 let Inst{4-0} = Rd; 6035} 6036 6037multiclass SIMDVectorLShiftLongBySizeBHS { 6038 let hasSideEffects = 0 in { 6039 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 6040 "shll", ".8h", ".8b", "8">; 6041 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 6042 "shll2", ".8h", ".16b", "8">; 6043 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 6044 "shll", ".4s", ".4h", "16">; 6045 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 6046 "shll2", ".4s", ".8h", "16">; 6047 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 6048 "shll", ".2d", ".2s", "32">; 6049 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 6050 "shll2", ".2d", ".4s", "32">; 6051 } 6052} 6053 6054// Supports all element sizes. 6055multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 6056 SDPatternOperator OpNode> { 6057 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6058 asm, ".4h", ".8b", 6059 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6060 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6061 asm, ".8h", ".16b", 6062 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6063 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6064 asm, ".2s", ".4h", 6065 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6066 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6067 asm, ".4s", ".8h", 6068 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6069 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6070 asm, ".1d", ".2s", 6071 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6072 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6073 asm, ".2d", ".4s", 6074 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6075} 6076 6077multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 6078 SDPatternOperator OpNode> { 6079 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6080 asm, ".4h", ".8b", 6081 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 6082 (v8i8 V64:$Rn)))]>; 6083 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6084 asm, ".8h", ".16b", 6085 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 6086 (v16i8 V128:$Rn)))]>; 6087 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6088 asm, ".2s", ".4h", 6089 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 6090 (v4i16 V64:$Rn)))]>; 6091 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6092 asm, ".4s", ".8h", 6093 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 6094 (v8i16 V128:$Rn)))]>; 6095 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6096 asm, ".1d", ".2s", 6097 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 6098 (v2i32 V64:$Rn)))]>; 6099 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6100 asm, ".2d", ".4s", 6101 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 6102 (v4i32 V128:$Rn)))]>; 6103} 6104 6105// Supports all element sizes, except 1xD. 6106multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 6107 SDPatternOperator OpNode> { 6108 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6109 asm, ".8b", ".8b", 6110 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 6111 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6112 asm, ".16b", ".16b", 6113 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 6114 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6115 asm, ".4h", ".4h", 6116 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 6117 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6118 asm, ".8h", ".8h", 6119 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 6120 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6121 asm, ".2s", ".2s", 6122 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 6123 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6124 asm, ".4s", ".4s", 6125 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 6126 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 6127 asm, ".2d", ".2d", 6128 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 6129} 6130 6131multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 6132 SDPatternOperator OpNode = null_frag> { 6133 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6134 asm, ".8b", ".8b", 6135 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6136 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6137 asm, ".16b", ".16b", 6138 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6139 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6140 asm, ".4h", ".4h", 6141 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6142 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6143 asm, ".8h", ".8h", 6144 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6145 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6146 asm, ".2s", ".2s", 6147 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6148 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6149 asm, ".4s", ".4s", 6150 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6151 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6152 asm, ".2d", ".2d", 6153 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6154} 6155 6156 6157// Supports only B element sizes. 6158multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6159 SDPatternOperator OpNode> { 6160 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6161 asm, ".8b", ".8b", 6162 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6163 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6164 asm, ".16b", ".16b", 6165 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6166 6167} 6168 6169// Supports only B and H element sizes. 6170multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6171 SDPatternOperator OpNode> { 6172 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6173 asm, ".8b", ".8b", 6174 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6175 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6176 asm, ".16b", ".16b", 6177 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6178 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6179 asm, ".4h", ".4h", 6180 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6181 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6182 asm, ".8h", ".8h", 6183 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6184} 6185 6186// Supports H, S and D element sizes, uses high bit of the size field 6187// as an extra opcode bit. 6188multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6189 SDPatternOperator OpNode, 6190 int fpexceptions = 1> { 6191 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 6192 let Predicates = [HasNEON, HasFullFP16] in { 6193 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6194 asm, ".4h", ".4h", 6195 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6196 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6197 asm, ".8h", ".8h", 6198 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6199 } // Predicates = [HasNEON, HasFullFP16] 6200 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6201 asm, ".2s", ".2s", 6202 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6203 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6204 asm, ".4s", ".4s", 6205 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6206 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6207 asm, ".2d", ".2d", 6208 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6209 } 6210} 6211 6212multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6213 SDPatternOperator OpNode> 6214 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6215 6216// Supports only S and D element sizes 6217let mayRaiseFPException = 1, Uses = [FPCR] in 6218multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6219 SDPatternOperator OpNode = null_frag> { 6220 6221 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6222 asm, ".2s", ".2s", 6223 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6224 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6225 asm, ".4s", ".4s", 6226 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6227 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6228 asm, ".2d", ".2d", 6229 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6230} 6231 6232multiclass FRIntNNTVector<bit U, bit op, string asm, 6233 SDPatternOperator OpNode = null_frag> : 6234 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6235 6236// Supports only S element size. 6237multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6238 SDPatternOperator OpNode> { 6239 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6240 asm, ".2s", ".2s", 6241 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6242 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6243 asm, ".4s", ".4s", 6244 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6245} 6246 6247let mayRaiseFPException = 1, Uses = [FPCR] in 6248multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6249 SDPatternOperator OpNode> { 6250 let Predicates = [HasNEON, HasFullFP16] in { 6251 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6252 asm, ".4h", ".4h", 6253 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6254 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6255 asm, ".8h", ".8h", 6256 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6257 } // Predicates = [HasNEON, HasFullFP16] 6258 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6259 asm, ".2s", ".2s", 6260 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6261 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6262 asm, ".4s", ".4s", 6263 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6264 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6265 asm, ".2d", ".2d", 6266 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6267} 6268 6269let mayRaiseFPException = 1, Uses = [FPCR] in 6270multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6271 SDPatternOperator OpNode> { 6272 let Predicates = [HasNEON, HasFullFP16] in { 6273 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6274 asm, ".4h", ".4h", 6275 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6276 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6277 asm, ".8h", ".8h", 6278 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6279 } // Predicates = [HasNEON, HasFullFP16] 6280 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6281 asm, ".2s", ".2s", 6282 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6283 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6284 asm, ".4s", ".4s", 6285 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6286 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6287 asm, ".2d", ".2d", 6288 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6289} 6290 6291let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6292class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6293 RegisterOperand inreg, RegisterOperand outreg, 6294 string asm, string outkind, string inkind, 6295 list<dag> pattern> 6296 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6297 "{\t$Rd" # outkind # ", $Rn" # inkind # 6298 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6299 Sched<[WriteVq]> { 6300 bits<5> Rd; 6301 bits<5> Rn; 6302 let Inst{31} = 0; 6303 let Inst{30} = Q; 6304 let Inst{29} = U; 6305 let Inst{28-24} = 0b01110; 6306 let Inst{23-22} = size; 6307 let Inst{21-17} = 0b10000; 6308 let Inst{16-12} = opcode; 6309 let Inst{11-10} = 0b10; 6310 let Inst{9-5} = Rn; 6311 let Inst{4-0} = Rd; 6312} 6313 6314let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6315class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6316 RegisterOperand inreg, RegisterOperand outreg, 6317 string asm, string outkind, string inkind, 6318 list<dag> pattern> 6319 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6320 "{\t$Rd" # outkind # ", $Rn" # inkind # 6321 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6322 Sched<[WriteVq]> { 6323 bits<5> Rd; 6324 bits<5> Rn; 6325 let Inst{31} = 0; 6326 let Inst{30} = Q; 6327 let Inst{29} = U; 6328 let Inst{28-24} = 0b01110; 6329 let Inst{23-22} = size; 6330 let Inst{21-17} = 0b10000; 6331 let Inst{16-12} = opcode; 6332 let Inst{11-10} = 0b10; 6333 let Inst{9-5} = Rn; 6334 let Inst{4-0} = Rd; 6335} 6336 6337multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6338 SDPatternOperator OpNode> { 6339 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6340 asm, ".8b", ".8h", 6341 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6342 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6343 asm#"2", ".16b", ".8h", []>; 6344 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6345 asm, ".4h", ".4s", 6346 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6347 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6348 asm#"2", ".8h", ".4s", []>; 6349 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6350 asm, ".2s", ".2d", 6351 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6352 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6353 asm#"2", ".4s", ".2d", []>; 6354 6355 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6356 (!cast<Instruction>(NAME # "v16i8") 6357 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6358 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6359 (!cast<Instruction>(NAME # "v8i16") 6360 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6361 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6362 (!cast<Instruction>(NAME # "v4i32") 6363 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6364} 6365 6366class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6367 bits<5> opcode, RegisterOperand regtype, string asm, 6368 string kind, string zero, ValueType dty, 6369 ValueType sty, SDNode OpNode> 6370 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6371 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6372 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6373 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6374 Sched<[!if(Q, WriteVq, WriteVd)]> { 6375 bits<5> Rd; 6376 bits<5> Rn; 6377 let Inst{31} = 0; 6378 let Inst{30} = Q; 6379 let Inst{29} = U; 6380 let Inst{28-24} = 0b01110; 6381 let Inst{23-22} = size; 6382 let Inst{21} = 0b1; 6383 let Inst{20-19} = size2; 6384 let Inst{18-17} = 0b00; 6385 let Inst{16-12} = opcode; 6386 let Inst{11-10} = 0b10; 6387 let Inst{9-5} = Rn; 6388 let Inst{4-0} = Rd; 6389} 6390 6391// Comparisons support all element sizes, except 1xD. 6392multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6393 SDNode OpNode> { 6394 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6395 asm, ".8b", "0", 6396 v8i8, v8i8, OpNode>; 6397 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6398 asm, ".16b", "0", 6399 v16i8, v16i8, OpNode>; 6400 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6401 asm, ".4h", "0", 6402 v4i16, v4i16, OpNode>; 6403 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6404 asm, ".8h", "0", 6405 v8i16, v8i16, OpNode>; 6406 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6407 asm, ".2s", "0", 6408 v2i32, v2i32, OpNode>; 6409 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6410 asm, ".4s", "0", 6411 v4i32, v4i32, OpNode>; 6412 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6413 asm, ".2d", "0", 6414 v2i64, v2i64, OpNode>; 6415} 6416 6417// FP Comparisons support only S and D element sizes (and H for v8.2a). 6418multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6419 string asm, SDNode OpNode> { 6420 6421 let mayRaiseFPException = 1, Uses = [FPCR] in { 6422 let Predicates = [HasNEON, HasFullFP16] in { 6423 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6424 asm, ".4h", "0.0", 6425 v4i16, v4f16, OpNode>; 6426 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6427 asm, ".8h", "0.0", 6428 v8i16, v8f16, OpNode>; 6429 } // Predicates = [HasNEON, HasFullFP16] 6430 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6431 asm, ".2s", "0.0", 6432 v2i32, v2f32, OpNode>; 6433 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6434 asm, ".4s", "0.0", 6435 v4i32, v4f32, OpNode>; 6436 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6437 asm, ".2d", "0.0", 6438 v2i64, v2f64, OpNode>; 6439 } 6440 6441 let Predicates = [HasNEON, HasFullFP16] in { 6442 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6443 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6444 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6445 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6446 } 6447 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6448 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6449 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6450 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6451 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6452 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6453 let Predicates = [HasNEON, HasFullFP16] in { 6454 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6455 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6456 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6457 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6458 } 6459 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6460 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6461 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6462 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6463 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6464 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6465} 6466 6467let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6468class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6469 RegisterOperand outtype, RegisterOperand intype, 6470 string asm, string VdTy, string VnTy, 6471 list<dag> pattern> 6472 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6473 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6474 Sched<[WriteVq]> { 6475 bits<5> Rd; 6476 bits<5> Rn; 6477 let Inst{31} = 0; 6478 let Inst{30} = Q; 6479 let Inst{29} = U; 6480 let Inst{28-24} = 0b01110; 6481 let Inst{23-22} = size; 6482 let Inst{21-17} = 0b10000; 6483 let Inst{16-12} = opcode; 6484 let Inst{11-10} = 0b10; 6485 let Inst{9-5} = Rn; 6486 let Inst{4-0} = Rd; 6487} 6488 6489let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6490class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6491 RegisterOperand outtype, RegisterOperand intype, 6492 string asm, string VdTy, string VnTy, 6493 list<dag> pattern> 6494 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6495 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6496 Sched<[WriteVq]> { 6497 bits<5> Rd; 6498 bits<5> Rn; 6499 let Inst{31} = 0; 6500 let Inst{30} = Q; 6501 let Inst{29} = U; 6502 let Inst{28-24} = 0b01110; 6503 let Inst{23-22} = size; 6504 let Inst{21-17} = 0b10000; 6505 let Inst{16-12} = opcode; 6506 let Inst{11-10} = 0b10; 6507 let Inst{9-5} = Rn; 6508 let Inst{4-0} = Rd; 6509} 6510 6511multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6512 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6513 asm, ".4s", ".4h", []>; 6514 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6515 asm#"2", ".4s", ".8h", []>; 6516 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6517 asm, ".2d", ".2s", []>; 6518 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6519 asm#"2", ".2d", ".4s", []>; 6520} 6521 6522multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6523 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6524 asm, ".4h", ".4s", []>; 6525 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6526 asm#"2", ".8h", ".4s", []>; 6527 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6528 asm, ".2s", ".2d", []>; 6529 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6530 asm#"2", ".4s", ".2d", []>; 6531} 6532 6533multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6534 Intrinsic OpNode> { 6535 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6536 asm, ".2s", ".2d", 6537 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6538 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6539 asm#"2", ".4s", ".2d", []>; 6540 6541 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6542 (!cast<Instruction>(NAME # "v4f32") 6543 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6544} 6545 6546//---------------------------------------------------------------------------- 6547// AdvSIMD three register different-size vector instructions. 6548//---------------------------------------------------------------------------- 6549 6550let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6551class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6552 RegisterOperand outtype, RegisterOperand intype1, 6553 RegisterOperand intype2, string asm, 6554 string outkind, string inkind1, string inkind2, 6555 list<dag> pattern> 6556 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6557 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6558 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6559 Sched<[WriteVq]> { 6560 bits<5> Rd; 6561 bits<5> Rn; 6562 bits<5> Rm; 6563 let Inst{31} = 0; 6564 let Inst{30} = size{0}; 6565 let Inst{29} = U; 6566 let Inst{28-24} = 0b01110; 6567 let Inst{23-22} = size{2-1}; 6568 let Inst{21} = 1; 6569 let Inst{20-16} = Rm; 6570 let Inst{15-12} = opcode; 6571 let Inst{11-10} = 0b00; 6572 let Inst{9-5} = Rn; 6573 let Inst{4-0} = Rd; 6574} 6575 6576let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6577class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6578 RegisterOperand outtype, RegisterOperand intype1, 6579 RegisterOperand intype2, string asm, 6580 string outkind, string inkind1, string inkind2, 6581 list<dag> pattern> 6582 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6583 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6584 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6585 Sched<[WriteVq]> { 6586 bits<5> Rd; 6587 bits<5> Rn; 6588 bits<5> Rm; 6589 let Inst{31} = 0; 6590 let Inst{30} = size{0}; 6591 let Inst{29} = U; 6592 let Inst{28-24} = 0b01110; 6593 let Inst{23-22} = size{2-1}; 6594 let Inst{21} = 1; 6595 let Inst{20-16} = Rm; 6596 let Inst{15-12} = opcode; 6597 let Inst{11-10} = 0b00; 6598 let Inst{9-5} = Rn; 6599 let Inst{4-0} = Rd; 6600} 6601 6602// FIXME: TableGen doesn't know how to deal with expanded types that also 6603// change the element count (in this case, placing the results in 6604// the high elements of the result register rather than the low 6605// elements). Until that's fixed, we can't code-gen those. 6606multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6607 Intrinsic IntOp> { 6608 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6609 V64, V128, V128, 6610 asm, ".8b", ".8h", ".8h", 6611 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6612 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6613 V128, V128, V128, 6614 asm#"2", ".16b", ".8h", ".8h", 6615 []>; 6616 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6617 V64, V128, V128, 6618 asm, ".4h", ".4s", ".4s", 6619 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6620 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6621 V128, V128, V128, 6622 asm#"2", ".8h", ".4s", ".4s", 6623 []>; 6624 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6625 V64, V128, V128, 6626 asm, ".2s", ".2d", ".2d", 6627 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6628 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6629 V128, V128, V128, 6630 asm#"2", ".4s", ".2d", ".2d", 6631 []>; 6632 6633 6634 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6635 // a version attached to an instruction. 6636 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6637 (v8i16 V128:$Rm))), 6638 (!cast<Instruction>(NAME # "v8i16_v16i8") 6639 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6640 V128:$Rn, V128:$Rm)>; 6641 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6642 (v4i32 V128:$Rm))), 6643 (!cast<Instruction>(NAME # "v4i32_v8i16") 6644 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6645 V128:$Rn, V128:$Rm)>; 6646 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6647 (v2i64 V128:$Rm))), 6648 (!cast<Instruction>(NAME # "v2i64_v4i32") 6649 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6650 V128:$Rn, V128:$Rm)>; 6651} 6652 6653multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6654 SDPatternOperator OpNode> { 6655 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6656 V128, V64, V64, 6657 asm, ".8h", ".8b", ".8b", 6658 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6659 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6660 V128, V128, V128, 6661 asm#"2", ".8h", ".16b", ".16b", []>; 6662 let Predicates = [HasAES] in { 6663 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6664 V128, V64, V64, 6665 asm, ".1q", ".1d", ".1d", 6666 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>; 6667 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6668 V128, V128, V128, 6669 asm#"2", ".1q", ".2d", ".2d", 6670 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)), 6671 (extract_high_v2i64 (v2i64 V128:$Rm))))]>; 6672 } 6673 6674 def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6675 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6676 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6677} 6678 6679multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6680 SDPatternOperator OpNode> { 6681 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6682 V128, V64, V64, 6683 asm, ".4s", ".4h", ".4h", 6684 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6685 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6686 V128, V128, V128, 6687 asm#"2", ".4s", ".8h", ".8h", 6688 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6689 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6690 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6691 V128, V64, V64, 6692 asm, ".2d", ".2s", ".2s", 6693 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6694 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6695 V128, V128, V128, 6696 asm#"2", ".2d", ".4s", ".4s", 6697 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6698 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6699} 6700 6701multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6702 SDPatternOperator OpNode = null_frag> { 6703 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6704 V128, V64, V64, 6705 asm, ".8h", ".8b", ".8b", 6706 [(set (v8i16 V128:$Rd), 6707 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6708 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6709 V128, V128, V128, 6710 asm#"2", ".8h", ".16b", ".16b", 6711 [(set (v8i16 V128:$Rd), 6712 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6713 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 6714 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6715 V128, V64, V64, 6716 asm, ".4s", ".4h", ".4h", 6717 [(set (v4i32 V128:$Rd), 6718 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6719 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6720 V128, V128, V128, 6721 asm#"2", ".4s", ".8h", ".8h", 6722 [(set (v4i32 V128:$Rd), 6723 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6724 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6725 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6726 V128, V64, V64, 6727 asm, ".2d", ".2s", ".2s", 6728 [(set (v2i64 V128:$Rd), 6729 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6730 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6731 V128, V128, V128, 6732 asm#"2", ".2d", ".4s", ".4s", 6733 [(set (v2i64 V128:$Rd), 6734 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6735 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6736} 6737 6738multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6739 string asm, 6740 SDPatternOperator OpNode> { 6741 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6742 V128, V64, V64, 6743 asm, ".8h", ".8b", ".8b", 6744 [(set (v8i16 V128:$dst), 6745 (add (v8i16 V128:$Rd), 6746 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6747 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6748 V128, V128, V128, 6749 asm#"2", ".8h", ".16b", ".16b", 6750 [(set (v8i16 V128:$dst), 6751 (add (v8i16 V128:$Rd), 6752 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6753 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 6754 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6755 V128, V64, V64, 6756 asm, ".4s", ".4h", ".4h", 6757 [(set (v4i32 V128:$dst), 6758 (add (v4i32 V128:$Rd), 6759 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6760 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6761 V128, V128, V128, 6762 asm#"2", ".4s", ".8h", ".8h", 6763 [(set (v4i32 V128:$dst), 6764 (add (v4i32 V128:$Rd), 6765 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6766 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 6767 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6768 V128, V64, V64, 6769 asm, ".2d", ".2s", ".2s", 6770 [(set (v2i64 V128:$dst), 6771 (add (v2i64 V128:$Rd), 6772 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6773 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6774 V128, V128, V128, 6775 asm#"2", ".2d", ".4s", ".4s", 6776 [(set (v2i64 V128:$dst), 6777 (add (v2i64 V128:$Rd), 6778 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6779 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 6780} 6781 6782multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6783 SDPatternOperator OpNode = null_frag> { 6784 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6785 V128, V64, V64, 6786 asm, ".8h", ".8b", ".8b", 6787 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6788 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6789 V128, V128, V128, 6790 asm#"2", ".8h", ".16b", ".16b", 6791 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6792 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6793 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6794 V128, V64, V64, 6795 asm, ".4s", ".4h", ".4h", 6796 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6797 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6798 V128, V128, V128, 6799 asm#"2", ".4s", ".8h", ".8h", 6800 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6801 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6802 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6803 V128, V64, V64, 6804 asm, ".2d", ".2s", ".2s", 6805 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6806 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6807 V128, V128, V128, 6808 asm#"2", ".2d", ".4s", ".4s", 6809 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6810 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6811} 6812 6813multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6814 string asm, 6815 SDPatternOperator OpNode> { 6816 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6817 V128, V64, V64, 6818 asm, ".8h", ".8b", ".8b", 6819 [(set (v8i16 V128:$dst), 6820 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6821 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6822 V128, V128, V128, 6823 asm#"2", ".8h", ".16b", ".16b", 6824 [(set (v8i16 V128:$dst), 6825 (OpNode (v8i16 V128:$Rd), 6826 (extract_high_v16i8 (v16i8 V128:$Rn)), 6827 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6828 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6829 V128, V64, V64, 6830 asm, ".4s", ".4h", ".4h", 6831 [(set (v4i32 V128:$dst), 6832 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6833 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6834 V128, V128, V128, 6835 asm#"2", ".4s", ".8h", ".8h", 6836 [(set (v4i32 V128:$dst), 6837 (OpNode (v4i32 V128:$Rd), 6838 (extract_high_v8i16 (v8i16 V128:$Rn)), 6839 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6840 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6841 V128, V64, V64, 6842 asm, ".2d", ".2s", ".2s", 6843 [(set (v2i64 V128:$dst), 6844 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6845 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6846 V128, V128, V128, 6847 asm#"2", ".2d", ".4s", ".4s", 6848 [(set (v2i64 V128:$dst), 6849 (OpNode (v2i64 V128:$Rd), 6850 (extract_high_v4i32 (v4i32 V128:$Rn)), 6851 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6852} 6853 6854multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6855 SDPatternOperator Accum> { 6856 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6857 V128, V64, V64, 6858 asm, ".4s", ".4h", ".4h", 6859 [(set (v4i32 V128:$dst), 6860 (Accum (v4i32 V128:$Rd), 6861 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6862 (v4i16 V64:$Rm)))))]>; 6863 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6864 V128, V128, V128, 6865 asm#"2", ".4s", ".8h", ".8h", 6866 [(set (v4i32 V128:$dst), 6867 (Accum (v4i32 V128:$Rd), 6868 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 6869 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6870 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6871 V128, V64, V64, 6872 asm, ".2d", ".2s", ".2s", 6873 [(set (v2i64 V128:$dst), 6874 (Accum (v2i64 V128:$Rd), 6875 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6876 (v2i32 V64:$Rm)))))]>; 6877 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6878 V128, V128, V128, 6879 asm#"2", ".2d", ".4s", ".4s", 6880 [(set (v2i64 V128:$dst), 6881 (Accum (v2i64 V128:$Rd), 6882 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 6883 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6884} 6885 6886multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6887 SDPatternOperator OpNode> { 6888 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6889 V128, V128, V64, 6890 asm, ".8h", ".8h", ".8b", 6891 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6892 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6893 V128, V128, V128, 6894 asm#"2", ".8h", ".8h", ".16b", 6895 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6896 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6897 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6898 V128, V128, V64, 6899 asm, ".4s", ".4s", ".4h", 6900 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6901 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6902 V128, V128, V128, 6903 asm#"2", ".4s", ".4s", ".8h", 6904 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6905 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6906 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6907 V128, V128, V64, 6908 asm, ".2d", ".2d", ".2s", 6909 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6910 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6911 V128, V128, V128, 6912 asm#"2", ".2d", ".2d", ".4s", 6913 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6914 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6915} 6916 6917//---------------------------------------------------------------------------- 6918// AdvSIMD bitwise extract from vector 6919//---------------------------------------------------------------------------- 6920 6921class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6922 string asm, string kind> 6923 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6924 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6925 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6926 [(set (vty regtype:$Rd), 6927 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6928 Sched<[!if(size, WriteVq, WriteVd)]> { 6929 bits<5> Rd; 6930 bits<5> Rn; 6931 bits<5> Rm; 6932 bits<4> imm; 6933 let Inst{31} = 0; 6934 let Inst{30} = size; 6935 let Inst{29-21} = 0b101110000; 6936 let Inst{20-16} = Rm; 6937 let Inst{15} = 0; 6938 let Inst{14-11} = imm; 6939 let Inst{10} = 0; 6940 let Inst{9-5} = Rn; 6941 let Inst{4-0} = Rd; 6942} 6943 6944 6945multiclass SIMDBitwiseExtract<string asm> { 6946 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6947 let imm{3} = 0; 6948 } 6949 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6950} 6951 6952//---------------------------------------------------------------------------- 6953// AdvSIMD zip vector 6954//---------------------------------------------------------------------------- 6955 6956class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6957 string asm, string kind, SDNode OpNode, ValueType valty> 6958 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6959 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6960 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6961 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6962 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 6963 bits<5> Rd; 6964 bits<5> Rn; 6965 bits<5> Rm; 6966 let Inst{31} = 0; 6967 let Inst{30} = size{0}; 6968 let Inst{29-24} = 0b001110; 6969 let Inst{23-22} = size{2-1}; 6970 let Inst{21} = 0; 6971 let Inst{20-16} = Rm; 6972 let Inst{15} = 0; 6973 let Inst{14-12} = opc; 6974 let Inst{11-10} = 0b10; 6975 let Inst{9-5} = Rn; 6976 let Inst{4-0} = Rd; 6977} 6978 6979multiclass SIMDZipVector<bits<3>opc, string asm, 6980 SDNode OpNode> { 6981 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6982 asm, ".8b", OpNode, v8i8>; 6983 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6984 asm, ".16b", OpNode, v16i8>; 6985 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6986 asm, ".4h", OpNode, v4i16>; 6987 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6988 asm, ".8h", OpNode, v8i16>; 6989 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6990 asm, ".2s", OpNode, v2i32>; 6991 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6992 asm, ".4s", OpNode, v4i32>; 6993 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6994 asm, ".2d", OpNode, v2i64>; 6995 6996 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6997 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6998 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)), 6999 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7000 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 7001 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7002 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)), 7003 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7004 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 7005 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 7006 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 7007 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 7008 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 7009 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 7010} 7011 7012//---------------------------------------------------------------------------- 7013// AdvSIMD three register scalar instructions 7014//---------------------------------------------------------------------------- 7015 7016let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7017class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 7018 RegisterClass regtype, string asm, 7019 list<dag> pattern> 7020 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7021 "\t$Rd, $Rn, $Rm", "", pattern>, 7022 Sched<[WriteVd]> { 7023 bits<5> Rd; 7024 bits<5> Rn; 7025 bits<5> Rm; 7026 let Inst{31-30} = 0b01; 7027 let Inst{29} = U; 7028 let Inst{28-24} = 0b11110; 7029 let Inst{23-21} = size; 7030 let Inst{20-16} = Rm; 7031 let Inst{15-11} = opcode; 7032 let Inst{10} = 1; 7033 let Inst{9-5} = Rn; 7034 let Inst{4-0} = Rd; 7035} 7036 7037let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7038class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 7039 dag oops, dag iops, string asm, 7040 list<dag> pattern> 7041 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 7042 Sched<[WriteVd]> { 7043 bits<5> Rd; 7044 bits<5> Rn; 7045 bits<5> Rm; 7046 let Inst{31-30} = 0b01; 7047 let Inst{29} = U; 7048 let Inst{28-24} = 0b11110; 7049 let Inst{23-22} = size; 7050 let Inst{21} = R; 7051 let Inst{20-16} = Rm; 7052 let Inst{15-11} = opcode; 7053 let Inst{10} = 1; 7054 let Inst{9-5} = Rn; 7055 let Inst{4-0} = Rd; 7056} 7057 7058multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 7059 SDPatternOperator OpNode> { 7060 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7061 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7062} 7063 7064multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 7065 SDPatternOperator OpNode> { 7066 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7067 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7068 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 7069 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7070 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 7071 7072 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 7073 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 7074 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 7075 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 7076} 7077 7078multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 7079 SDPatternOperator OpNode> { 7080 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 7081 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7082 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7083} 7084 7085multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 7086 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 7087 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 7088 asm, []>; 7089 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 7090 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 7091 asm, []>; 7092} 7093 7094multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 7095 SDPatternOperator OpNode = null_frag, 7096 Predicate pred = HasNEON> { 7097 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7098 let Predicates = [pred] in { 7099 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7100 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7101 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7102 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7103 } 7104 let Predicates = [pred, HasFullFP16] in { 7105 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7106 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 7107 } 7108 } 7109 7110 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7111 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7112} 7113 7114multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 7115 SDPatternOperator OpNode = null_frag> { 7116 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7117 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7118 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7119 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7120 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 7121 let Predicates = [HasNEON, HasFullFP16] in { 7122 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7123 []>; 7124 } // Predicates = [HasNEON, HasFullFP16] 7125 } 7126 7127 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7128 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7129} 7130 7131class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 7132 dag oops, dag iops, string asm, string cstr, list<dag> pat> 7133 : I<oops, iops, asm, 7134 "\t$Rd, $Rn, $Rm", cstr, pat>, 7135 Sched<[WriteVd]> { 7136 bits<5> Rd; 7137 bits<5> Rn; 7138 bits<5> Rm; 7139 let Inst{31-30} = 0b01; 7140 let Inst{29} = U; 7141 let Inst{28-24} = 0b11110; 7142 let Inst{23-22} = size; 7143 let Inst{21} = 1; 7144 let Inst{20-16} = Rm; 7145 let Inst{15-11} = opcode; 7146 let Inst{10} = 0; 7147 let Inst{9-5} = Rn; 7148 let Inst{4-0} = Rd; 7149} 7150 7151let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7152multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 7153 SDPatternOperator OpNode = null_frag> { 7154 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7155 (outs FPR32:$Rd), 7156 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7157 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7158 (outs FPR64:$Rd), 7159 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7160 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7161} 7162 7163let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7164multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7165 SDPatternOperator OpNode = null_frag> { 7166 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7167 (outs FPR32:$dst), 7168 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7169 asm, "$Rd = $dst", []>; 7170 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7171 (outs FPR64:$dst), 7172 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7173 asm, "$Rd = $dst", 7174 [(set (i64 FPR64:$dst), 7175 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7176} 7177 7178//---------------------------------------------------------------------------- 7179// AdvSIMD two register scalar instructions 7180//---------------------------------------------------------------------------- 7181 7182let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7183class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7184 RegisterClass regtype, RegisterClass regtype2, 7185 string asm, list<dag> pat> 7186 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7187 "\t$Rd, $Rn", "", pat>, 7188 Sched<[WriteVd]> { 7189 bits<5> Rd; 7190 bits<5> Rn; 7191 let Inst{31-30} = 0b01; 7192 let Inst{29} = U; 7193 let Inst{28-24} = 0b11110; 7194 let Inst{23-22} = size; 7195 let Inst{21} = 0b1; 7196 let Inst{20-19} = size2; 7197 let Inst{18-17} = 0b00; 7198 let Inst{16-12} = opcode; 7199 let Inst{11-10} = 0b10; 7200 let Inst{9-5} = Rn; 7201 let Inst{4-0} = Rd; 7202} 7203 7204let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7205class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7206 RegisterClass regtype, RegisterClass regtype2, 7207 string asm, list<dag> pat> 7208 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7209 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7210 Sched<[WriteVd]> { 7211 bits<5> Rd; 7212 bits<5> Rn; 7213 let Inst{31-30} = 0b01; 7214 let Inst{29} = U; 7215 let Inst{28-24} = 0b11110; 7216 let Inst{23-22} = size; 7217 let Inst{21-17} = 0b10000; 7218 let Inst{16-12} = opcode; 7219 let Inst{11-10} = 0b10; 7220 let Inst{9-5} = Rn; 7221 let Inst{4-0} = Rd; 7222} 7223 7224 7225let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7226class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7227 RegisterClass regtype, string asm, string zero> 7228 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7229 "\t$Rd, $Rn, #" # zero, "", []>, 7230 Sched<[WriteVd]> { 7231 bits<5> Rd; 7232 bits<5> Rn; 7233 let Inst{31-30} = 0b01; 7234 let Inst{29} = U; 7235 let Inst{28-24} = 0b11110; 7236 let Inst{23-22} = size; 7237 let Inst{21} = 0b1; 7238 let Inst{20-19} = size2; 7239 let Inst{18-17} = 0b00; 7240 let Inst{16-12} = opcode; 7241 let Inst{11-10} = 0b10; 7242 let Inst{9-5} = Rn; 7243 let Inst{4-0} = Rd; 7244} 7245 7246let mayRaiseFPException = 1, Uses = [FPCR] in 7247class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7248 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7249 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7250 Sched<[WriteVd]> { 7251 bits<5> Rd; 7252 bits<5> Rn; 7253 let Inst{31-17} = 0b011111100110000; 7254 let Inst{16-12} = opcode; 7255 let Inst{11-10} = 0b10; 7256 let Inst{9-5} = Rn; 7257 let Inst{4-0} = Rd; 7258} 7259 7260multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7261 SDPatternOperator OpNode> { 7262 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7263 7264 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7265 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7266} 7267 7268multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7269 SDPatternOperator OpNode> { 7270 let mayRaiseFPException = 1, Uses = [FPCR] in { 7271 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7272 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7273 let Predicates = [HasNEON, HasFullFP16] in { 7274 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7275 } 7276 } 7277 7278 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7279 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7280 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7281 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7282 let Predicates = [HasNEON, HasFullFP16] in { 7283 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7284 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7285 } 7286 7287 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7288 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7289} 7290 7291multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7292 SDPatternOperator OpNode = null_frag, 7293 list<Predicate> preds = []> { 7294 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7295 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7296 7297 let Predicates = preds in { 7298 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7299 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7300 } 7301} 7302 7303let mayRaiseFPException = 1, Uses = [FPCR] in 7304multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7305 Predicate pred = HasNEON> { 7306 let Predicates = [pred] in { 7307 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7308 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7309 } 7310 let Predicates = [pred, HasFullFP16] in { 7311 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7312 } 7313} 7314 7315let mayRaiseFPException = 1, Uses = [FPCR] in 7316multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7317 SDPatternOperator OpNode> { 7318 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7319 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7320 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7321 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7322 let Predicates = [HasNEON, HasFullFP16] in { 7323 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7324 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7325 } 7326} 7327 7328multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7329 SDPatternOperator OpNode = null_frag> { 7330 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7331 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7332 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7333 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7334 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7335 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7336 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7337 } 7338 7339 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7340 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7341} 7342 7343multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7344 Intrinsic OpNode> { 7345 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7346 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7347 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7348 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7349 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7350 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7351 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7352 } 7353 7354 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7355 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7356} 7357 7358 7359 7360let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7361multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7362 SDPatternOperator OpNode = null_frag> { 7363 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7364 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>; 7365 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7366 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7367} 7368 7369//---------------------------------------------------------------------------- 7370// AdvSIMD scalar pairwise instructions 7371//---------------------------------------------------------------------------- 7372 7373let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7374class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7375 RegisterOperand regtype, RegisterOperand vectype, 7376 string asm, string kind> 7377 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7378 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7379 Sched<[WriteVd]> { 7380 bits<5> Rd; 7381 bits<5> Rn; 7382 let Inst{31-30} = 0b01; 7383 let Inst{29} = U; 7384 let Inst{28-24} = 0b11110; 7385 let Inst{23-22} = size; 7386 let Inst{21-17} = 0b11000; 7387 let Inst{16-12} = opcode; 7388 let Inst{11-10} = 0b10; 7389 let Inst{9-5} = Rn; 7390 let Inst{4-0} = Rd; 7391} 7392 7393multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7394 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7395 asm, ".2d">; 7396} 7397 7398let mayRaiseFPException = 1, Uses = [FPCR] in 7399multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7400 let Predicates = [HasNEON, HasFullFP16] in { 7401 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7402 asm, ".2h">; 7403 } 7404 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7405 asm, ".2s">; 7406 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7407 asm, ".2d">; 7408} 7409 7410//---------------------------------------------------------------------------- 7411// AdvSIMD across lanes instructions 7412//---------------------------------------------------------------------------- 7413 7414let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7415class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7416 RegisterClass regtype, RegisterOperand vectype, 7417 string asm, string kind, list<dag> pattern> 7418 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7419 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7420 Sched<[!if(Q, WriteVq, WriteVd)]> { 7421 bits<5> Rd; 7422 bits<5> Rn; 7423 let Inst{31} = 0; 7424 let Inst{30} = Q; 7425 let Inst{29} = U; 7426 let Inst{28-24} = 0b01110; 7427 let Inst{23-22} = size; 7428 let Inst{21-17} = 0b11000; 7429 let Inst{16-12} = opcode; 7430 let Inst{11-10} = 0b10; 7431 let Inst{9-5} = Rn; 7432 let Inst{4-0} = Rd; 7433} 7434 7435multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7436 string asm> { 7437 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7438 asm, ".8b", []>; 7439 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7440 asm, ".16b", []>; 7441 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7442 asm, ".4h", []>; 7443 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7444 asm, ".8h", []>; 7445 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7446 asm, ".4s", []>; 7447} 7448 7449multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7450 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7451 asm, ".8b", []>; 7452 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7453 asm, ".16b", []>; 7454 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7455 asm, ".4h", []>; 7456 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7457 asm, ".8h", []>; 7458 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7459 asm, ".4s", []>; 7460} 7461 7462let mayRaiseFPException = 1, Uses = [FPCR] in 7463multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7464 Intrinsic intOp> { 7465 let Predicates = [HasNEON, HasFullFP16] in { 7466 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7467 asm, ".4h", 7468 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7469 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7470 asm, ".8h", 7471 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7472 } // Predicates = [HasNEON, HasFullFP16] 7473 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7474 asm, ".4s", 7475 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7476} 7477 7478//---------------------------------------------------------------------------- 7479// AdvSIMD INS/DUP instructions 7480//---------------------------------------------------------------------------- 7481 7482// FIXME: There has got to be a better way to factor these. ugh. 7483 7484class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7485 string operands, string constraints, list<dag> pattern> 7486 : I<outs, ins, asm, operands, constraints, pattern>, 7487 Sched<[!if(Q, WriteVq, WriteVd)]> { 7488 bits<5> Rd; 7489 bits<5> Rn; 7490 let Inst{31} = 0; 7491 let Inst{30} = Q; 7492 let Inst{29} = op; 7493 let Inst{28-21} = 0b01110000; 7494 let Inst{15} = 0; 7495 let Inst{10} = 1; 7496 let Inst{9-5} = Rn; 7497 let Inst{4-0} = Rd; 7498} 7499 7500class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7501 RegisterOperand vecreg, RegisterClass regtype> 7502 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7503 "{\t$Rd" # size # ", $Rn" # 7504 "|" # size # "\t$Rd, $Rn}", "", 7505 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7506 let Inst{20-16} = imm5; 7507 let Inst{14-11} = 0b0001; 7508} 7509 7510class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7511 ValueType vectype, ValueType insreg, 7512 RegisterOperand vecreg, Operand idxtype, 7513 SDNode OpNode> 7514 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7515 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7516 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7517 [(set (vectype vecreg:$Rd), 7518 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7519 let Inst{14-11} = 0b0000; 7520} 7521 7522class SIMDDup64FromElement 7523 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7524 VectorIndexD, AArch64duplane64> { 7525 bits<1> idx; 7526 let Inst{20} = idx; 7527 let Inst{19-16} = 0b1000; 7528} 7529 7530class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7531 RegisterOperand vecreg> 7532 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7533 VectorIndexS, AArch64duplane32> { 7534 bits<2> idx; 7535 let Inst{20-19} = idx; 7536 let Inst{18-16} = 0b100; 7537} 7538 7539class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7540 RegisterOperand vecreg> 7541 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7542 VectorIndexH, AArch64duplane16> { 7543 bits<3> idx; 7544 let Inst{20-18} = idx; 7545 let Inst{17-16} = 0b10; 7546} 7547 7548class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7549 RegisterOperand vecreg> 7550 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7551 VectorIndexB, AArch64duplane8> { 7552 bits<4> idx; 7553 let Inst{20-17} = idx; 7554 let Inst{16} = 1; 7555} 7556 7557class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7558 Operand idxtype, string asm, list<dag> pattern> 7559 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7560 "{\t$Rd, $Rn" # size # "$idx" # 7561 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7562 let Inst{14-11} = imm4; 7563} 7564 7565class SIMDSMov<bit Q, string size, RegisterClass regtype, 7566 Operand idxtype> 7567 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7568class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7569 Operand idxtype> 7570 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7571 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7572 7573class SIMDMovAlias<string asm, string size, Instruction inst, 7574 RegisterClass regtype, Operand idxtype> 7575 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7576 "|" # size # "\t$dst, $src$idx}", 7577 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7578 7579multiclass SMov { 7580 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7581 // streaming mode. 7582 let Predicates = [HasNEONorSME] in { 7583 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7584 let Inst{20-16} = 0b00001; 7585 } 7586 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7587 let Inst{20-16} = 0b00001; 7588 } 7589 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7590 let Inst{20-16} = 0b00010; 7591 } 7592 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7593 let Inst{20-16} = 0b00010; 7594 } 7595 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7596 let Inst{20-16} = 0b00100; 7597 } 7598 } 7599 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7600 bits<4> idx; 7601 let Inst{20-17} = idx; 7602 let Inst{16} = 1; 7603 } 7604 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7605 bits<4> idx; 7606 let Inst{20-17} = idx; 7607 let Inst{16} = 1; 7608 } 7609 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7610 bits<3> idx; 7611 let Inst{20-18} = idx; 7612 let Inst{17-16} = 0b10; 7613 } 7614 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7615 bits<3> idx; 7616 let Inst{20-18} = idx; 7617 let Inst{17-16} = 0b10; 7618 } 7619 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7620 bits<2> idx; 7621 let Inst{20-19} = idx; 7622 let Inst{18-16} = 0b100; 7623 } 7624} 7625 7626multiclass UMov { 7627 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7628 // streaming mode. 7629 let Predicates = [HasNEONorSME] in { 7630 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7631 let Inst{20-16} = 0b00001; 7632 } 7633 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7634 let Inst{20-16} = 0b00010; 7635 } 7636 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7637 let Inst{20-16} = 0b00100; 7638 } 7639 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7640 let Inst{20-16} = 0b01000; 7641 } 7642 def : SIMDMovAlias<"mov", ".s", 7643 !cast<Instruction>(NAME # vi32_idx0), 7644 GPR32, VectorIndex0>; 7645 def : SIMDMovAlias<"mov", ".d", 7646 !cast<Instruction>(NAME # vi64_idx0), 7647 GPR64, VectorIndex0>; 7648 } 7649 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7650 bits<4> idx; 7651 let Inst{20-17} = idx; 7652 let Inst{16} = 1; 7653 } 7654 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7655 bits<3> idx; 7656 let Inst{20-18} = idx; 7657 let Inst{17-16} = 0b10; 7658 } 7659 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7660 bits<2> idx; 7661 let Inst{20-19} = idx; 7662 let Inst{18-16} = 0b100; 7663 } 7664 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7665 bits<1> idx; 7666 let Inst{20} = idx; 7667 let Inst{19-16} = 0b1000; 7668 } 7669 def : SIMDMovAlias<"mov", ".s", 7670 !cast<Instruction>(NAME#"vi32"), 7671 GPR32, VectorIndexS>; 7672 def : SIMDMovAlias<"mov", ".d", 7673 !cast<Instruction>(NAME#"vi64"), 7674 GPR64, VectorIndexD>; 7675} 7676 7677class SIMDInsFromMain<string size, ValueType vectype, 7678 RegisterClass regtype, Operand idxtype> 7679 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7680 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7681 "{\t$Rd" # size # "$idx, $Rn" # 7682 "|" # size # "\t$Rd$idx, $Rn}", 7683 "$Rd = $dst", 7684 [(set V128:$dst, 7685 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7686 let Inst{14-11} = 0b0011; 7687} 7688 7689class SIMDInsFromElement<string size, ValueType vectype, 7690 ValueType elttype, Operand idxtype> 7691 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7692 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7693 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7694 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7695 "$Rd = $dst", 7696 [(set V128:$dst, 7697 (vector_insert 7698 (vectype V128:$Rd), 7699 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7700 idxtype:$idx))]>; 7701 7702class SIMDInsMainMovAlias<string size, Instruction inst, 7703 RegisterClass regtype, Operand idxtype> 7704 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7705 "|" # size #"\t$dst$idx, $src}", 7706 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7707class SIMDInsElementMovAlias<string size, Instruction inst, 7708 Operand idxtype> 7709 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7710 # "|" # size #"\t$dst$idx, $src$idx2}", 7711 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7712 7713 7714multiclass SIMDIns { 7715 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7716 bits<4> idx; 7717 let Inst{20-17} = idx; 7718 let Inst{16} = 1; 7719 } 7720 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7721 bits<3> idx; 7722 let Inst{20-18} = idx; 7723 let Inst{17-16} = 0b10; 7724 } 7725 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7726 bits<2> idx; 7727 let Inst{20-19} = idx; 7728 let Inst{18-16} = 0b100; 7729 } 7730 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7731 bits<1> idx; 7732 let Inst{20} = idx; 7733 let Inst{19-16} = 0b1000; 7734 } 7735 7736 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7737 bits<4> idx; 7738 bits<4> idx2; 7739 let Inst{20-17} = idx; 7740 let Inst{16} = 1; 7741 let Inst{14-11} = idx2; 7742 } 7743 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7744 bits<3> idx; 7745 bits<3> idx2; 7746 let Inst{20-18} = idx; 7747 let Inst{17-16} = 0b10; 7748 let Inst{14-12} = idx2; 7749 let Inst{11} = {?}; 7750 } 7751 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7752 bits<2> idx; 7753 bits<2> idx2; 7754 let Inst{20-19} = idx; 7755 let Inst{18-16} = 0b100; 7756 let Inst{14-13} = idx2; 7757 let Inst{12-11} = {?,?}; 7758 } 7759 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7760 bits<1> idx; 7761 bits<1> idx2; 7762 let Inst{20} = idx; 7763 let Inst{19-16} = 0b1000; 7764 let Inst{14} = idx2; 7765 let Inst{13-11} = {?,?,?}; 7766 } 7767 7768 // For all forms of the INS instruction, the "mov" mnemonic is the 7769 // preferred alias. Why they didn't just call the instruction "mov" in 7770 // the first place is a very good question indeed... 7771 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7772 GPR32, VectorIndexB>; 7773 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7774 GPR32, VectorIndexH>; 7775 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7776 GPR32, VectorIndexS>; 7777 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7778 GPR64, VectorIndexD>; 7779 7780 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7781 VectorIndexB>; 7782 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7783 VectorIndexH>; 7784 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7785 VectorIndexS>; 7786 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7787 VectorIndexD>; 7788} 7789 7790//---------------------------------------------------------------------------- 7791// AdvSIMD TBL/TBX 7792//---------------------------------------------------------------------------- 7793 7794let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7795class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7796 RegisterOperand listtype, string asm, string kind> 7797 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7798 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7799 Sched<[!if(Q, WriteVq, WriteVd)]> { 7800 bits<5> Vd; 7801 bits<5> Vn; 7802 bits<5> Vm; 7803 let Inst{31} = 0; 7804 let Inst{30} = Q; 7805 let Inst{29-21} = 0b001110000; 7806 let Inst{20-16} = Vm; 7807 let Inst{15} = 0; 7808 let Inst{14-13} = len; 7809 let Inst{12} = op; 7810 let Inst{11-10} = 0b00; 7811 let Inst{9-5} = Vn; 7812 let Inst{4-0} = Vd; 7813} 7814 7815let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7816class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7817 RegisterOperand listtype, string asm, string kind> 7818 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7819 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7820 Sched<[!if(Q, WriteVq, WriteVd)]> { 7821 bits<5> Vd; 7822 bits<5> Vn; 7823 bits<5> Vm; 7824 let Inst{31} = 0; 7825 let Inst{30} = Q; 7826 let Inst{29-21} = 0b001110000; 7827 let Inst{20-16} = Vm; 7828 let Inst{15} = 0; 7829 let Inst{14-13} = len; 7830 let Inst{12} = op; 7831 let Inst{11-10} = 0b00; 7832 let Inst{9-5} = Vn; 7833 let Inst{4-0} = Vd; 7834} 7835 7836class SIMDTableLookupAlias<string asm, Instruction inst, 7837 RegisterOperand vectype, RegisterOperand listtype> 7838 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7839 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7840 7841multiclass SIMDTableLookup<bit op, string asm> { 7842 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7843 asm, ".8b">; 7844 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7845 asm, ".8b">; 7846 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7847 asm, ".8b">; 7848 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7849 asm, ".8b">; 7850 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7851 asm, ".16b">; 7852 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7853 asm, ".16b">; 7854 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7855 asm, ".16b">; 7856 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7857 asm, ".16b">; 7858 7859 def : SIMDTableLookupAlias<asm # ".8b", 7860 !cast<Instruction>(NAME#"v8i8One"), 7861 V64, VecListOne128>; 7862 def : SIMDTableLookupAlias<asm # ".8b", 7863 !cast<Instruction>(NAME#"v8i8Two"), 7864 V64, VecListTwo128>; 7865 def : SIMDTableLookupAlias<asm # ".8b", 7866 !cast<Instruction>(NAME#"v8i8Three"), 7867 V64, VecListThree128>; 7868 def : SIMDTableLookupAlias<asm # ".8b", 7869 !cast<Instruction>(NAME#"v8i8Four"), 7870 V64, VecListFour128>; 7871 def : SIMDTableLookupAlias<asm # ".16b", 7872 !cast<Instruction>(NAME#"v16i8One"), 7873 V128, VecListOne128>; 7874 def : SIMDTableLookupAlias<asm # ".16b", 7875 !cast<Instruction>(NAME#"v16i8Two"), 7876 V128, VecListTwo128>; 7877 def : SIMDTableLookupAlias<asm # ".16b", 7878 !cast<Instruction>(NAME#"v16i8Three"), 7879 V128, VecListThree128>; 7880 def : SIMDTableLookupAlias<asm # ".16b", 7881 !cast<Instruction>(NAME#"v16i8Four"), 7882 V128, VecListFour128>; 7883} 7884 7885multiclass SIMDTableLookupTied<bit op, string asm> { 7886 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7887 asm, ".8b">; 7888 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7889 asm, ".8b">; 7890 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7891 asm, ".8b">; 7892 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7893 asm, ".8b">; 7894 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7895 asm, ".16b">; 7896 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7897 asm, ".16b">; 7898 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7899 asm, ".16b">; 7900 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7901 asm, ".16b">; 7902 7903 def : SIMDTableLookupAlias<asm # ".8b", 7904 !cast<Instruction>(NAME#"v8i8One"), 7905 V64, VecListOne128>; 7906 def : SIMDTableLookupAlias<asm # ".8b", 7907 !cast<Instruction>(NAME#"v8i8Two"), 7908 V64, VecListTwo128>; 7909 def : SIMDTableLookupAlias<asm # ".8b", 7910 !cast<Instruction>(NAME#"v8i8Three"), 7911 V64, VecListThree128>; 7912 def : SIMDTableLookupAlias<asm # ".8b", 7913 !cast<Instruction>(NAME#"v8i8Four"), 7914 V64, VecListFour128>; 7915 def : SIMDTableLookupAlias<asm # ".16b", 7916 !cast<Instruction>(NAME#"v16i8One"), 7917 V128, VecListOne128>; 7918 def : SIMDTableLookupAlias<asm # ".16b", 7919 !cast<Instruction>(NAME#"v16i8Two"), 7920 V128, VecListTwo128>; 7921 def : SIMDTableLookupAlias<asm # ".16b", 7922 !cast<Instruction>(NAME#"v16i8Three"), 7923 V128, VecListThree128>; 7924 def : SIMDTableLookupAlias<asm # ".16b", 7925 !cast<Instruction>(NAME#"v16i8Four"), 7926 V128, VecListFour128>; 7927} 7928 7929 7930//---------------------------------------------------------------------------- 7931// AdvSIMD scalar DUP 7932//---------------------------------------------------------------------------- 7933let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7934class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 7935 string asm, string kind, Operand idxtype> 7936 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 7937 "{\t$dst, $src" # kind # "$idx" # 7938 "|\t$dst, $src$idx}", "", []>, 7939 Sched<[WriteVd]> { 7940 bits<5> dst; 7941 bits<5> src; 7942 let Inst{31-21} = 0b01011110000; 7943 let Inst{15-10} = 0b000001; 7944 let Inst{9-5} = src; 7945 let Inst{4-0} = dst; 7946} 7947 7948class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 7949 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7950 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7951 # "|\t$dst, $src$index}", 7952 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7953 7954 7955multiclass SIMDScalarDUP<string asm> { 7956 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 7957 bits<4> idx; 7958 let Inst{20-17} = idx; 7959 let Inst{16} = 1; 7960 } 7961 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 7962 bits<3> idx; 7963 let Inst{20-18} = idx; 7964 let Inst{17-16} = 0b10; 7965 } 7966 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 7967 bits<2> idx; 7968 let Inst{20-19} = idx; 7969 let Inst{18-16} = 0b100; 7970 } 7971 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 7972 bits<1> idx; 7973 let Inst{20} = idx; 7974 let Inst{19-16} = 0b1000; 7975 } 7976 7977 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7978 VectorIndexD:$idx)))), 7979 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7980 7981 // 'DUP' mnemonic aliases. 7982 def : SIMDScalarDUPAlias<"dup", ".b", 7983 !cast<Instruction>(NAME#"i8"), 7984 FPR8, V128, VectorIndexB>; 7985 def : SIMDScalarDUPAlias<"dup", ".h", 7986 !cast<Instruction>(NAME#"i16"), 7987 FPR16, V128, VectorIndexH>; 7988 def : SIMDScalarDUPAlias<"dup", ".s", 7989 !cast<Instruction>(NAME#"i32"), 7990 FPR32, V128, VectorIndexS>; 7991 def : SIMDScalarDUPAlias<"dup", ".d", 7992 !cast<Instruction>(NAME#"i64"), 7993 FPR64, V128, VectorIndexD>; 7994} 7995 7996//---------------------------------------------------------------------------- 7997// AdvSIMD modified immediate instructions 7998//---------------------------------------------------------------------------- 7999 8000class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 8001 string asm, string op_string, 8002 string cstr, list<dag> pattern> 8003 : I<oops, iops, asm, op_string, cstr, pattern>, 8004 Sched<[!if(Q, WriteVq, WriteVd)]> { 8005 bits<5> Rd; 8006 bits<8> imm8; 8007 let Inst{31} = 0; 8008 let Inst{30} = Q; 8009 let Inst{29} = op; 8010 let Inst{28-19} = 0b0111100000; 8011 let Inst{18-16} = imm8{7-5}; 8012 let Inst{11} = op2; 8013 let Inst{10} = 1; 8014 let Inst{9-5} = imm8{4-0}; 8015 let Inst{4-0} = Rd; 8016} 8017 8018class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 8019 Operand immtype, dag opt_shift_iop, 8020 string opt_shift, string asm, string kind, 8021 list<dag> pattern> 8022 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 8023 !con((ins immtype:$imm8), opt_shift_iop), asm, 8024 "{\t$Rd" # kind # ", $imm8" # opt_shift # 8025 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8026 "", pattern> { 8027 let DecoderMethod = "DecodeModImmInstruction"; 8028} 8029 8030class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 8031 Operand immtype, dag opt_shift_iop, 8032 string opt_shift, string asm, string kind, 8033 list<dag> pattern> 8034 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 8035 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 8036 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 8037 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8038 "$Rd = $dst", pattern> { 8039 let DecoderMethod = "DecodeModImmTiedInstruction"; 8040} 8041 8042class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 8043 RegisterOperand vectype, string asm, 8044 string kind, list<dag> pattern> 8045 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8046 (ins logical_vec_shift:$shift), 8047 "$shift", asm, kind, pattern> { 8048 bits<2> shift; 8049 let Inst{15} = b15_b12{1}; 8050 let Inst{14-13} = shift; 8051 let Inst{12} = b15_b12{0}; 8052} 8053 8054class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 8055 RegisterOperand vectype, string asm, 8056 string kind, list<dag> pattern> 8057 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8058 (ins logical_vec_shift:$shift), 8059 "$shift", asm, kind, pattern> { 8060 bits<2> shift; 8061 let Inst{15} = b15_b12{1}; 8062 let Inst{14-13} = shift; 8063 let Inst{12} = b15_b12{0}; 8064} 8065 8066 8067class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 8068 RegisterOperand vectype, string asm, 8069 string kind, list<dag> pattern> 8070 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8071 (ins logical_vec_hw_shift:$shift), 8072 "$shift", asm, kind, pattern> { 8073 bits<2> shift; 8074 let Inst{15} = b15_b12{1}; 8075 let Inst{14} = 0; 8076 let Inst{13} = shift{0}; 8077 let Inst{12} = b15_b12{0}; 8078} 8079 8080class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 8081 RegisterOperand vectype, string asm, 8082 string kind, list<dag> pattern> 8083 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8084 (ins logical_vec_hw_shift:$shift), 8085 "$shift", asm, kind, pattern> { 8086 bits<2> shift; 8087 let Inst{15} = b15_b12{1}; 8088 let Inst{14} = 0; 8089 let Inst{13} = shift{0}; 8090 let Inst{12} = b15_b12{0}; 8091} 8092 8093multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 8094 string asm> { 8095 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 8096 asm, ".4h", []>; 8097 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 8098 asm, ".8h", []>; 8099 8100 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 8101 asm, ".2s", []>; 8102 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 8103 asm, ".4s", []>; 8104} 8105 8106multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 8107 bits<2> w_cmode, string asm, 8108 SDNode OpNode> { 8109 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 8110 asm, ".4h", 8111 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 8112 imm0_255:$imm8, 8113 (i32 imm:$shift)))]>; 8114 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 8115 asm, ".8h", 8116 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 8117 imm0_255:$imm8, 8118 (i32 imm:$shift)))]>; 8119 8120 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 8121 asm, ".2s", 8122 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 8123 imm0_255:$imm8, 8124 (i32 imm:$shift)))]>; 8125 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 8126 asm, ".4s", 8127 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 8128 imm0_255:$imm8, 8129 (i32 imm:$shift)))]>; 8130} 8131 8132class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 8133 RegisterOperand vectype, string asm, 8134 string kind, list<dag> pattern> 8135 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8136 (ins move_vec_shift:$shift), 8137 "$shift", asm, kind, pattern> { 8138 bits<1> shift; 8139 let Inst{15-13} = cmode{3-1}; 8140 let Inst{12} = shift; 8141} 8142 8143class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 8144 RegisterOperand vectype, 8145 Operand imm_type, string asm, 8146 string kind, list<dag> pattern> 8147 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 8148 asm, kind, pattern> { 8149 let Inst{15-12} = cmode; 8150} 8151 8152class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 8153 list<dag> pattern> 8154 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 8155 "\t$Rd, $imm8", "", pattern> { 8156 let Inst{15-12} = cmode; 8157 let DecoderMethod = "DecodeModImmInstruction"; 8158} 8159 8160//---------------------------------------------------------------------------- 8161// AdvSIMD indexed element 8162//---------------------------------------------------------------------------- 8163 8164let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8165class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8166 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8167 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8168 string apple_kind, string dst_kind, string lhs_kind, 8169 string rhs_kind, list<dag> pattern> 8170 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8171 asm, 8172 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8173 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8174 Sched<[WriteVd]> { 8175 bits<5> Rd; 8176 bits<5> Rn; 8177 bits<5> Rm; 8178 8179 let Inst{31} = 0; 8180 let Inst{30} = Q; 8181 let Inst{29} = U; 8182 let Inst{28} = Scalar; 8183 let Inst{27-24} = 0b1111; 8184 let Inst{23-22} = size; 8185 // Bit 21 must be set by the derived class. 8186 let Inst{20-16} = Rm; 8187 let Inst{15-12} = opc; 8188 // Bit 11 must be set by the derived class. 8189 let Inst{10} = 0; 8190 let Inst{9-5} = Rn; 8191 let Inst{4-0} = Rd; 8192} 8193 8194let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8195class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8196 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8197 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8198 string apple_kind, string dst_kind, string lhs_kind, 8199 string rhs_kind, list<dag> pattern> 8200 : I<(outs dst_reg:$dst), 8201 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8202 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8203 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8204 Sched<[WriteVd]> { 8205 bits<5> Rd; 8206 bits<5> Rn; 8207 bits<5> Rm; 8208 8209 let Inst{31} = 0; 8210 let Inst{30} = Q; 8211 let Inst{29} = U; 8212 let Inst{28} = Scalar; 8213 let Inst{27-24} = 0b1111; 8214 let Inst{23-22} = size; 8215 // Bit 21 must be set by the derived class. 8216 let Inst{20-16} = Rm; 8217 let Inst{15-12} = opc; 8218 // Bit 11 must be set by the derived class. 8219 let Inst{10} = 0; 8220 let Inst{9-5} = Rn; 8221 let Inst{4-0} = Rd; 8222} 8223 8224 8225//---------------------------------------------------------------------------- 8226// Armv8.6 BFloat16 Extension 8227//---------------------------------------------------------------------------- 8228let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8229 8230class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8231 string kind2, RegisterOperand RegType, 8232 ValueType AccumType, ValueType InputType> 8233 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8234 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8235 (InputType RegType:$Rn), 8236 (InputType RegType:$Rm)))]> { 8237 let AsmString = !strconcat(asm, 8238 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8239 ", $Rm" # kind2 # "}"); 8240} 8241 8242multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8243 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8244 v2f32, v4bf16>; 8245 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8246 v4f32, v8bf16>; 8247} 8248 8249class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8250 string dst_kind, string lhs_kind, 8251 string rhs_kind, 8252 RegisterOperand RegType, 8253 ValueType AccumType, 8254 ValueType InputType> 8255 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8256 RegType, RegType, V128, VectorIndexS, 8257 asm, "", dst_kind, lhs_kind, rhs_kind, 8258 [(set (AccumType RegType:$dst), 8259 (AccumType (int_aarch64_neon_bfdot 8260 (AccumType RegType:$Rd), 8261 (InputType RegType:$Rn), 8262 (InputType (bitconvert (AccumType 8263 (AArch64duplane32 (v4f32 V128:$Rm), 8264 VectorIndexS:$idx)))))))]> { 8265 8266 bits<2> idx; 8267 let Inst{21} = idx{0}; // L 8268 let Inst{11} = idx{1}; // H 8269} 8270 8271multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8272 8273 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8274 ".2h", V64, v2f32, v4bf16>; 8275 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8276 ".2h", V128, v4f32, v8bf16>; 8277} 8278 8279let mayRaiseFPException = 1, Uses = [FPCR] in 8280class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8281 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8282 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8283 (v8bf16 V128:$Rn), 8284 (v8bf16 V128:$Rm)))]> { 8285 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8286} 8287 8288let mayRaiseFPException = 1, Uses = [FPCR] in 8289class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8290 : I<(outs V128:$dst), 8291 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8292 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8293 [(set (v4f32 V128:$dst), 8294 (v4f32 (OpNode (v4f32 V128:$Rd), 8295 (v8bf16 V128:$Rn), 8296 (v8bf16 8297 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8298 VectorIndexH:$idx)))))]>, 8299 Sched<[WriteVq]> { 8300 bits<5> Rd; 8301 bits<5> Rn; 8302 bits<4> Rm; 8303 bits<3> idx; 8304 8305 let Inst{31} = 0; 8306 let Inst{30} = Q; 8307 let Inst{29-22} = 0b00111111; 8308 let Inst{21-20} = idx{1-0}; 8309 let Inst{19-16} = Rm; 8310 let Inst{15-12} = 0b1111; 8311 let Inst{11} = idx{2}; // H 8312 let Inst{10} = 0; 8313 let Inst{9-5} = Rn; 8314 let Inst{4-0} = Rd; 8315} 8316 8317class SIMDThreeSameVectorBF16MatrixMul<string asm> 8318 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8319 V128, asm, ".4s", 8320 [(set (v4f32 V128:$dst), 8321 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8322 (v8bf16 V128:$Rn), 8323 (v8bf16 V128:$Rm)))]> { 8324 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8325 ", $Rm", ".8h", "}"); 8326} 8327 8328let mayRaiseFPException = 1, Uses = [FPCR] in 8329class SIMD_BFCVTN 8330 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8331 "bfcvtn", ".4h", ".4s", 8332 [(set (v8bf16 V128:$Rd), 8333 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8334 8335let mayRaiseFPException = 1, Uses = [FPCR] in 8336class SIMD_BFCVTN2 8337 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8338 "bfcvtn2", ".8h", ".4s", 8339 [(set (v8bf16 V128:$dst), 8340 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8341 8342let mayRaiseFPException = 1, Uses = [FPCR] in 8343class BF16ToSinglePrecision<string asm> 8344 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8345 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8346 Sched<[WriteFCvt]> { 8347 bits<5> Rd; 8348 bits<5> Rn; 8349 let Inst{31-10} = 0b0001111001100011010000; 8350 let Inst{9-5} = Rn; 8351 let Inst{4-0} = Rd; 8352} 8353} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8354 8355//---------------------------------------------------------------------------- 8356// Armv8.6 Matrix Multiply Extension 8357//---------------------------------------------------------------------------- 8358 8359class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8360 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8361 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8362 (v16i8 V128:$Rn), 8363 (v16i8 V128:$Rm)))]> { 8364 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8365} 8366 8367//---------------------------------------------------------------------------- 8368// ARMv8.2-A Dot Product Instructions (Indexed) 8369class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8370 string dst_kind, string lhs_kind, string rhs_kind, 8371 RegisterOperand RegType, 8372 ValueType AccumType, ValueType InputType, 8373 SDPatternOperator OpNode> : 8374 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8375 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8376 [(set (AccumType RegType:$dst), 8377 (AccumType (OpNode (AccumType RegType:$Rd), 8378 (InputType RegType:$Rn), 8379 (InputType (bitconvert (AccumType 8380 (AArch64duplane32 (v4i32 V128:$Rm), 8381 VectorIndexS:$idx)))))))]> { 8382 bits<2> idx; 8383 let Inst{21} = idx{0}; // L 8384 let Inst{11} = idx{1}; // H 8385} 8386 8387multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8388 SDPatternOperator OpNode> { 8389 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8390 V64, v2i32, v8i8, OpNode>; 8391 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8392 V128, v4i32, v16i8, OpNode>; 8393} 8394 8395// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8396let mayRaiseFPException = 1, Uses = [FPCR] in 8397class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8398 string dst_kind, string lhs_kind, 8399 string rhs_kind, RegisterOperand RegType, 8400 ValueType AccumType, ValueType InputType, 8401 SDPatternOperator OpNode> : 8402 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 8403 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8404 [(set (AccumType RegType:$dst), 8405 (AccumType (OpNode (AccumType RegType:$Rd), 8406 (InputType RegType:$Rn), 8407 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 8408 VectorIndexH:$idx)))))]> { 8409 // idx = H:L:M 8410 bits<3> idx; 8411 let Inst{11} = idx{2}; // H 8412 let Inst{21} = idx{1}; // L 8413 let Inst{20} = idx{0}; // M 8414} 8415 8416multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8417 SDPatternOperator OpNode> { 8418 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8419 V64, v2f32, v4f16, OpNode>; 8420 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8421 V128, v4f32, v8f16, OpNode>; 8422} 8423 8424let mayRaiseFPException = 1, Uses = [FPCR] in 8425multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8426 SDPatternOperator OpNode> { 8427 let Predicates = [HasNEON, HasFullFP16] in { 8428 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8429 V64, V64, 8430 V128_lo, VectorIndexH, 8431 asm, ".4h", ".4h", ".4h", ".h", 8432 [(set (v4f16 V64:$Rd), 8433 (OpNode (v4f16 V64:$Rn), 8434 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8435 bits<3> idx; 8436 let Inst{11} = idx{2}; 8437 let Inst{21} = idx{1}; 8438 let Inst{20} = idx{0}; 8439 } 8440 8441 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8442 V128, V128, 8443 V128_lo, VectorIndexH, 8444 asm, ".8h", ".8h", ".8h", ".h", 8445 [(set (v8f16 V128:$Rd), 8446 (OpNode (v8f16 V128:$Rn), 8447 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8448 bits<3> idx; 8449 let Inst{11} = idx{2}; 8450 let Inst{21} = idx{1}; 8451 let Inst{20} = idx{0}; 8452 } 8453 } // Predicates = [HasNEON, HasFullFP16] 8454 8455 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8456 V64, V64, 8457 V128, VectorIndexS, 8458 asm, ".2s", ".2s", ".2s", ".s", 8459 [(set (v2f32 V64:$Rd), 8460 (OpNode (v2f32 V64:$Rn), 8461 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8462 bits<2> idx; 8463 let Inst{11} = idx{1}; 8464 let Inst{21} = idx{0}; 8465 } 8466 8467 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8468 V128, V128, 8469 V128, VectorIndexS, 8470 asm, ".4s", ".4s", ".4s", ".s", 8471 [(set (v4f32 V128:$Rd), 8472 (OpNode (v4f32 V128:$Rn), 8473 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8474 bits<2> idx; 8475 let Inst{11} = idx{1}; 8476 let Inst{21} = idx{0}; 8477 } 8478 8479 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8480 V128, V128, 8481 V128, VectorIndexD, 8482 asm, ".2d", ".2d", ".2d", ".d", 8483 [(set (v2f64 V128:$Rd), 8484 (OpNode (v2f64 V128:$Rn), 8485 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8486 bits<1> idx; 8487 let Inst{11} = idx{0}; 8488 let Inst{21} = 0; 8489 } 8490 8491 let Predicates = [HasNEON, HasFullFP16] in { 8492 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8493 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8494 asm, ".h", "", "", ".h", 8495 [(set (f16 FPR16Op:$Rd), 8496 (OpNode (f16 FPR16Op:$Rn), 8497 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8498 VectorIndexH:$idx))))]> { 8499 bits<3> idx; 8500 let Inst{11} = idx{2}; 8501 let Inst{21} = idx{1}; 8502 let Inst{20} = idx{0}; 8503 } 8504 } // Predicates = [HasNEON, HasFullFP16] 8505 8506 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8507 FPR32Op, FPR32Op, V128, VectorIndexS, 8508 asm, ".s", "", "", ".s", 8509 [(set (f32 FPR32Op:$Rd), 8510 (OpNode (f32 FPR32Op:$Rn), 8511 (f32 (vector_extract (v4f32 V128:$Rm), 8512 VectorIndexS:$idx))))]> { 8513 bits<2> idx; 8514 let Inst{11} = idx{1}; 8515 let Inst{21} = idx{0}; 8516 } 8517 8518 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8519 FPR64Op, FPR64Op, V128, VectorIndexD, 8520 asm, ".d", "", "", ".d", 8521 [(set (f64 FPR64Op:$Rd), 8522 (OpNode (f64 FPR64Op:$Rn), 8523 (f64 (vector_extract (v2f64 V128:$Rm), 8524 VectorIndexD:$idx))))]> { 8525 bits<1> idx; 8526 let Inst{11} = idx{0}; 8527 let Inst{21} = 0; 8528 } 8529} 8530 8531multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8532 let Predicates = [HasNEON, HasFullFP16] in { 8533 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8534 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8535 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8536 VectorIndexH:$idx))), 8537 (!cast<Instruction>(INST # "v8i16_indexed") 8538 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8539 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8540 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8541 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8542 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8543 8544 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8545 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8546 VectorIndexH:$idx))), 8547 (!cast<Instruction>(INST # "v4i16_indexed") 8548 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8549 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8550 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8551 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8552 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8553 8554 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8555 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8556 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8557 V128_lo:$Rm, VectorIndexH:$idx)>; 8558 } // Predicates = [HasNEON, HasFullFP16] 8559 8560 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8561 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8562 (AArch64duplane32 (v4f32 V128:$Rm), 8563 VectorIndexS:$idx))), 8564 (!cast<Instruction>(INST # v2i32_indexed) 8565 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8566 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8567 (AArch64dup (f32 FPR32Op:$Rm)))), 8568 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8569 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8570 8571 8572 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8573 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8574 (AArch64duplane32 (v4f32 V128:$Rm), 8575 VectorIndexS:$idx))), 8576 (!cast<Instruction>(INST # "v4i32_indexed") 8577 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8578 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8579 (AArch64dup (f32 FPR32Op:$Rm)))), 8580 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8581 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8582 8583 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8584 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8585 (AArch64duplane64 (v2f64 V128:$Rm), 8586 VectorIndexD:$idx))), 8587 (!cast<Instruction>(INST # "v2i64_indexed") 8588 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8589 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8590 (AArch64dup (f64 FPR64Op:$Rm)))), 8591 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8592 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8593 8594 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8595 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8596 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8597 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8598 V128:$Rm, VectorIndexS:$idx)>; 8599 8600 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8601 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8602 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8603 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8604 V128:$Rm, VectorIndexD:$idx)>; 8605} 8606 8607let mayRaiseFPException = 1, Uses = [FPCR] in 8608multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8609 let Predicates = [HasNEON, HasFullFP16] in { 8610 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8611 V128_lo, VectorIndexH, 8612 asm, ".4h", ".4h", ".4h", ".h", []> { 8613 bits<3> idx; 8614 let Inst{11} = idx{2}; 8615 let Inst{21} = idx{1}; 8616 let Inst{20} = idx{0}; 8617 } 8618 8619 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8620 V128, V128, 8621 V128_lo, VectorIndexH, 8622 asm, ".8h", ".8h", ".8h", ".h", []> { 8623 bits<3> idx; 8624 let Inst{11} = idx{2}; 8625 let Inst{21} = idx{1}; 8626 let Inst{20} = idx{0}; 8627 } 8628 } // Predicates = [HasNEON, HasFullFP16] 8629 8630 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8631 V128, VectorIndexS, 8632 asm, ".2s", ".2s", ".2s", ".s", []> { 8633 bits<2> idx; 8634 let Inst{11} = idx{1}; 8635 let Inst{21} = idx{0}; 8636 } 8637 8638 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8639 V128, V128, 8640 V128, VectorIndexS, 8641 asm, ".4s", ".4s", ".4s", ".s", []> { 8642 bits<2> idx; 8643 let Inst{11} = idx{1}; 8644 let Inst{21} = idx{0}; 8645 } 8646 8647 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8648 V128, V128, 8649 V128, VectorIndexD, 8650 asm, ".2d", ".2d", ".2d", ".d", []> { 8651 bits<1> idx; 8652 let Inst{11} = idx{0}; 8653 let Inst{21} = 0; 8654 } 8655 8656 let Predicates = [HasNEON, HasFullFP16] in { 8657 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8658 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8659 asm, ".h", "", "", ".h", []> { 8660 bits<3> idx; 8661 let Inst{11} = idx{2}; 8662 let Inst{21} = idx{1}; 8663 let Inst{20} = idx{0}; 8664 } 8665 } // Predicates = [HasNEON, HasFullFP16] 8666 8667 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8668 FPR32Op, FPR32Op, V128, VectorIndexS, 8669 asm, ".s", "", "", ".s", []> { 8670 bits<2> idx; 8671 let Inst{11} = idx{1}; 8672 let Inst{21} = idx{0}; 8673 } 8674 8675 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8676 FPR64Op, FPR64Op, V128, VectorIndexD, 8677 asm, ".d", "", "", ".d", []> { 8678 bits<1> idx; 8679 let Inst{11} = idx{0}; 8680 let Inst{21} = 0; 8681 } 8682} 8683 8684multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8685 SDPatternOperator OpNodeLaneQ> { 8686 8687 def : Pat<(v4i16 (OpNodeLane 8688 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8689 VectorIndexS32b:$idx)), 8690 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8691 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8692 (UImmS1XForm $idx))>; 8693 8694 def : Pat<(v4i16 (OpNodeLaneQ 8695 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8696 VectorIndexH32b:$idx)), 8697 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8698 (UImmS1XForm $idx))>; 8699 8700 def : Pat<(v8i16 (OpNodeLane 8701 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8702 VectorIndexS32b:$idx)), 8703 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8704 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8705 (UImmS1XForm $idx))>; 8706 8707 def : Pat<(v8i16 (OpNodeLaneQ 8708 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8709 VectorIndexH32b:$idx)), 8710 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8711 (UImmS1XForm $idx))>; 8712 8713 def : Pat<(v2i32 (OpNodeLane 8714 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8715 VectorIndexD32b:$idx)), 8716 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8717 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8718 (UImmS1XForm $idx))>; 8719 8720 def : Pat<(v2i32 (OpNodeLaneQ 8721 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8722 VectorIndexS32b:$idx)), 8723 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8724 (UImmS1XForm $idx))>; 8725 8726 def : Pat<(v4i32 (OpNodeLane 8727 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8728 VectorIndexD32b:$idx)), 8729 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8730 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8731 (UImmS1XForm $idx))>; 8732 8733 def : Pat<(v4i32 (OpNodeLaneQ 8734 (v4i32 V128:$Rn), 8735 (v4i32 V128:$Rm), 8736 VectorIndexS32b:$idx)), 8737 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8738 (UImmS1XForm $idx))>; 8739 8740} 8741 8742multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8743 SDPatternOperator OpNode> { 8744 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8745 V128_lo, VectorIndexH, 8746 asm, ".4h", ".4h", ".4h", ".h", 8747 [(set (v4i16 V64:$Rd), 8748 (OpNode (v4i16 V64:$Rn), 8749 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8750 bits<3> idx; 8751 let Inst{11} = idx{2}; 8752 let Inst{21} = idx{1}; 8753 let Inst{20} = idx{0}; 8754 } 8755 8756 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8757 V128, V128, 8758 V128_lo, VectorIndexH, 8759 asm, ".8h", ".8h", ".8h", ".h", 8760 [(set (v8i16 V128:$Rd), 8761 (OpNode (v8i16 V128:$Rn), 8762 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8763 bits<3> idx; 8764 let Inst{11} = idx{2}; 8765 let Inst{21} = idx{1}; 8766 let Inst{20} = idx{0}; 8767 } 8768 8769 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8770 V64, V64, 8771 V128, VectorIndexS, 8772 asm, ".2s", ".2s", ".2s", ".s", 8773 [(set (v2i32 V64:$Rd), 8774 (OpNode (v2i32 V64:$Rn), 8775 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8776 bits<2> idx; 8777 let Inst{11} = idx{1}; 8778 let Inst{21} = idx{0}; 8779 } 8780 8781 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8782 V128, V128, 8783 V128, VectorIndexS, 8784 asm, ".4s", ".4s", ".4s", ".s", 8785 [(set (v4i32 V128:$Rd), 8786 (OpNode (v4i32 V128:$Rn), 8787 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8788 bits<2> idx; 8789 let Inst{11} = idx{1}; 8790 let Inst{21} = idx{0}; 8791 } 8792 8793 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8794 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8795 asm, ".h", "", "", ".h", []> { 8796 bits<3> idx; 8797 let Inst{11} = idx{2}; 8798 let Inst{21} = idx{1}; 8799 let Inst{20} = idx{0}; 8800 } 8801 8802 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8803 FPR32Op, FPR32Op, V128, VectorIndexS, 8804 asm, ".s", "", "", ".s", 8805 [(set (i32 FPR32Op:$Rd), 8806 (OpNode FPR32Op:$Rn, 8807 (i32 (vector_extract (v4i32 V128:$Rm), 8808 VectorIndexS:$idx))))]> { 8809 bits<2> idx; 8810 let Inst{11} = idx{1}; 8811 let Inst{21} = idx{0}; 8812 } 8813} 8814 8815multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8816 SDPatternOperator OpNode> { 8817 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8818 V64, V64, 8819 V128_lo, VectorIndexH, 8820 asm, ".4h", ".4h", ".4h", ".h", 8821 [(set (v4i16 V64:$Rd), 8822 (OpNode (v4i16 V64:$Rn), 8823 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8824 bits<3> idx; 8825 let Inst{11} = idx{2}; 8826 let Inst{21} = idx{1}; 8827 let Inst{20} = idx{0}; 8828 } 8829 8830 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8831 V128, V128, 8832 V128_lo, VectorIndexH, 8833 asm, ".8h", ".8h", ".8h", ".h", 8834 [(set (v8i16 V128:$Rd), 8835 (OpNode (v8i16 V128:$Rn), 8836 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8837 bits<3> idx; 8838 let Inst{11} = idx{2}; 8839 let Inst{21} = idx{1}; 8840 let Inst{20} = idx{0}; 8841 } 8842 8843 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8844 V64, V64, 8845 V128, VectorIndexS, 8846 asm, ".2s", ".2s", ".2s", ".s", 8847 [(set (v2i32 V64:$Rd), 8848 (OpNode (v2i32 V64:$Rn), 8849 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8850 bits<2> idx; 8851 let Inst{11} = idx{1}; 8852 let Inst{21} = idx{0}; 8853 } 8854 8855 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8856 V128, V128, 8857 V128, VectorIndexS, 8858 asm, ".4s", ".4s", ".4s", ".s", 8859 [(set (v4i32 V128:$Rd), 8860 (OpNode (v4i32 V128:$Rn), 8861 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8862 bits<2> idx; 8863 let Inst{11} = idx{1}; 8864 let Inst{21} = idx{0}; 8865 } 8866} 8867 8868multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8869 SDPatternOperator OpNode> { 8870 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8871 V128_lo, VectorIndexH, 8872 asm, ".4h", ".4h", ".4h", ".h", 8873 [(set (v4i16 V64:$dst), 8874 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8875 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8876 bits<3> idx; 8877 let Inst{11} = idx{2}; 8878 let Inst{21} = idx{1}; 8879 let Inst{20} = idx{0}; 8880 } 8881 8882 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8883 V128, V128, 8884 V128_lo, VectorIndexH, 8885 asm, ".8h", ".8h", ".8h", ".h", 8886 [(set (v8i16 V128:$dst), 8887 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8888 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8889 bits<3> idx; 8890 let Inst{11} = idx{2}; 8891 let Inst{21} = idx{1}; 8892 let Inst{20} = idx{0}; 8893 } 8894 8895 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8896 V64, V64, 8897 V128, VectorIndexS, 8898 asm, ".2s", ".2s", ".2s", ".s", 8899 [(set (v2i32 V64:$dst), 8900 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8901 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8902 bits<2> idx; 8903 let Inst{11} = idx{1}; 8904 let Inst{21} = idx{0}; 8905 } 8906 8907 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8908 V128, V128, 8909 V128, VectorIndexS, 8910 asm, ".4s", ".4s", ".4s", ".s", 8911 [(set (v4i32 V128:$dst), 8912 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8913 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8914 bits<2> idx; 8915 let Inst{11} = idx{1}; 8916 let Inst{21} = idx{0}; 8917 } 8918} 8919 8920multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8921 SDPatternOperator OpNode> { 8922 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8923 V128, V64, 8924 V128_lo, VectorIndexH, 8925 asm, ".4s", ".4s", ".4h", ".h", 8926 [(set (v4i32 V128:$Rd), 8927 (OpNode (v4i16 V64:$Rn), 8928 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8929 bits<3> idx; 8930 let Inst{11} = idx{2}; 8931 let Inst{21} = idx{1}; 8932 let Inst{20} = idx{0}; 8933 } 8934 8935 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8936 V128, V128, 8937 V128_lo, VectorIndexH, 8938 asm#"2", ".4s", ".4s", ".8h", ".h", 8939 [(set (v4i32 V128:$Rd), 8940 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 8941 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8942 8943 bits<3> idx; 8944 let Inst{11} = idx{2}; 8945 let Inst{21} = idx{1}; 8946 let Inst{20} = idx{0}; 8947 } 8948 8949 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8950 V128, V64, 8951 V128, VectorIndexS, 8952 asm, ".2d", ".2d", ".2s", ".s", 8953 [(set (v2i64 V128:$Rd), 8954 (OpNode (v2i32 V64:$Rn), 8955 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8956 bits<2> idx; 8957 let Inst{11} = idx{1}; 8958 let Inst{21} = idx{0}; 8959 } 8960 8961 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8962 V128, V128, 8963 V128, VectorIndexS, 8964 asm#"2", ".2d", ".2d", ".4s", ".s", 8965 [(set (v2i64 V128:$Rd), 8966 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 8967 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8968 bits<2> idx; 8969 let Inst{11} = idx{1}; 8970 let Inst{21} = idx{0}; 8971 } 8972 8973 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8974 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8975 asm, ".h", "", "", ".h", []> { 8976 bits<3> idx; 8977 let Inst{11} = idx{2}; 8978 let Inst{21} = idx{1}; 8979 let Inst{20} = idx{0}; 8980 } 8981 8982 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8983 FPR64Op, FPR32Op, V128, VectorIndexS, 8984 asm, ".s", "", "", ".s", []> { 8985 bits<2> idx; 8986 let Inst{11} = idx{1}; 8987 let Inst{21} = idx{0}; 8988 } 8989} 8990 8991multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8992 SDPatternOperator Accum> { 8993 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8994 V128, V64, 8995 V128_lo, VectorIndexH, 8996 asm, ".4s", ".4s", ".4h", ".h", 8997 [(set (v4i32 V128:$dst), 8998 (Accum (v4i32 V128:$Rd), 8999 (v4i32 (int_aarch64_neon_sqdmull 9000 (v4i16 V64:$Rn), 9001 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9002 VectorIndexH:$idx))))))]> { 9003 bits<3> idx; 9004 let Inst{11} = idx{2}; 9005 let Inst{21} = idx{1}; 9006 let Inst{20} = idx{0}; 9007 } 9008 9009 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9010 V128, V128, 9011 V128_lo, VectorIndexH, 9012 asm#"2", ".4s", ".4s", ".8h", ".h", 9013 [(set (v4i32 V128:$dst), 9014 (Accum (v4i32 V128:$Rd), 9015 (v4i32 (int_aarch64_neon_sqdmull 9016 (extract_high_v8i16 (v8i16 V128:$Rn)), 9017 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 9018 bits<3> idx; 9019 let Inst{11} = idx{2}; 9020 let Inst{21} = idx{1}; 9021 let Inst{20} = idx{0}; 9022 } 9023 9024 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9025 V128, V64, 9026 V128, VectorIndexS, 9027 asm, ".2d", ".2d", ".2s", ".s", 9028 [(set (v2i64 V128:$dst), 9029 (Accum (v2i64 V128:$Rd), 9030 (v2i64 (int_aarch64_neon_sqdmull 9031 (v2i32 V64:$Rn), 9032 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 9033 VectorIndexS:$idx))))))]> { 9034 bits<2> idx; 9035 let Inst{11} = idx{1}; 9036 let Inst{21} = idx{0}; 9037 } 9038 9039 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9040 V128, V128, 9041 V128, VectorIndexS, 9042 asm#"2", ".2d", ".2d", ".4s", ".s", 9043 [(set (v2i64 V128:$dst), 9044 (Accum (v2i64 V128:$Rd), 9045 (v2i64 (int_aarch64_neon_sqdmull 9046 (extract_high_v4i32 (v4i32 V128:$Rn)), 9047 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9048 bits<2> idx; 9049 let Inst{11} = idx{1}; 9050 let Inst{21} = idx{0}; 9051 } 9052 9053 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9054 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9055 asm, ".h", "", "", ".h", []> { 9056 bits<3> idx; 9057 let Inst{11} = idx{2}; 9058 let Inst{21} = idx{1}; 9059 let Inst{20} = idx{0}; 9060 } 9061 9062 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9063 (i32 (vector_extract 9064 (v4i32 (int_aarch64_neon_sqdmull 9065 (v4i16 V64:$Rn), 9066 (v4i16 V64:$Rm))), 9067 (i64 0))))), 9068 (!cast<Instruction>(NAME # v1i32_indexed) 9069 FPR32Op:$Rd, 9070 (EXTRACT_SUBREG V64:$Rn, hsub), 9071 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub), 9072 (i64 0))>; 9073 9074 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9075 (i32 (vector_extract 9076 (v4i32 (int_aarch64_neon_sqdmull 9077 (v4i16 V64:$Rn), 9078 (v4i16 (AArch64duplane16 9079 (v8i16 V128_lo:$Rm), 9080 VectorIndexH:$idx)))), 9081 (i64 0))))), 9082 (!cast<Instruction>(NAME # v1i32_indexed) 9083 FPR32Op:$Rd, 9084 (EXTRACT_SUBREG V64:$Rn, hsub), 9085 V128_lo:$Rm, 9086 VectorIndexH:$idx)>; 9087 9088 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9089 FPR64Op, FPR32Op, V128, VectorIndexS, 9090 asm, ".s", "", "", ".s", 9091 [(set (i64 FPR64Op:$dst), 9092 (Accum (i64 FPR64Op:$Rd), 9093 (i64 (int_aarch64_neon_sqdmulls_scalar 9094 (i32 FPR32Op:$Rn), 9095 (i32 (vector_extract (v4i32 V128:$Rm), 9096 VectorIndexS:$idx))))))]> { 9097 9098 bits<2> idx; 9099 let Inst{11} = idx{1}; 9100 let Inst{21} = idx{0}; 9101 } 9102} 9103 9104multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 9105 SDPatternOperator OpNode> { 9106 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9107 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9108 V128, V64, 9109 V128_lo, VectorIndexH, 9110 asm, ".4s", ".4s", ".4h", ".h", 9111 [(set (v4i32 V128:$Rd), 9112 (OpNode (v4i16 V64:$Rn), 9113 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9114 bits<3> idx; 9115 let Inst{11} = idx{2}; 9116 let Inst{21} = idx{1}; 9117 let Inst{20} = idx{0}; 9118 } 9119 9120 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9121 V128, V128, 9122 V128_lo, VectorIndexH, 9123 asm#"2", ".4s", ".4s", ".8h", ".h", 9124 [(set (v4i32 V128:$Rd), 9125 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9126 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9127 9128 bits<3> idx; 9129 let Inst{11} = idx{2}; 9130 let Inst{21} = idx{1}; 9131 let Inst{20} = idx{0}; 9132 } 9133 9134 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9135 V128, V64, 9136 V128, VectorIndexS, 9137 asm, ".2d", ".2d", ".2s", ".s", 9138 [(set (v2i64 V128:$Rd), 9139 (OpNode (v2i32 V64:$Rn), 9140 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9141 bits<2> idx; 9142 let Inst{11} = idx{1}; 9143 let Inst{21} = idx{0}; 9144 } 9145 9146 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9147 V128, V128, 9148 V128, VectorIndexS, 9149 asm#"2", ".2d", ".2d", ".4s", ".s", 9150 [(set (v2i64 V128:$Rd), 9151 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9152 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9153 bits<2> idx; 9154 let Inst{11} = idx{1}; 9155 let Inst{21} = idx{0}; 9156 } 9157 } 9158} 9159 9160multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 9161 SDPatternOperator OpNode> { 9162 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9163 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9164 V128, V64, 9165 V128_lo, VectorIndexH, 9166 asm, ".4s", ".4s", ".4h", ".h", 9167 [(set (v4i32 V128:$dst), 9168 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 9169 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9170 bits<3> idx; 9171 let Inst{11} = idx{2}; 9172 let Inst{21} = idx{1}; 9173 let Inst{20} = idx{0}; 9174 } 9175 9176 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9177 V128, V128, 9178 V128_lo, VectorIndexH, 9179 asm#"2", ".4s", ".4s", ".8h", ".h", 9180 [(set (v4i32 V128:$dst), 9181 (OpNode (v4i32 V128:$Rd), 9182 (extract_high_v8i16 (v8i16 V128:$Rn)), 9183 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9184 bits<3> idx; 9185 let Inst{11} = idx{2}; 9186 let Inst{21} = idx{1}; 9187 let Inst{20} = idx{0}; 9188 } 9189 9190 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9191 V128, V64, 9192 V128, VectorIndexS, 9193 asm, ".2d", ".2d", ".2s", ".s", 9194 [(set (v2i64 V128:$dst), 9195 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9196 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9197 bits<2> idx; 9198 let Inst{11} = idx{1}; 9199 let Inst{21} = idx{0}; 9200 } 9201 9202 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9203 V128, V128, 9204 V128, VectorIndexS, 9205 asm#"2", ".2d", ".2d", ".4s", ".s", 9206 [(set (v2i64 V128:$dst), 9207 (OpNode (v2i64 V128:$Rd), 9208 (extract_high_v4i32 (v4i32 V128:$Rn)), 9209 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9210 bits<2> idx; 9211 let Inst{11} = idx{1}; 9212 let Inst{21} = idx{0}; 9213 } 9214 } 9215} 9216 9217//---------------------------------------------------------------------------- 9218// AdvSIMD scalar shift by immediate 9219//---------------------------------------------------------------------------- 9220 9221let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9222class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9223 RegisterClass regtype1, RegisterClass regtype2, 9224 Operand immtype, string asm, list<dag> pattern> 9225 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9226 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9227 Sched<[WriteVd]> { 9228 bits<5> Rd; 9229 bits<5> Rn; 9230 bits<7> imm; 9231 let Inst{31-30} = 0b01; 9232 let Inst{29} = U; 9233 let Inst{28-23} = 0b111110; 9234 let Inst{22-16} = fixed_imm; 9235 let Inst{15-11} = opc; 9236 let Inst{10} = 1; 9237 let Inst{9-5} = Rn; 9238 let Inst{4-0} = Rd; 9239} 9240 9241let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9242class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9243 RegisterClass regtype1, RegisterClass regtype2, 9244 Operand immtype, string asm, list<dag> pattern> 9245 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9246 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9247 Sched<[WriteVd]> { 9248 bits<5> Rd; 9249 bits<5> Rn; 9250 bits<7> imm; 9251 let Inst{31-30} = 0b01; 9252 let Inst{29} = U; 9253 let Inst{28-23} = 0b111110; 9254 let Inst{22-16} = fixed_imm; 9255 let Inst{15-11} = opc; 9256 let Inst{10} = 1; 9257 let Inst{9-5} = Rn; 9258 let Inst{4-0} = Rd; 9259} 9260 9261 9262multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9263 let Predicates = [HasNEON, HasFullFP16] in { 9264 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9265 FPR16, FPR16, vecshiftR16, asm, []> { 9266 let Inst{19-16} = imm{3-0}; 9267 } 9268 } // Predicates = [HasNEON, HasFullFP16] 9269 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9270 FPR32, FPR32, vecshiftR32, asm, []> { 9271 let Inst{20-16} = imm{4-0}; 9272 } 9273 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9274 FPR64, FPR64, vecshiftR64, asm, []> { 9275 let Inst{21-16} = imm{5-0}; 9276 } 9277} 9278 9279multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9280 SDPatternOperator OpNode> { 9281 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9282 FPR64, FPR64, vecshiftR64, asm, 9283 [(set (i64 FPR64:$Rd), 9284 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9285 let Inst{21-16} = imm{5-0}; 9286 } 9287 9288 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9289 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9290} 9291 9292multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9293 SDPatternOperator OpNode = null_frag> { 9294 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9295 FPR64, FPR64, vecshiftR64, asm, 9296 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9297 (i32 vecshiftR64:$imm)))]> { 9298 let Inst{21-16} = imm{5-0}; 9299 } 9300 9301 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9302 (i32 vecshiftR64:$imm))), 9303 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9304 vecshiftR64:$imm)>; 9305} 9306 9307multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9308 SDPatternOperator OpNode> { 9309 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9310 FPR64, FPR64, vecshiftL64, asm, 9311 [(set (i64 FPR64:$Rd), 9312 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9313 let Inst{21-16} = imm{5-0}; 9314 } 9315 9316 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9317 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9318} 9319 9320let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9321multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9322 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9323 FPR64, FPR64, vecshiftL64, asm, []> { 9324 let Inst{21-16} = imm{5-0}; 9325 } 9326} 9327 9328let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9329multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9330 SDPatternOperator OpNode = null_frag> { 9331 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9332 FPR8, FPR16, vecshiftR8, asm, []> { 9333 let Inst{18-16} = imm{2-0}; 9334 } 9335 9336 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9337 FPR16, FPR32, vecshiftR16, asm, []> { 9338 let Inst{19-16} = imm{3-0}; 9339 } 9340 9341 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9342 FPR32, FPR64, vecshiftR32, asm, 9343 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9344 let Inst{20-16} = imm{4-0}; 9345 } 9346} 9347 9348multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9349 SDPatternOperator OpNode> { 9350 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9351 FPR8, FPR8, vecshiftL8, asm, []> { 9352 let Inst{18-16} = imm{2-0}; 9353 } 9354 9355 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9356 FPR16, FPR16, vecshiftL16, asm, []> { 9357 let Inst{19-16} = imm{3-0}; 9358 } 9359 9360 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9361 FPR32, FPR32, vecshiftL32, asm, 9362 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9363 let Inst{20-16} = imm{4-0}; 9364 } 9365 9366 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9367 FPR64, FPR64, vecshiftL64, asm, 9368 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9369 let Inst{21-16} = imm{5-0}; 9370 } 9371 9372 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9373 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9374} 9375 9376multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9377 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9378 FPR8, FPR8, vecshiftR8, asm, []> { 9379 let Inst{18-16} = imm{2-0}; 9380 } 9381 9382 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9383 FPR16, FPR16, vecshiftR16, asm, []> { 9384 let Inst{19-16} = imm{3-0}; 9385 } 9386 9387 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9388 FPR32, FPR32, vecshiftR32, asm, []> { 9389 let Inst{20-16} = imm{4-0}; 9390 } 9391 9392 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9393 FPR64, FPR64, vecshiftR64, asm, []> { 9394 let Inst{21-16} = imm{5-0}; 9395 } 9396} 9397 9398//---------------------------------------------------------------------------- 9399// AdvSIMD vector x indexed element 9400//---------------------------------------------------------------------------- 9401 9402let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9403class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9404 RegisterOperand dst_reg, RegisterOperand src_reg, 9405 Operand immtype, 9406 string asm, string dst_kind, string src_kind, 9407 list<dag> pattern> 9408 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9409 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9410 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9411 Sched<[!if(Q, WriteVq, WriteVd)]> { 9412 bits<5> Rd; 9413 bits<5> Rn; 9414 let Inst{31} = 0; 9415 let Inst{30} = Q; 9416 let Inst{29} = U; 9417 let Inst{28-23} = 0b011110; 9418 let Inst{22-16} = fixed_imm; 9419 let Inst{15-11} = opc; 9420 let Inst{10} = 1; 9421 let Inst{9-5} = Rn; 9422 let Inst{4-0} = Rd; 9423} 9424 9425let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9426class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9427 RegisterOperand vectype1, RegisterOperand vectype2, 9428 Operand immtype, 9429 string asm, string dst_kind, string src_kind, 9430 list<dag> pattern> 9431 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9432 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9433 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9434 Sched<[!if(Q, WriteVq, WriteVd)]> { 9435 bits<5> Rd; 9436 bits<5> Rn; 9437 let Inst{31} = 0; 9438 let Inst{30} = Q; 9439 let Inst{29} = U; 9440 let Inst{28-23} = 0b011110; 9441 let Inst{22-16} = fixed_imm; 9442 let Inst{15-11} = opc; 9443 let Inst{10} = 1; 9444 let Inst{9-5} = Rn; 9445 let Inst{4-0} = Rd; 9446} 9447 9448multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9449 Intrinsic OpNode> { 9450 let Predicates = [HasNEON, HasFullFP16] in { 9451 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9452 V64, V64, vecshiftR16, 9453 asm, ".4h", ".4h", 9454 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9455 bits<4> imm; 9456 let Inst{19-16} = imm; 9457 } 9458 9459 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9460 V128, V128, vecshiftR16, 9461 asm, ".8h", ".8h", 9462 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9463 bits<4> imm; 9464 let Inst{19-16} = imm; 9465 } 9466 } // Predicates = [HasNEON, HasFullFP16] 9467 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9468 V64, V64, vecshiftR32, 9469 asm, ".2s", ".2s", 9470 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9471 bits<5> imm; 9472 let Inst{20-16} = imm; 9473 } 9474 9475 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9476 V128, V128, vecshiftR32, 9477 asm, ".4s", ".4s", 9478 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9479 bits<5> imm; 9480 let Inst{20-16} = imm; 9481 } 9482 9483 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9484 V128, V128, vecshiftR64, 9485 asm, ".2d", ".2d", 9486 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9487 bits<6> imm; 9488 let Inst{21-16} = imm; 9489 } 9490} 9491 9492multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9493 Intrinsic OpNode> { 9494 let Predicates = [HasNEON, HasFullFP16] in { 9495 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9496 V64, V64, vecshiftR16, 9497 asm, ".4h", ".4h", 9498 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9499 bits<4> imm; 9500 let Inst{19-16} = imm; 9501 } 9502 9503 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9504 V128, V128, vecshiftR16, 9505 asm, ".8h", ".8h", 9506 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9507 bits<4> imm; 9508 let Inst{19-16} = imm; 9509 } 9510 } // Predicates = [HasNEON, HasFullFP16] 9511 9512 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9513 V64, V64, vecshiftR32, 9514 asm, ".2s", ".2s", 9515 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9516 bits<5> imm; 9517 let Inst{20-16} = imm; 9518 } 9519 9520 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9521 V128, V128, vecshiftR32, 9522 asm, ".4s", ".4s", 9523 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9524 bits<5> imm; 9525 let Inst{20-16} = imm; 9526 } 9527 9528 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9529 V128, V128, vecshiftR64, 9530 asm, ".2d", ".2d", 9531 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9532 bits<6> imm; 9533 let Inst{21-16} = imm; 9534 } 9535} 9536 9537multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9538 SDPatternOperator OpNode> { 9539 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9540 V64, V128, vecshiftR16Narrow, 9541 asm, ".8b", ".8h", 9542 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9543 bits<3> imm; 9544 let Inst{18-16} = imm; 9545 } 9546 9547 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9548 V128, V128, vecshiftR16Narrow, 9549 asm#"2", ".16b", ".8h", []> { 9550 bits<3> imm; 9551 let Inst{18-16} = imm; 9552 let hasSideEffects = 0; 9553 } 9554 9555 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9556 V64, V128, vecshiftR32Narrow, 9557 asm, ".4h", ".4s", 9558 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9559 bits<4> imm; 9560 let Inst{19-16} = imm; 9561 } 9562 9563 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9564 V128, V128, vecshiftR32Narrow, 9565 asm#"2", ".8h", ".4s", []> { 9566 bits<4> imm; 9567 let Inst{19-16} = imm; 9568 let hasSideEffects = 0; 9569 } 9570 9571 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9572 V64, V128, vecshiftR64Narrow, 9573 asm, ".2s", ".2d", 9574 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9575 bits<5> imm; 9576 let Inst{20-16} = imm; 9577 } 9578 9579 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9580 V128, V128, vecshiftR64Narrow, 9581 asm#"2", ".4s", ".2d", []> { 9582 bits<5> imm; 9583 let Inst{20-16} = imm; 9584 let hasSideEffects = 0; 9585 } 9586 9587 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9588 // themselves, so put them here instead. 9589 9590 // Patterns involving what's effectively an insert high and a normal 9591 // intrinsic, represented by CONCAT_VECTORS. 9592 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9593 vecshiftR16Narrow:$imm)), 9594 (!cast<Instruction>(NAME # "v16i8_shift") 9595 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9596 V128:$Rn, vecshiftR16Narrow:$imm)>; 9597 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9598 vecshiftR32Narrow:$imm)), 9599 (!cast<Instruction>(NAME # "v8i16_shift") 9600 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9601 V128:$Rn, vecshiftR32Narrow:$imm)>; 9602 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9603 vecshiftR64Narrow:$imm)), 9604 (!cast<Instruction>(NAME # "v4i32_shift") 9605 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9606 V128:$Rn, vecshiftR64Narrow:$imm)>; 9607} 9608 9609multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9610 SDPatternOperator OpNode> { 9611 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9612 V64, V64, vecshiftL8, 9613 asm, ".8b", ".8b", 9614 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9615 (i32 vecshiftL8:$imm)))]> { 9616 bits<3> imm; 9617 let Inst{18-16} = imm; 9618 } 9619 9620 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9621 V128, V128, vecshiftL8, 9622 asm, ".16b", ".16b", 9623 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9624 (i32 vecshiftL8:$imm)))]> { 9625 bits<3> imm; 9626 let Inst{18-16} = imm; 9627 } 9628 9629 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9630 V64, V64, vecshiftL16, 9631 asm, ".4h", ".4h", 9632 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9633 (i32 vecshiftL16:$imm)))]> { 9634 bits<4> imm; 9635 let Inst{19-16} = imm; 9636 } 9637 9638 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9639 V128, V128, vecshiftL16, 9640 asm, ".8h", ".8h", 9641 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9642 (i32 vecshiftL16:$imm)))]> { 9643 bits<4> imm; 9644 let Inst{19-16} = imm; 9645 } 9646 9647 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9648 V64, V64, vecshiftL32, 9649 asm, ".2s", ".2s", 9650 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9651 (i32 vecshiftL32:$imm)))]> { 9652 bits<5> imm; 9653 let Inst{20-16} = imm; 9654 } 9655 9656 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9657 V128, V128, vecshiftL32, 9658 asm, ".4s", ".4s", 9659 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9660 (i32 vecshiftL32:$imm)))]> { 9661 bits<5> imm; 9662 let Inst{20-16} = imm; 9663 } 9664 9665 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9666 V128, V128, vecshiftL64, 9667 asm, ".2d", ".2d", 9668 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9669 (i32 vecshiftL64:$imm)))]> { 9670 bits<6> imm; 9671 let Inst{21-16} = imm; 9672 } 9673} 9674 9675multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9676 SDPatternOperator OpNode> { 9677 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9678 V64, V64, vecshiftR8, 9679 asm, ".8b", ".8b", 9680 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9681 (i32 vecshiftR8:$imm)))]> { 9682 bits<3> imm; 9683 let Inst{18-16} = imm; 9684 } 9685 9686 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9687 V128, V128, vecshiftR8, 9688 asm, ".16b", ".16b", 9689 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9690 (i32 vecshiftR8:$imm)))]> { 9691 bits<3> imm; 9692 let Inst{18-16} = imm; 9693 } 9694 9695 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9696 V64, V64, vecshiftR16, 9697 asm, ".4h", ".4h", 9698 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9699 (i32 vecshiftR16:$imm)))]> { 9700 bits<4> imm; 9701 let Inst{19-16} = imm; 9702 } 9703 9704 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9705 V128, V128, vecshiftR16, 9706 asm, ".8h", ".8h", 9707 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9708 (i32 vecshiftR16:$imm)))]> { 9709 bits<4> imm; 9710 let Inst{19-16} = imm; 9711 } 9712 9713 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9714 V64, V64, vecshiftR32, 9715 asm, ".2s", ".2s", 9716 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9717 (i32 vecshiftR32:$imm)))]> { 9718 bits<5> imm; 9719 let Inst{20-16} = imm; 9720 } 9721 9722 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9723 V128, V128, vecshiftR32, 9724 asm, ".4s", ".4s", 9725 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9726 (i32 vecshiftR32:$imm)))]> { 9727 bits<5> imm; 9728 let Inst{20-16} = imm; 9729 } 9730 9731 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9732 V128, V128, vecshiftR64, 9733 asm, ".2d", ".2d", 9734 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9735 (i32 vecshiftR64:$imm)))]> { 9736 bits<6> imm; 9737 let Inst{21-16} = imm; 9738 } 9739} 9740 9741let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9742multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9743 SDPatternOperator OpNode = null_frag> { 9744 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9745 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9746 [(set (v8i8 V64:$dst), 9747 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9748 (i32 vecshiftR8:$imm)))]> { 9749 bits<3> imm; 9750 let Inst{18-16} = imm; 9751 } 9752 9753 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9754 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9755 [(set (v16i8 V128:$dst), 9756 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9757 (i32 vecshiftR8:$imm)))]> { 9758 bits<3> imm; 9759 let Inst{18-16} = imm; 9760 } 9761 9762 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9763 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9764 [(set (v4i16 V64:$dst), 9765 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9766 (i32 vecshiftR16:$imm)))]> { 9767 bits<4> imm; 9768 let Inst{19-16} = imm; 9769 } 9770 9771 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9772 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9773 [(set (v8i16 V128:$dst), 9774 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9775 (i32 vecshiftR16:$imm)))]> { 9776 bits<4> imm; 9777 let Inst{19-16} = imm; 9778 } 9779 9780 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9781 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9782 [(set (v2i32 V64:$dst), 9783 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9784 (i32 vecshiftR32:$imm)))]> { 9785 bits<5> imm; 9786 let Inst{20-16} = imm; 9787 } 9788 9789 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9790 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9791 [(set (v4i32 V128:$dst), 9792 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9793 (i32 vecshiftR32:$imm)))]> { 9794 bits<5> imm; 9795 let Inst{20-16} = imm; 9796 } 9797 9798 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9799 V128, V128, vecshiftR64, 9800 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9801 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9802 (i32 vecshiftR64:$imm)))]> { 9803 bits<6> imm; 9804 let Inst{21-16} = imm; 9805 } 9806} 9807 9808multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9809 SDPatternOperator OpNode = null_frag> { 9810 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9811 V64, V64, vecshiftL8, 9812 asm, ".8b", ".8b", 9813 [(set (v8i8 V64:$dst), 9814 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9815 (i32 vecshiftL8:$imm)))]> { 9816 bits<3> imm; 9817 let Inst{18-16} = imm; 9818 } 9819 9820 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9821 V128, V128, vecshiftL8, 9822 asm, ".16b", ".16b", 9823 [(set (v16i8 V128:$dst), 9824 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9825 (i32 vecshiftL8:$imm)))]> { 9826 bits<3> imm; 9827 let Inst{18-16} = imm; 9828 } 9829 9830 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9831 V64, V64, vecshiftL16, 9832 asm, ".4h", ".4h", 9833 [(set (v4i16 V64:$dst), 9834 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9835 (i32 vecshiftL16:$imm)))]> { 9836 bits<4> imm; 9837 let Inst{19-16} = imm; 9838 } 9839 9840 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9841 V128, V128, vecshiftL16, 9842 asm, ".8h", ".8h", 9843 [(set (v8i16 V128:$dst), 9844 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9845 (i32 vecshiftL16:$imm)))]> { 9846 bits<4> imm; 9847 let Inst{19-16} = imm; 9848 } 9849 9850 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9851 V64, V64, vecshiftL32, 9852 asm, ".2s", ".2s", 9853 [(set (v2i32 V64:$dst), 9854 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9855 (i32 vecshiftL32:$imm)))]> { 9856 bits<5> imm; 9857 let Inst{20-16} = imm; 9858 } 9859 9860 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9861 V128, V128, vecshiftL32, 9862 asm, ".4s", ".4s", 9863 [(set (v4i32 V128:$dst), 9864 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9865 (i32 vecshiftL32:$imm)))]> { 9866 bits<5> imm; 9867 let Inst{20-16} = imm; 9868 } 9869 9870 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9871 V128, V128, vecshiftL64, 9872 asm, ".2d", ".2d", 9873 [(set (v2i64 V128:$dst), 9874 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9875 (i32 vecshiftL64:$imm)))]> { 9876 bits<6> imm; 9877 let Inst{21-16} = imm; 9878 } 9879} 9880 9881multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9882 SDPatternOperator OpNode> { 9883 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9884 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9885 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9886 bits<3> imm; 9887 let Inst{18-16} = imm; 9888 } 9889 9890 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9891 V128, V128, vecshiftL8, 9892 asm#"2", ".8h", ".16b", 9893 [(set (v8i16 V128:$Rd), 9894 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 9895 bits<3> imm; 9896 let Inst{18-16} = imm; 9897 } 9898 9899 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9900 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9901 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9902 bits<4> imm; 9903 let Inst{19-16} = imm; 9904 } 9905 9906 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9907 V128, V128, vecshiftL16, 9908 asm#"2", ".4s", ".8h", 9909 [(set (v4i32 V128:$Rd), 9910 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 9911 9912 bits<4> imm; 9913 let Inst{19-16} = imm; 9914 } 9915 9916 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9917 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9918 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9919 bits<5> imm; 9920 let Inst{20-16} = imm; 9921 } 9922 9923 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9924 V128, V128, vecshiftL32, 9925 asm#"2", ".2d", ".4s", 9926 [(set (v2i64 V128:$Rd), 9927 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 9928 bits<5> imm; 9929 let Inst{20-16} = imm; 9930 } 9931} 9932 9933 9934//--- 9935// Vector load/store 9936//--- 9937// SIMD ldX/stX no-index memory references don't allow the optional 9938// ", #0" constant and handle post-indexing explicitly, so we use 9939// a more specialized parse method for them. Otherwise, it's the same as 9940// the general GPR64sp handling. 9941 9942class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9943 string asm, dag oops, dag iops, list<dag> pattern> 9944 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9945 bits<5> Vt; 9946 bits<5> Rn; 9947 let Inst{31} = 0; 9948 let Inst{30} = Q; 9949 let Inst{29-23} = 0b0011000; 9950 let Inst{22} = L; 9951 let Inst{21-16} = 0b000000; 9952 let Inst{15-12} = opcode; 9953 let Inst{11-10} = size; 9954 let Inst{9-5} = Rn; 9955 let Inst{4-0} = Vt; 9956} 9957 9958class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9959 string asm, dag oops, dag iops> 9960 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9961 bits<5> Vt; 9962 bits<5> Rn; 9963 bits<5> Xm; 9964 let Inst{31} = 0; 9965 let Inst{30} = Q; 9966 let Inst{29-23} = 0b0011001; 9967 let Inst{22} = L; 9968 let Inst{21} = 0; 9969 let Inst{20-16} = Xm; 9970 let Inst{15-12} = opcode; 9971 let Inst{11-10} = size; 9972 let Inst{9-5} = Rn; 9973 let Inst{4-0} = Vt; 9974} 9975 9976// The immediate form of AdvSIMD post-indexed addressing is encoded with 9977// register post-index addressing from the zero register. 9978multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9979 int Offset, int Size> { 9980 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9981 // "ld1\t$Vt, [$Rn], #16" 9982 // may get mapped to 9983 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9984 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9985 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9986 GPR64sp:$Rn, 9987 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9988 XZR), 1>; 9989 9990 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9991 // "ld1.8b\t$Vt, [$Rn], #16" 9992 // may get mapped to 9993 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9994 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9995 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9996 GPR64sp:$Rn, 9997 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9998 XZR), 0>; 9999 10000 // E.g. "ld1.8b { v0, v1 }, [x1]" 10001 // "ld1\t$Vt, [$Rn]" 10002 // may get mapped to 10003 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 10004 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10005 (!cast<Instruction>(BaseName # Count # "v" # layout) 10006 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10007 GPR64sp:$Rn), 0>; 10008 10009 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 10010 // "ld1\t$Vt, [$Rn], $Xm" 10011 // may get mapped to 10012 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 10013 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10014 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10015 GPR64sp:$Rn, 10016 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10017 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10018} 10019 10020multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 10021 int Offset128, int Offset64, bits<4> opcode> { 10022 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10023 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 10024 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 10025 (ins GPR64sp:$Rn), []>; 10026 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 10027 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 10028 (ins GPR64sp:$Rn), []>; 10029 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 10030 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 10031 (ins GPR64sp:$Rn), []>; 10032 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 10033 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 10034 (ins GPR64sp:$Rn), []>; 10035 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 10036 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 10037 (ins GPR64sp:$Rn), []>; 10038 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 10039 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 10040 (ins GPR64sp:$Rn), []>; 10041 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 10042 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 10043 (ins GPR64sp:$Rn), []>; 10044 10045 10046 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 10047 (outs GPR64sp:$wback, 10048 !cast<RegisterOperand>(veclist # "16b"):$Vt), 10049 (ins GPR64sp:$Rn, 10050 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10051 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 10052 (outs GPR64sp:$wback, 10053 !cast<RegisterOperand>(veclist # "8h"):$Vt), 10054 (ins GPR64sp:$Rn, 10055 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10056 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 10057 (outs GPR64sp:$wback, 10058 !cast<RegisterOperand>(veclist # "4s"):$Vt), 10059 (ins GPR64sp:$Rn, 10060 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10061 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 10062 (outs GPR64sp:$wback, 10063 !cast<RegisterOperand>(veclist # "2d"):$Vt), 10064 (ins GPR64sp:$Rn, 10065 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10066 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 10067 (outs GPR64sp:$wback, 10068 !cast<RegisterOperand>(veclist # "8b"):$Vt), 10069 (ins GPR64sp:$Rn, 10070 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10071 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 10072 (outs GPR64sp:$wback, 10073 !cast<RegisterOperand>(veclist # "4h"):$Vt), 10074 (ins GPR64sp:$Rn, 10075 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10076 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 10077 (outs GPR64sp:$wback, 10078 !cast<RegisterOperand>(veclist # "2s"):$Vt), 10079 (ins GPR64sp:$Rn, 10080 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10081 } 10082 10083 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10084 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10085 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10086 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10087 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10088 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10089 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10090} 10091 10092// Only ld1/st1 has a v1d version. 10093multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 10094 int Offset128, int Offset64, bits<4> opcode> { 10095 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 10096 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 10097 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10098 GPR64sp:$Rn), []>; 10099 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 10100 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10101 GPR64sp:$Rn), []>; 10102 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 10103 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10104 GPR64sp:$Rn), []>; 10105 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 10106 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10107 GPR64sp:$Rn), []>; 10108 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 10109 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10110 GPR64sp:$Rn), []>; 10111 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 10112 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10113 GPR64sp:$Rn), []>; 10114 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 10115 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10116 GPR64sp:$Rn), []>; 10117 10118 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 10119 (outs GPR64sp:$wback), 10120 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10121 GPR64sp:$Rn, 10122 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10123 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 10124 (outs GPR64sp:$wback), 10125 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10126 GPR64sp:$Rn, 10127 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10128 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 10129 (outs GPR64sp:$wback), 10130 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10131 GPR64sp:$Rn, 10132 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10133 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 10134 (outs GPR64sp:$wback), 10135 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10136 GPR64sp:$Rn, 10137 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10138 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 10139 (outs GPR64sp:$wback), 10140 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10141 GPR64sp:$Rn, 10142 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10143 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 10144 (outs GPR64sp:$wback), 10145 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10146 GPR64sp:$Rn, 10147 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10148 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 10149 (outs GPR64sp:$wback), 10150 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10151 GPR64sp:$Rn, 10152 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10153 } 10154 10155 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10156 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10157 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10158 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10159 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10160 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10161 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10162} 10163 10164multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 10165 int Offset128, int Offset64, bits<4> opcode> 10166 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10167 10168 // LD1 instructions have extra "1d" variants. 10169 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10170 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 10171 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10172 (ins GPR64sp:$Rn), []>; 10173 10174 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10175 (outs GPR64sp:$wback, 10176 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10177 (ins GPR64sp:$Rn, 10178 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10179 } 10180 10181 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10182} 10183 10184multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10185 int Offset128, int Offset64, bits<4> opcode> 10186 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10187 10188 // ST1 instructions have extra "1d" variants. 10189 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10190 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10191 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10192 GPR64sp:$Rn), []>; 10193 10194 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10195 (outs GPR64sp:$wback), 10196 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10197 GPR64sp:$Rn, 10198 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10199 } 10200 10201 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10202} 10203 10204multiclass SIMDLd1Multiple<string asm> { 10205 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10206 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10207 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10208 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10209} 10210 10211multiclass SIMDSt1Multiple<string asm> { 10212 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10213 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10214 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10215 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10216} 10217 10218multiclass SIMDLd2Multiple<string asm> { 10219 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10220} 10221 10222multiclass SIMDSt2Multiple<string asm> { 10223 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10224} 10225 10226multiclass SIMDLd3Multiple<string asm> { 10227 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10228} 10229 10230multiclass SIMDSt3Multiple<string asm> { 10231 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10232} 10233 10234multiclass SIMDLd4Multiple<string asm> { 10235 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10236} 10237 10238multiclass SIMDSt4Multiple<string asm> { 10239 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10240} 10241 10242//--- 10243// AdvSIMD Load/store single-element 10244//--- 10245 10246class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10247 string asm, string operands, string cst, 10248 dag oops, dag iops, list<dag> pattern> 10249 : I<oops, iops, asm, operands, cst, pattern> { 10250 bits<5> Vt; 10251 bits<5> Rn; 10252 let Inst{31} = 0; 10253 let Inst{29-24} = 0b001101; 10254 let Inst{22} = L; 10255 let Inst{21} = R; 10256 let Inst{15-13} = opcode; 10257 let Inst{9-5} = Rn; 10258 let Inst{4-0} = Vt; 10259} 10260 10261class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10262 string asm, string operands, string cst, 10263 dag oops, dag iops, list<dag> pattern> 10264 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10265 bits<5> Vt; 10266 bits<5> Rn; 10267 let Inst{31} = 0; 10268 let Inst{29-24} = 0b001101; 10269 let Inst{22} = L; 10270 let Inst{21} = R; 10271 let Inst{15-13} = opcode; 10272 let Inst{9-5} = Rn; 10273 let Inst{4-0} = Vt; 10274} 10275 10276 10277let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10278class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10279 DAGOperand listtype> 10280 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10281 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10282 []> { 10283 let Inst{30} = Q; 10284 let Inst{23} = 0; 10285 let Inst{20-16} = 0b00000; 10286 let Inst{12} = S; 10287 let Inst{11-10} = size; 10288} 10289let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10290class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10291 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10292 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10293 "$Rn = $wback", 10294 (outs GPR64sp:$wback, listtype:$Vt), 10295 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10296 bits<5> Xm; 10297 let Inst{30} = Q; 10298 let Inst{23} = 1; 10299 let Inst{20-16} = Xm; 10300 let Inst{12} = S; 10301 let Inst{11-10} = size; 10302} 10303 10304multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10305 int Offset, int Size> { 10306 // E.g. "ld1r { v0.8b }, [x1], #1" 10307 // "ld1r.8b\t$Vt, [$Rn], #1" 10308 // may get mapped to 10309 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10310 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10311 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10312 GPR64sp:$Rn, 10313 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10314 XZR), 1>; 10315 10316 // E.g. "ld1r.8b { v0 }, [x1], #1" 10317 // "ld1r.8b\t$Vt, [$Rn], #1" 10318 // may get mapped to 10319 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10320 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10321 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10322 GPR64sp:$Rn, 10323 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10324 XZR), 0>; 10325 10326 // E.g. "ld1r.8b { v0 }, [x1]" 10327 // "ld1r.8b\t$Vt, [$Rn]" 10328 // may get mapped to 10329 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10330 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10331 (!cast<Instruction>(BaseName # "v" # layout) 10332 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10333 GPR64sp:$Rn), 0>; 10334 10335 // E.g. "ld1r.8b { v0 }, [x1], x2" 10336 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10337 // may get mapped to 10338 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10339 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10340 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10341 GPR64sp:$Rn, 10342 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10343 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10344} 10345 10346multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10347 int Offset1, int Offset2, int Offset4, int Offset8> { 10348 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10349 !cast<DAGOperand>("VecList" # Count # "8b")>; 10350 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10351 !cast<DAGOperand>("VecList" # Count #"16b")>; 10352 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10353 !cast<DAGOperand>("VecList" # Count #"4h")>; 10354 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10355 !cast<DAGOperand>("VecList" # Count #"8h")>; 10356 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10357 !cast<DAGOperand>("VecList" # Count #"2s")>; 10358 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10359 !cast<DAGOperand>("VecList" # Count #"4s")>; 10360 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10361 !cast<DAGOperand>("VecList" # Count #"1d")>; 10362 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10363 !cast<DAGOperand>("VecList" # Count #"2d")>; 10364 10365 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10366 !cast<DAGOperand>("VecList" # Count # "8b"), 10367 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10368 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10369 !cast<DAGOperand>("VecList" # Count # "16b"), 10370 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10371 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10372 !cast<DAGOperand>("VecList" # Count # "4h"), 10373 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10374 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10375 !cast<DAGOperand>("VecList" # Count # "8h"), 10376 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10377 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10378 !cast<DAGOperand>("VecList" # Count # "2s"), 10379 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10380 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10381 !cast<DAGOperand>("VecList" # Count # "4s"), 10382 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10383 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10384 !cast<DAGOperand>("VecList" # Count # "1d"), 10385 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10386 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10387 !cast<DAGOperand>("VecList" # Count # "2d"), 10388 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10389 10390 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10391 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10392 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10393 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10394 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10395 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10396 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10397 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10398} 10399 10400class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10401 dag oops, dag iops, list<dag> pattern> 10402 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10403 pattern> { 10404 // idx encoded in Q:S:size fields. 10405 bits<4> idx; 10406 let Inst{30} = idx{3}; 10407 let Inst{23} = 0; 10408 let Inst{20-16} = 0b00000; 10409 let Inst{12} = idx{2}; 10410 let Inst{11-10} = idx{1-0}; 10411} 10412class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10413 dag oops, dag iops, list<dag> pattern> 10414 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10415 oops, iops, pattern> { 10416 // idx encoded in Q:S:size fields. 10417 bits<4> idx; 10418 let Inst{30} = idx{3}; 10419 let Inst{23} = 0; 10420 let Inst{20-16} = 0b00000; 10421 let Inst{12} = idx{2}; 10422 let Inst{11-10} = idx{1-0}; 10423} 10424class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10425 dag oops, dag iops> 10426 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10427 "$Rn = $wback", oops, iops, []> { 10428 // idx encoded in Q:S:size fields. 10429 bits<4> idx; 10430 bits<5> Xm; 10431 let Inst{30} = idx{3}; 10432 let Inst{23} = 1; 10433 let Inst{20-16} = Xm; 10434 let Inst{12} = idx{2}; 10435 let Inst{11-10} = idx{1-0}; 10436} 10437class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10438 dag oops, dag iops> 10439 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10440 "$Rn = $wback", oops, iops, []> { 10441 // idx encoded in Q:S:size fields. 10442 bits<4> idx; 10443 bits<5> Xm; 10444 let Inst{30} = idx{3}; 10445 let Inst{23} = 1; 10446 let Inst{20-16} = Xm; 10447 let Inst{12} = idx{2}; 10448 let Inst{11-10} = idx{1-0}; 10449} 10450 10451class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10452 dag oops, dag iops, list<dag> pattern> 10453 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10454 pattern> { 10455 // idx encoded in Q:S:size<1> fields. 10456 bits<3> idx; 10457 let Inst{30} = idx{2}; 10458 let Inst{23} = 0; 10459 let Inst{20-16} = 0b00000; 10460 let Inst{12} = idx{1}; 10461 let Inst{11} = idx{0}; 10462 let Inst{10} = size; 10463} 10464class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10465 dag oops, dag iops, list<dag> pattern> 10466 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10467 oops, iops, pattern> { 10468 // idx encoded in Q:S:size<1> fields. 10469 bits<3> idx; 10470 let Inst{30} = idx{2}; 10471 let Inst{23} = 0; 10472 let Inst{20-16} = 0b00000; 10473 let Inst{12} = idx{1}; 10474 let Inst{11} = idx{0}; 10475 let Inst{10} = size; 10476} 10477 10478class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10479 dag oops, dag iops> 10480 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10481 "$Rn = $wback", oops, iops, []> { 10482 // idx encoded in Q:S:size<1> fields. 10483 bits<3> idx; 10484 bits<5> Xm; 10485 let Inst{30} = idx{2}; 10486 let Inst{23} = 1; 10487 let Inst{20-16} = Xm; 10488 let Inst{12} = idx{1}; 10489 let Inst{11} = idx{0}; 10490 let Inst{10} = size; 10491} 10492class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10493 dag oops, dag iops> 10494 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10495 "$Rn = $wback", oops, iops, []> { 10496 // idx encoded in Q:S:size<1> fields. 10497 bits<3> idx; 10498 bits<5> Xm; 10499 let Inst{30} = idx{2}; 10500 let Inst{23} = 1; 10501 let Inst{20-16} = Xm; 10502 let Inst{12} = idx{1}; 10503 let Inst{11} = idx{0}; 10504 let Inst{10} = size; 10505} 10506class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10507 dag oops, dag iops, list<dag> pattern> 10508 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10509 pattern> { 10510 // idx encoded in Q:S fields. 10511 bits<2> idx; 10512 let Inst{30} = idx{1}; 10513 let Inst{23} = 0; 10514 let Inst{20-16} = 0b00000; 10515 let Inst{12} = idx{0}; 10516 let Inst{11-10} = size; 10517} 10518class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10519 dag oops, dag iops, list<dag> pattern> 10520 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10521 oops, iops, pattern> { 10522 // idx encoded in Q:S fields. 10523 bits<2> idx; 10524 let Inst{30} = idx{1}; 10525 let Inst{23} = 0; 10526 let Inst{20-16} = 0b00000; 10527 let Inst{12} = idx{0}; 10528 let Inst{11-10} = size; 10529} 10530class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10531 string asm, dag oops, dag iops> 10532 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10533 "$Rn = $wback", oops, iops, []> { 10534 // idx encoded in Q:S fields. 10535 bits<2> idx; 10536 bits<5> Xm; 10537 let Inst{30} = idx{1}; 10538 let Inst{23} = 1; 10539 let Inst{20-16} = Xm; 10540 let Inst{12} = idx{0}; 10541 let Inst{11-10} = size; 10542} 10543class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10544 string asm, dag oops, dag iops> 10545 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10546 "$Rn = $wback", oops, iops, []> { 10547 // idx encoded in Q:S fields. 10548 bits<2> idx; 10549 bits<5> Xm; 10550 let Inst{30} = idx{1}; 10551 let Inst{23} = 1; 10552 let Inst{20-16} = Xm; 10553 let Inst{12} = idx{0}; 10554 let Inst{11-10} = size; 10555} 10556class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10557 dag oops, dag iops, list<dag> pattern> 10558 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10559 pattern> { 10560 // idx encoded in Q field. 10561 bits<1> idx; 10562 let Inst{30} = idx; 10563 let Inst{23} = 0; 10564 let Inst{20-16} = 0b00000; 10565 let Inst{12} = 0; 10566 let Inst{11-10} = size; 10567} 10568class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10569 dag oops, dag iops, list<dag> pattern> 10570 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10571 oops, iops, pattern> { 10572 // idx encoded in Q field. 10573 bits<1> idx; 10574 let Inst{30} = idx; 10575 let Inst{23} = 0; 10576 let Inst{20-16} = 0b00000; 10577 let Inst{12} = 0; 10578 let Inst{11-10} = size; 10579} 10580class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10581 string asm, dag oops, dag iops> 10582 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10583 "$Rn = $wback", oops, iops, []> { 10584 // idx encoded in Q field. 10585 bits<1> idx; 10586 bits<5> Xm; 10587 let Inst{30} = idx; 10588 let Inst{23} = 1; 10589 let Inst{20-16} = Xm; 10590 let Inst{12} = 0; 10591 let Inst{11-10} = size; 10592} 10593class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10594 string asm, dag oops, dag iops> 10595 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10596 "$Rn = $wback", oops, iops, []> { 10597 // idx encoded in Q field. 10598 bits<1> idx; 10599 bits<5> Xm; 10600 let Inst{30} = idx; 10601 let Inst{23} = 1; 10602 let Inst{20-16} = Xm; 10603 let Inst{12} = 0; 10604 let Inst{11-10} = size; 10605} 10606 10607let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10608multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10609 RegisterOperand listtype, 10610 RegisterOperand GPR64pi> { 10611 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10612 (outs listtype:$dst), 10613 (ins listtype:$Vt, VectorIndexB:$idx, 10614 GPR64sp:$Rn), []>; 10615 10616 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10617 (outs GPR64sp:$wback, listtype:$dst), 10618 (ins listtype:$Vt, VectorIndexB:$idx, 10619 GPR64sp:$Rn, GPR64pi:$Xm)>; 10620} 10621let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10622multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10623 RegisterOperand listtype, 10624 RegisterOperand GPR64pi> { 10625 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10626 (outs listtype:$dst), 10627 (ins listtype:$Vt, VectorIndexH:$idx, 10628 GPR64sp:$Rn), []>; 10629 10630 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10631 (outs GPR64sp:$wback, listtype:$dst), 10632 (ins listtype:$Vt, VectorIndexH:$idx, 10633 GPR64sp:$Rn, GPR64pi:$Xm)>; 10634} 10635let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10636multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10637 RegisterOperand listtype, 10638 RegisterOperand GPR64pi> { 10639 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10640 (outs listtype:$dst), 10641 (ins listtype:$Vt, VectorIndexS:$idx, 10642 GPR64sp:$Rn), []>; 10643 10644 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10645 (outs GPR64sp:$wback, listtype:$dst), 10646 (ins listtype:$Vt, VectorIndexS:$idx, 10647 GPR64sp:$Rn, GPR64pi:$Xm)>; 10648} 10649let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10650multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10651 RegisterOperand listtype, RegisterOperand GPR64pi> { 10652 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10653 (outs listtype:$dst), 10654 (ins listtype:$Vt, VectorIndexD:$idx, 10655 GPR64sp:$Rn), []>; 10656 10657 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10658 (outs GPR64sp:$wback, listtype:$dst), 10659 (ins listtype:$Vt, VectorIndexD:$idx, 10660 GPR64sp:$Rn, GPR64pi:$Xm)>; 10661} 10662let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10663multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10664 RegisterOperand listtype, RegisterOperand GPR64pi> { 10665 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10666 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10667 GPR64sp:$Rn), []>; 10668 10669 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10670 (outs GPR64sp:$wback), 10671 (ins listtype:$Vt, VectorIndexB:$idx, 10672 GPR64sp:$Rn, GPR64pi:$Xm)>; 10673} 10674let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10675multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10676 RegisterOperand listtype, RegisterOperand GPR64pi> { 10677 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10678 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10679 GPR64sp:$Rn), []>; 10680 10681 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10682 (outs GPR64sp:$wback), 10683 (ins listtype:$Vt, VectorIndexH:$idx, 10684 GPR64sp:$Rn, GPR64pi:$Xm)>; 10685} 10686let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10687multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10688 RegisterOperand listtype, RegisterOperand GPR64pi> { 10689 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10690 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10691 GPR64sp:$Rn), []>; 10692 10693 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10694 (outs GPR64sp:$wback), 10695 (ins listtype:$Vt, VectorIndexS:$idx, 10696 GPR64sp:$Rn, GPR64pi:$Xm)>; 10697} 10698let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10699multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10700 RegisterOperand listtype, RegisterOperand GPR64pi> { 10701 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10702 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10703 GPR64sp:$Rn), []>; 10704 10705 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10706 (outs GPR64sp:$wback), 10707 (ins listtype:$Vt, VectorIndexD:$idx, 10708 GPR64sp:$Rn, GPR64pi:$Xm)>; 10709} 10710 10711multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10712 string Count, int Offset, Operand idxtype> { 10713 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10714 // "ld1\t$Vt, [$Rn], #1" 10715 // may get mapped to 10716 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10717 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10718 (!cast<Instruction>(NAME # Type # "_POST") 10719 GPR64sp:$Rn, 10720 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10721 idxtype:$idx, XZR), 1>; 10722 10723 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10724 // "ld1.8b\t$Vt, [$Rn], #1" 10725 // may get mapped to 10726 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10727 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10728 (!cast<Instruction>(NAME # Type # "_POST") 10729 GPR64sp:$Rn, 10730 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10731 idxtype:$idx, XZR), 0>; 10732 10733 // E.g. "ld1.8b { v0 }[0], [x1]" 10734 // "ld1.8b\t$Vt, [$Rn]" 10735 // may get mapped to 10736 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10737 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10738 (!cast<Instruction>(NAME # Type) 10739 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10740 idxtype:$idx, GPR64sp:$Rn), 0>; 10741 10742 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10743 // "ld1.8b\t$Vt, [$Rn], $Xm" 10744 // may get mapped to 10745 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10746 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10747 (!cast<Instruction>(NAME # Type # "_POST") 10748 GPR64sp:$Rn, 10749 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10750 idxtype:$idx, 10751 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10752} 10753 10754multiclass SIMDLdSt1SingleAliases<string asm> { 10755 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10756 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10757 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10758 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10759} 10760 10761multiclass SIMDLdSt2SingleAliases<string asm> { 10762 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10763 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10764 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10765 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10766} 10767 10768multiclass SIMDLdSt3SingleAliases<string asm> { 10769 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10770 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10771 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10772 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10773} 10774 10775multiclass SIMDLdSt4SingleAliases<string asm> { 10776 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10777 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10778 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10779 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10780} 10781} // end of 'let Predicates = [HasNEON]' 10782 10783//---------------------------------------------------------------------------- 10784// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10785//---------------------------------------------------------------------------- 10786 10787let Predicates = [HasNEON, HasRDM] in { 10788 10789class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10790 RegisterOperand regtype, string asm, 10791 string kind, list<dag> pattern> 10792 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10793 pattern> { 10794} 10795multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10796 SDPatternOperator op> { 10797 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10798 [(set (v4i16 V64:$dst), 10799 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 10800 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10801 [(set (v8i16 V128:$dst), 10802 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 10803 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10804 [(set (v2i32 V64:$dst), 10805 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 10806 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10807 [(set (v4i32 V128:$dst), 10808 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 10809} 10810 10811multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10812 SDPatternOperator op> { 10813 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10814 V64, V64, V128_lo, VectorIndexH, 10815 asm, ".4h", ".4h", ".4h", ".h", 10816 [(set (v4i16 V64:$dst), 10817 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10818 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10819 VectorIndexH:$idx)))))]> { 10820 bits<3> idx; 10821 let Inst{11} = idx{2}; 10822 let Inst{21} = idx{1}; 10823 let Inst{20} = idx{0}; 10824 } 10825 10826 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10827 V128, V128, V128_lo, VectorIndexH, 10828 asm, ".8h", ".8h", ".8h", ".h", 10829 [(set (v8i16 V128:$dst), 10830 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10831 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10832 VectorIndexH:$idx)))))]> { 10833 bits<3> idx; 10834 let Inst{11} = idx{2}; 10835 let Inst{21} = idx{1}; 10836 let Inst{20} = idx{0}; 10837 } 10838 10839 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10840 V64, V64, V128, VectorIndexS, 10841 asm, ".2s", ".2s", ".2s", ".s", 10842 [(set (v2i32 V64:$dst), 10843 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10844 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 10845 VectorIndexS:$idx)))))]> { 10846 bits<2> idx; 10847 let Inst{11} = idx{1}; 10848 let Inst{21} = idx{0}; 10849 } 10850 10851 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10852 V128, V128, V128, VectorIndexS, 10853 asm, ".4s", ".4s", ".4s", ".s", 10854 [(set (v4i32 V128:$dst), 10855 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10856 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10857 VectorIndexS:$idx)))))]> { 10858 bits<2> idx; 10859 let Inst{11} = idx{1}; 10860 let Inst{21} = idx{0}; 10861 } 10862 10863 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10864 FPR16Op, FPR16Op, V128_lo, 10865 VectorIndexH, asm, ".h", "", "", ".h", 10866 []> { 10867 bits<3> idx; 10868 let Inst{11} = idx{2}; 10869 let Inst{21} = idx{1}; 10870 let Inst{20} = idx{0}; 10871 } 10872 10873 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10874 FPR32Op, FPR32Op, V128, VectorIndexS, 10875 asm, ".s", "", "", ".s", 10876 [(set (i32 FPR32Op:$dst), 10877 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 10878 (i32 (vector_extract (v4i32 V128:$Rm), 10879 VectorIndexS:$idx)))))]> { 10880 bits<2> idx; 10881 let Inst{11} = idx{1}; 10882 let Inst{21} = idx{0}; 10883 } 10884} 10885} // let Predicates = [HasNeon, HasRDM] 10886 10887//---------------------------------------------------------------------------- 10888// ARMv8.3 Complex ADD/MLA instructions 10889//---------------------------------------------------------------------------- 10890 10891class ComplexRotationOperand<int Angle, int Remainder, string Type> 10892 : AsmOperandClass { 10893 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10894 let DiagnosticType = "InvalidComplexRotation" # Type; 10895 let Name = "ComplexRotation" # Type; 10896} 10897def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10898 SDNodeXForm<imm, [{ 10899 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10900}]>> { 10901 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10902 let PrintMethod = "printComplexRotationOp<90, 0>"; 10903} 10904def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10905 SDNodeXForm<imm, [{ 10906 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10907}]>> { 10908 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10909 let PrintMethod = "printComplexRotationOp<180, 90>"; 10910} 10911let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 10912class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10913 RegisterOperand regtype, Operand rottype, 10914 string asm, string kind, list<dag> pattern> 10915 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10916 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10917 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10918 Sched<[!if(Q, WriteVq, WriteVd)]> { 10919 bits<5> Rd; 10920 bits<5> Rn; 10921 bits<5> Rm; 10922 bits<1> rot; 10923 let Inst{31} = 0; 10924 let Inst{30} = Q; 10925 let Inst{29} = U; 10926 let Inst{28-24} = 0b01110; 10927 let Inst{23-22} = size; 10928 let Inst{21} = 0; 10929 let Inst{20-16} = Rm; 10930 let Inst{15-13} = opcode; 10931 // Non-tied version (FCADD) only has one rotation bit 10932 let Inst{12} = rot; 10933 let Inst{11} = 0; 10934 let Inst{10} = 1; 10935 let Inst{9-5} = Rn; 10936 let Inst{4-0} = Rd; 10937} 10938 10939//8.3 CompNum - Floating-point complex number support 10940multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10941 string asm, SDPatternOperator OpNode>{ 10942 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10943 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10944 asm, ".4h", 10945 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10946 (v4f16 V64:$Rn), 10947 (v4f16 V64:$Rm), 10948 (i32 rottype:$rot)))]>; 10949 10950 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10951 asm, ".8h", 10952 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10953 (v8f16 V128:$Rn), 10954 (v8f16 V128:$Rm), 10955 (i32 rottype:$rot)))]>; 10956 } 10957 10958 let Predicates = [HasComplxNum, HasNEON] in { 10959 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10960 asm, ".2s", 10961 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10962 (v2f32 V64:$Rn), 10963 (v2f32 V64:$Rm), 10964 (i32 rottype:$rot)))]>; 10965 10966 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10967 asm, ".4s", 10968 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10969 (v4f32 V128:$Rn), 10970 (v4f32 V128:$Rm), 10971 (i32 rottype:$rot)))]>; 10972 10973 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10974 asm, ".2d", 10975 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10976 (v2f64 V128:$Rn), 10977 (v2f64 V128:$Rm), 10978 (i32 rottype:$rot)))]>; 10979 } 10980} 10981 10982let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 10983class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10984 bits<3> opcode, 10985 RegisterOperand regtype, 10986 Operand rottype, string asm, 10987 string kind, list<dag> pattern> 10988 : I<(outs regtype:$dst), 10989 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10990 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10991 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10992 Sched<[!if(Q, WriteVq, WriteVd)]> { 10993 bits<5> Rd; 10994 bits<5> Rn; 10995 bits<5> Rm; 10996 bits<2> rot; 10997 let Inst{31} = 0; 10998 let Inst{30} = Q; 10999 let Inst{29} = U; 11000 let Inst{28-24} = 0b01110; 11001 let Inst{23-22} = size; 11002 let Inst{21} = 0; 11003 let Inst{20-16} = Rm; 11004 let Inst{15-13} = opcode; 11005 let Inst{12-11} = rot; 11006 let Inst{10} = 1; 11007 let Inst{9-5} = Rn; 11008 let Inst{4-0} = Rd; 11009} 11010 11011multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 11012 Operand rottype, string asm, 11013 SDPatternOperator OpNode> { 11014 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11015 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 11016 rottype, asm, ".4h", 11017 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11018 (v4f16 V64:$Rn), 11019 (v4f16 V64:$Rm), 11020 (i32 rottype:$rot)))]>; 11021 11022 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 11023 rottype, asm, ".8h", 11024 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11025 (v8f16 V128:$Rn), 11026 (v8f16 V128:$Rm), 11027 (i32 rottype:$rot)))]>; 11028 } 11029 11030 let Predicates = [HasComplxNum, HasNEON] in { 11031 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 11032 rottype, asm, ".2s", 11033 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11034 (v2f32 V64:$Rn), 11035 (v2f32 V64:$Rm), 11036 (i32 rottype:$rot)))]>; 11037 11038 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 11039 rottype, asm, ".4s", 11040 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11041 (v4f32 V128:$Rn), 11042 (v4f32 V128:$Rm), 11043 (i32 rottype:$rot)))]>; 11044 11045 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 11046 rottype, asm, ".2d", 11047 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11048 (v2f64 V128:$Rn), 11049 (v2f64 V128:$Rm), 11050 (i32 rottype:$rot)))]>; 11051 } 11052} 11053 11054let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11055class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 11056 bit opc1, bit opc2, RegisterOperand dst_reg, 11057 RegisterOperand lhs_reg, 11058 RegisterOperand rhs_reg, Operand vec_idx, 11059 Operand rottype, string asm, string apple_kind, 11060 string dst_kind, string lhs_kind, 11061 string rhs_kind, list<dag> pattern> 11062 : I<(outs dst_reg:$dst), 11063 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 11064 asm, 11065 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 11066 "$idx, $rot" # "|" # apple_kind # 11067 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 11068 Sched<[!if(Q, WriteVq, WriteVd)]> { 11069 bits<5> Rd; 11070 bits<5> Rn; 11071 bits<5> Rm; 11072 bits<2> rot; 11073 11074 let Inst{31} = 0; 11075 let Inst{30} = Q; 11076 let Inst{29} = U; 11077 let Inst{28} = Scalar; 11078 let Inst{27-24} = 0b1111; 11079 let Inst{23-22} = size; 11080 // Bit 21 must be set by the derived class. 11081 let Inst{20-16} = Rm; 11082 let Inst{15} = opc1; 11083 let Inst{14-13} = rot; 11084 let Inst{12} = opc2; 11085 // Bit 11 must be set by the derived class. 11086 let Inst{10} = 0; 11087 let Inst{9-5} = Rn; 11088 let Inst{4-0} = Rd; 11089} 11090 11091// The complex instructions index by pairs of elements, so the VectorIndexes 11092// don't match the lane types, and the index bits are different to the other 11093// classes. 11094multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 11095 string asm> { 11096 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11097 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 11098 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 11099 ".4h", ".h", []> { 11100 bits<1> idx; 11101 let Inst{11} = 0; 11102 let Inst{21} = idx{0}; 11103 } 11104 11105 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 11106 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 11107 ".8h", ".8h", ".h", []> { 11108 bits<2> idx; 11109 let Inst{11} = idx{1}; 11110 let Inst{21} = idx{0}; 11111 } 11112 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 11113 11114 let Predicates = [HasComplxNum, HasNEON] in { 11115 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 11116 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 11117 ".4s", ".4s", ".s", []> { 11118 bits<1> idx; 11119 let Inst{11} = idx{0}; 11120 let Inst{21} = 0; 11121 } 11122 } // Predicates = [HasComplxNum, HasNEON] 11123} 11124 11125//---------------------------------------------------------------------------- 11126// Crypto extensions 11127//---------------------------------------------------------------------------- 11128 11129let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11130class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 11131 list<dag> pat> 11132 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 11133 Sched<[WriteVq]>{ 11134 bits<5> Rd; 11135 bits<5> Rn; 11136 let Inst{31-16} = 0b0100111000101000; 11137 let Inst{15-12} = opc; 11138 let Inst{11-10} = 0b10; 11139 let Inst{9-5} = Rn; 11140 let Inst{4-0} = Rd; 11141} 11142 11143class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 11144 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 11145 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 11146 11147class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 11148 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 11149 "$Rd = $dst", 11150 [(set (v16i8 V128:$dst), 11151 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 11152 11153let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11154class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 11155 dag oops, dag iops, list<dag> pat> 11156 : I<oops, iops, asm, 11157 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 11158 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 11159 Sched<[WriteVq]>{ 11160 bits<5> Rd; 11161 bits<5> Rn; 11162 bits<5> Rm; 11163 let Inst{31-21} = 0b01011110000; 11164 let Inst{20-16} = Rm; 11165 let Inst{15} = 0; 11166 let Inst{14-12} = opc; 11167 let Inst{11-10} = 0b00; 11168 let Inst{9-5} = Rn; 11169 let Inst{4-0} = Rd; 11170} 11171 11172class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11173 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11174 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11175 [(set (v4i32 FPR128:$dst), 11176 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11177 (v4i32 V128:$Rm)))]>; 11178 11179class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11180 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11181 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11182 [(set (v4i32 V128:$dst), 11183 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11184 (v4i32 V128:$Rm)))]>; 11185 11186class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11187 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11188 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11189 [(set (v4i32 FPR128:$dst), 11190 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11191 (v4i32 V128:$Rm)))]>; 11192 11193let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11194class SHA2OpInst<bits<4> opc, string asm, string kind, 11195 string cstr, dag oops, dag iops, 11196 list<dag> pat> 11197 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11198 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11199 Sched<[WriteVq]>{ 11200 bits<5> Rd; 11201 bits<5> Rn; 11202 let Inst{31-16} = 0b0101111000101000; 11203 let Inst{15-12} = opc; 11204 let Inst{11-10} = 0b10; 11205 let Inst{9-5} = Rn; 11206 let Inst{4-0} = Rd; 11207} 11208 11209class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11210 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11211 (ins V128:$Rd, V128:$Rn), 11212 [(set (v4i32 V128:$dst), 11213 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11214 11215class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11216 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11217 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11218 11219// Armv8.2-A Crypto extensions 11220class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11221 list<dag> pattern> 11222 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11223 bits<5> Vd; 11224 bits<5> Vn; 11225 let Inst{31-25} = 0b1100111; 11226 let Inst{9-5} = Vn; 11227 let Inst{4-0} = Vd; 11228} 11229 11230class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11231 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11232 "$Vd = $Vdst", []> { 11233 let Inst{31-25} = 0b1100111; 11234 let Inst{24-21} = 0b0110; 11235 let Inst{20-15} = 0b000001; 11236 let Inst{14} = op0; 11237 let Inst{13-12} = 0b00; 11238 let Inst{11-10} = op1; 11239} 11240class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11241 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11242class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11243 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11244 11245class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11246 string asmops, string cst> 11247 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11248 bits<5> Vm; 11249 let Inst{24-21} = 0b0011; 11250 let Inst{20-16} = Vm; 11251 let Inst{15} = 0b1; 11252 let Inst{14} = op0; 11253 let Inst{13-12} = 0b00; 11254 let Inst{11-10} = op1; 11255} 11256class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11257 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11258 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11259class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11260 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11261 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11262class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11263 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11264 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11265class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11266 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11267 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11268class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11269 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11270 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11271 11272class CryptoRRRR<bits<2>op0, string asm, string asmops> 11273 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11274 asmops, "", []> { 11275 bits<5> Vm; 11276 bits<5> Va; 11277 let Inst{24-23} = 0b00; 11278 let Inst{22-21} = op0; 11279 let Inst{20-16} = Vm; 11280 let Inst{15} = 0b0; 11281 let Inst{14-10} = Va; 11282} 11283class CryptoRRRR_16B<bits<2>op0, string asm> 11284 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11285 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11286} 11287class CryptoRRRR_4S<bits<2>op0, string asm> 11288 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11289 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11290} 11291 11292class CryptoRRRi6<string asm> 11293 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11294 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11295 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11296 bits<6> imm; 11297 bits<5> Vm; 11298 let Inst{24-21} = 0b0100; 11299 let Inst{20-16} = Vm; 11300 let Inst{15-10} = imm; 11301 let Inst{9-5} = Vn; 11302 let Inst{4-0} = Vd; 11303} 11304 11305class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11306 : BaseCryptoV82<(outs V128:$Vdst), 11307 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11308 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11309 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11310 bits<2> imm; 11311 bits<5> Vm; 11312 let Inst{24-21} = 0b0010; 11313 let Inst{20-16} = Vm; 11314 let Inst{15} = 0b1; 11315 let Inst{14} = op0; 11316 let Inst{13-12} = imm; 11317 let Inst{11-10} = op1; 11318} 11319 11320//---------------------------------------------------------------------------- 11321// v8.1 atomic instructions extension: 11322// * CAS 11323// * CASP 11324// * SWP 11325// * LDOPregister<OP>, and aliases STOPregister<OP> 11326 11327// Instruction encodings: 11328// 11329// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11330// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11331// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11332// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11333// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11334// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11335 11336// Instruction syntax: 11337// 11338// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11339// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11340// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11341// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11342// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11343// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11344// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11345// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11346// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11347// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11348 11349let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11350class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11351 string cstr, list<dag> pattern> 11352 : I<oops, iops, asm, operands, cstr, pattern> { 11353 bits<2> Sz; 11354 bit NP; 11355 bit Acq; 11356 bit Rel; 11357 bits<5> Rs; 11358 bits<5> Rn; 11359 bits<5> Rt; 11360 let Inst{31-30} = Sz; 11361 let Inst{29-24} = 0b001000; 11362 let Inst{23} = NP; 11363 let Inst{22} = Acq; 11364 let Inst{21} = 0b1; 11365 let Inst{20-16} = Rs; 11366 let Inst{15} = Rel; 11367 let Inst{14-10} = 0b11111; 11368 let Inst{9-5} = Rn; 11369 let Inst{4-0} = Rt; 11370 let Predicates = [HasLSE]; 11371} 11372 11373class BaseCAS<string order, string size, RegisterClass RC> 11374 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11375 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11376 "$out = $Rs",[]>, 11377 Sched<[WriteAtomic]> { 11378 let NP = 1; 11379} 11380 11381multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11382 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11383 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11384 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11385 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11386} 11387 11388class BaseCASP<string order, string size, RegisterOperand RC> 11389 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11390 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11391 "$out = $Rs",[]>, 11392 Sched<[WriteAtomic]> { 11393 let NP = 0; 11394} 11395 11396multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11397 let Sz = 0b00, Acq = Acq, Rel = Rel in 11398 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11399 let Sz = 0b01, Acq = Acq, Rel = Rel in 11400 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11401} 11402 11403let Predicates = [HasLSE] in 11404class BaseSWP<string order, string size, RegisterClass RC> 11405 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11406 "\t$Rs, $Rt, [$Rn]","",[]>, 11407 Sched<[WriteAtomic]> { 11408 bits<2> Sz; 11409 bit Acq; 11410 bit Rel; 11411 bits<5> Rs; 11412 bits<3> opc = 0b000; 11413 bits<5> Rn; 11414 bits<5> Rt; 11415 let Inst{31-30} = Sz; 11416 let Inst{29-24} = 0b111000; 11417 let Inst{23} = Acq; 11418 let Inst{22} = Rel; 11419 let Inst{21} = 0b1; 11420 let Inst{20-16} = Rs; 11421 let Inst{15} = 0b1; 11422 let Inst{14-12} = opc; 11423 let Inst{11-10} = 0b00; 11424 let Inst{9-5} = Rn; 11425 let Inst{4-0} = Rt; 11426 let Predicates = [HasLSE]; 11427} 11428 11429multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11430 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11431 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11432 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11433 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11434} 11435 11436let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11437class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11438 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11439 "\t$Rs, $Rt, [$Rn]","",[]>, 11440 Sched<[WriteAtomic]> { 11441 bits<2> Sz; 11442 bit Acq; 11443 bit Rel; 11444 bits<5> Rs; 11445 bits<3> opc; 11446 bits<5> Rn; 11447 bits<5> Rt; 11448 let Inst{31-30} = Sz; 11449 let Inst{29-24} = 0b111000; 11450 let Inst{23} = Acq; 11451 let Inst{22} = Rel; 11452 let Inst{21} = 0b1; 11453 let Inst{20-16} = Rs; 11454 let Inst{15} = 0b0; 11455 let Inst{14-12} = opc; 11456 let Inst{11-10} = 0b00; 11457 let Inst{9-5} = Rn; 11458 let Inst{4-0} = Rt; 11459 let Predicates = [HasLSE]; 11460} 11461 11462multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11463 string order> { 11464 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11465 def B : BaseLDOPregister<op, order, "b", GPR32>; 11466 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11467 def H : BaseLDOPregister<op, order, "h", GPR32>; 11468 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11469 def W : BaseLDOPregister<op, order, "", GPR32>; 11470 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11471 def X : BaseLDOPregister<op, order, "", GPR64>; 11472} 11473 11474// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11475// complex DAG for DstRHS. 11476let Predicates = [HasLSE] in 11477multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11478 string size, dag SrcRHS, dag DstRHS> { 11479 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11480 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11481 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11482 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11483 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11484 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11485 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11486 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11487 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11488 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11489} 11490 11491multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11492 string size, dag RHS> { 11493 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11494} 11495 11496multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11497 string size, dag LHS, dag RHS> { 11498 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11499} 11500 11501multiclass LDOPregister_patterns<string inst, string op> { 11502 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11503 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11504 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11505 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11506} 11507 11508multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11509 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11510 (i64 GPR64:$Rm), 11511 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11512 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11513 (i32 GPR32:$Rm), 11514 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11515 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11516 (i32 GPR32:$Rm), 11517 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11518 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11519 (i32 GPR32:$Rm), 11520 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11521} 11522 11523let Predicates = [HasLSE] in 11524multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11525 string size, dag OLD, dag NEW> { 11526 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11527 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11528 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11529 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11530 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11531 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11532 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11533 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11534 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11535 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11536} 11537 11538multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11539 string size, dag OLD, dag NEW> { 11540 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11541} 11542 11543multiclass CASregister_patterns<string inst, string op> { 11544 defm : CASregister_patterns_ord<inst, "X", op, "64", 11545 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11546 defm : CASregister_patterns_ord<inst, "W", op, "32", 11547 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11548 defm : CASregister_patterns_ord<inst, "H", op, "16", 11549 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11550 defm : CASregister_patterns_ord<inst, "B", op, "8", 11551 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11552} 11553 11554let Predicates = [HasLSE] in 11555class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11556 Instruction inst> : 11557 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11558 11559multiclass STOPregister<string asm, string instr> { 11560 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11561 !cast<Instruction>(instr # "LB")>; 11562 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11563 !cast<Instruction>(instr # "LH")>; 11564 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11565 !cast<Instruction>(instr # "LW")>; 11566 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11567 !cast<Instruction>(instr # "LX")>; 11568 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11569 !cast<Instruction>(instr # "B")>; 11570 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11571 !cast<Instruction>(instr # "H")>; 11572 def : BaseSTOPregister<asm, GPR32, WZR, 11573 !cast<Instruction>(instr # "W")>; 11574 def : BaseSTOPregister<asm, GPR64, XZR, 11575 !cast<Instruction>(instr # "X")>; 11576} 11577 11578class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11579 dag iops, dag oops, list<dag> pat> 11580 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11581 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11582 bits<5> Rt; 11583 bits<5> Rn; 11584 let Inst{31-21} = 0b11111000001; 11585 let Inst{15} = 1; 11586 let Inst{14-12} = opc; 11587 let Inst{11-10} = 0b00; 11588 let Inst{9-5} = Rn; 11589 let Inst{4-0} = Rt; 11590 11591 let Predicates = [HasV8_7a]; 11592} 11593 11594class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11595 list<dag> pat = []> 11596 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11597 let Inst{20-16} = 0b11111; 11598} 11599 11600class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11601 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11602 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11603 bits<5> Rs; 11604 let Inst{20-16} = Rs; 11605} 11606 11607class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11608 bits<2> op2, string asm> 11609 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11610 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11611 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11612 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11613 Sched<[]> { 11614 bits<5> Rd; 11615 bits<5> Rs; 11616 bits<5> Rn; 11617 let Inst{31-27} = 0b00011; 11618 let Inst{26} = isMove; 11619 let Inst{25-24} = 0b01; 11620 let Inst{23-22} = opcode; 11621 let Inst{21} = 0b0; 11622 let Inst{20-16} = Rs; 11623 let Inst{15-14} = op2; 11624 let Inst{13-12} = op1; 11625 let Inst{11-10} = 0b01; 11626 let Inst{9-5} = Rn; 11627 let Inst{4-0} = Rd; 11628 11629 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11630 let mayLoad = 1; 11631 let mayStore = 1; 11632} 11633 11634class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11635 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11636 11637class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11638 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11639 11640class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11641 string asm> 11642 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11643 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11644 asm, "\t[$Rd]!, $Rn!, $Rm", 11645 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11646 Sched<[]> { 11647 bits<5> Rd; 11648 bits<5> Rn; 11649 bits<5> Rm; 11650 let Inst{31-27} = 0b00011; 11651 let Inst{26} = isTagging; 11652 let Inst{25-21} = 0b01110; 11653 let Inst{20-16} = Rm; 11654 let Inst{15-14} = opcode; 11655 let Inst{13} = op2; 11656 let Inst{12} = op1; 11657 let Inst{11-10} = 0b01; 11658 let Inst{9-5} = Rn; 11659 let Inst{4-0} = Rd; 11660 11661 let DecoderMethod = "DecodeSETMemOpInstruction"; 11662 let mayLoad = 0; 11663 let mayStore = 1; 11664} 11665 11666class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 11667 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 11668 11669class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 11670 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 11671 11672multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 11673 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 11674 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 11675 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 11676 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 11677 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 11678 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 11679 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 11680 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 11681 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 11682 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 11683 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 11684 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 11685 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 11686 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 11687 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 11688 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 11689} 11690 11691multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 11692 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 11693 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 11694 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 11695 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 11696 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 11697 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 11698 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 11699 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 11700 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 11701 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 11702 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 11703 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 11704 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 11705 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 11706 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 11707 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 11708} 11709 11710multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 11711 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 11712 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 11713 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 11714 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 11715} 11716 11717multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 11718 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 11719 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 11720 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 11721 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 11722} 11723 11724//---------------------------------------------------------------------------- 11725// 2022 Armv8.9/Armv9.4 Extensions 11726//---------------------------------------------------------------------------- 11727 11728//--- 11729// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC) 11730//--- 11731 11732class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc, 11733 RegisterClass regtype, ImmLeaf immtype, string asm, 11734 SDPatternOperator OpNode> 11735 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm), 11736 asm, "\t$Rd, $Rn, $imm", "", 11737 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> { 11738 bits<5> Rd; 11739 bits<5> Rn; 11740 bits<8> imm; 11741 11742 let Inst{31} = sf; 11743 let Inst{30} = Op; 11744 let Inst{29} = S; 11745 let Inst{28-22} = 0b1000111; 11746 let Inst{21-18} = opc; 11747 let Inst{17-10} = imm; 11748 let Inst{9-5} = Rn; 11749 let Inst{4-0} = Rd; 11750} 11751 11752class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin, 11753 RegisterClass regtype, string asm, 11754 SDPatternOperator OpNode> 11755 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>, 11756 Sched<[WriteI]> { 11757 let Inst{11} = isMin; 11758 let Inst{10} = isUnsigned; 11759 let mayLoad = 0; 11760 let mayStore = 0; 11761 let hasSideEffects = 0; 11762} 11763 11764class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin, 11765 RegisterClass regtype, ImmLeaf immtype, string asm, 11766 SDPatternOperator OpNode> 11767 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm, 11768 OpNode>, 11769 Sched<[]> { 11770 let Inst{19} = isMin; 11771 let Inst{18} = isUnsigned; 11772 let mayLoad = 0; 11773 let mayStore = 0; 11774 let hasSideEffects = 0; 11775} 11776 11777multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm, 11778 SDPatternOperator OpNode = null_frag> { 11779 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>; 11780 11781 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32, 11782 !cond(isUnsigned : uimm8_32b, 11783 !not(isUnsigned) : simm8_32b), asm, OpNode>; 11784 11785 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>; 11786 11787 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64, 11788 !cond(isUnsigned : uimm8_64b, 11789 !not(isUnsigned) : simm8_64b), asm, OpNode>; 11790} 11791 11792//--- 11793// RCPC instructions (FEAT_LRCPC3) 11794//--- 11795 11796class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops, 11797 string asm, string operands, string cstr = ""> 11798 : I<oops, iops, asm, operands, cstr, []>, 11799 Sched<[WriteAtomic]> { 11800 bits<5> Rt; 11801 bits<5> Rn; 11802 let Inst{31-30} = size; 11803 let Inst{29-24} = {0,1,1,V,0,1}; 11804 let Inst{23-22} = opc; 11805 let Inst{21} = 0b0; 11806 // Inst{20-12} 11807 let Inst{11-10} = 0b10; 11808 let Inst{9-5} = Rn; 11809 let Inst{4-0} = Rt; 11810 11811 let mayLoad = Inst{22}; 11812 let mayStore = !not(Inst{22}); 11813 let hasSideEffects = 0; 11814} 11815 11816class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2, 11817 dag oops, dag iops, string asm, 11818 string operands, string cstr> 11819 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 11820 bits<5> Rt2; 11821 let Inst{20-16} = Rt2; 11822 let Inst{15-12} = opc2; 11823} 11824 11825class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops, 11826 string asm, string operands, string cstr> 11827 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 11828 let Inst{20-12} = 0b000000000; // imm9 11829} 11830 11831multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype, 11832 dag oops, dag iops, string asm> { 11833 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> { 11834 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 11835 let Inst{20-12} = simm; 11836 } 11837 11838 def a : InstAlias<asm # "\t$Rt, [$Rn]", 11839 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 11840} 11841 11842class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst> 11843 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm, 11844 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>, 11845 Sched<[]> { 11846 bit Q; 11847 let Inst{31} = 0; 11848 let Inst{30} = Q; 11849 let Inst{23} = 0; 11850 let Inst{20-16} = 0b00001; 11851 let Inst{12} = 0; // S 11852 let Inst{11-10} = 0b01; // size 11853 11854 let mayLoad = L; 11855 let mayStore = !not(L); 11856 let hasSideEffects = 1; 11857} 11858 11859//--- 11860// Instrumentation Extension (FEAT_ITE) 11861//--- 11862 11863let Predicates = [HasITE] in 11864def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> { 11865 let Inst{20-19} = 0b01; 11866 let Inst{18-16} = 0b011; 11867 let Inst{15-12} = 0b0111; 11868 let Inst{11-8} = 0b0010; 11869 let Inst{7-5} = 0b111; 11870} 11871 11872// * RCWCAS family 11873// * RCW<OP> family 11874 11875//-------------------------------------------------------------------- 11876// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?) 11877 11878// Instruction encoding: 11879// 11880// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0 11881// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 11882// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 11883// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 11884// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 11885 11886// Instruction syntax: 11887// 11888// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11889// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>] 11890 11891class BaseRCWCASEncoding<dag oops, dag iops, string asm> 11892 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>, 11893 Sched<[]> { 11894 bit Acq; 11895 bit Rel; 11896 bit SC; 11897 bit Pair; 11898 bits<5> Rs; 11899 bits<5> Rn; 11900 bits<5> Rt; 11901 let Inst{31} = 0b0; 11902 let Inst{30} = SC; 11903 let Inst{29-24} = 0b011001; 11904 let Inst{23} = Acq; 11905 let Inst{22} = Rel; 11906 let Inst{21} = 0b1; 11907 let Inst{20-16} = Rs; 11908 let Inst{15-13} = 0b000; 11909 let Inst{12-11} = 0b01; 11910 let Inst{10} = Pair; 11911 let Inst{9-5} = Rn; 11912 let Inst{4-0} = Rt; 11913 let mayLoad = 1; 11914 let mayStore = 1; 11915 let hasSideEffects = 1; 11916 let Defs = [NZCV]; 11917} 11918 11919multiclass BaseRCWCAS<dag oops, dag iops, string prefix> { 11920 let Acq = 0b0, Rel = 0b0 in 11921 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">; 11922 let Acq = 0b1, Rel = 0b0 in 11923 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">; 11924 let Acq = 0b0, Rel = 0b1 in 11925 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">; 11926 let Acq = 0b1, Rel = 0b1 in 11927 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">; 11928} 11929 11930multiclass ReadCheckWriteCompareAndSwap { 11931 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in 11932 defm CAS : BaseRCWCAS<(outs GPR64:$out), 11933 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >; 11934 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in 11935 defm SCAS : BaseRCWCAS<(outs GPR64:$out), 11936 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">; 11937 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in 11938 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out), 11939 (ins XSeqPairClassOperand:$Rs, 11940 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 11941 "rcwcasp">; 11942 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in 11943 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out), 11944 (ins XSeqPairClassOperand:$Rs, 11945 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 11946 "rcwscasp">; 11947} 11948 11949//------------------------------------------------------------------ 11950// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?) 11951 11952// Instruction encoding: 11953// 11954// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 11955// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 11956// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 11957// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 11958// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 11959// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 11960// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 11961 11962// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 11963// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 11964// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 11965// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 11966// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 11967// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 11968// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 11969 11970// Instruction syntax: 11971// 11972// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11973// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>] 11974 11975class BaseRCWOPEncoding<string asm> 11976 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm, 11977 "\t$Rs, $Rt, [$Rn]", "", []>, 11978 Sched<[]> { 11979 bit Acq; 11980 bit Rel; 11981 bit SC; 11982 bits<3> opc; 11983 bits<5> Rs; 11984 bits<5> Rn; 11985 bits<5> Rt; 11986 let Inst{31} = 0b0; 11987 let Inst{30} = SC; 11988 let Inst{29-24} = 0b111000; 11989 let Inst{23} = Acq; 11990 let Inst{22} = Rel; 11991 let Inst{21} = 0b1; 11992 let Inst{20-16} = Rs; 11993 let Inst{15} = 0b1; 11994 let Inst{14-12} = opc; 11995 let Inst{11-10} = 0b00; 11996 let Inst{9-5} = Rn; 11997 let Inst{4-0} = Rt; 11998 let mayLoad = 1; 11999 let mayStore = 1; 12000 let hasSideEffects = 1; 12001 let Defs = [NZCV]; 12002 let Predicates = [HasTHE]; 12003} 12004 12005class BaseRCWOPPEncoding<string asm> 12006 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12007 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm, 12008 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12009 Sched<[]> { 12010 bit Acq; 12011 bit Rel; 12012 bit SC; 12013 bits<3> opc; 12014 bits<5> Rt2; 12015 bits<5> Rn; 12016 bits<5> Rt; 12017 let Inst{31} = 0b0; 12018 let Inst{30} = SC; 12019 let Inst{29-24} = 0b011001; 12020 let Inst{23} = Acq; 12021 let Inst{22} = Rel; 12022 let Inst{21} = 0b1; 12023 let Inst{20-16} = Rt2; 12024 let Inst{15} = 0b1; 12025 let Inst{14-12} = opc; 12026 let Inst{11-10} = 0b00; 12027 let Inst{9-5} = Rn; 12028 let Inst{4-0} = Rt; 12029 let mayLoad = 1; 12030 let mayStore = 1; 12031 let hasSideEffects = 1; 12032 let Defs = [NZCV]; 12033 let Predicates = [HasTHE, HasD128]; 12034} 12035 12036multiclass BaseRCWOP<string prefix> { 12037 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">; 12038 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">; 12039 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">; 12040 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">; 12041 12042 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">; 12043 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">; 12044 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">; 12045 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">; 12046} 12047 12048multiclass ReadCheckWriteOperation<bits<3> opc, string op> { 12049 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>; 12050 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >; 12051} 12052 12053//--- 12054// 128-bit atomic instructions (FEAT_LSE128) 12055//--- 12056 12057let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in 12058class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm> 12059: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12060 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), 12061 asm, "\t$Rt, $Rt2, [$Rn]", 12062 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12063 Sched<[]> { 12064 bits<5> Rt; 12065 bits<5> Rt2; 12066 bits<5> Rn; 12067 let Inst{31-24} = 0b00011001; 12068 let Inst{23-22} = AR; 12069 let Inst{21} = 0b1; 12070 let Inst{20-16} = Rt2; 12071 let Inst{15} = o3; 12072 let Inst{14-12} = op0; 12073 let Inst{11-10} = 0b00; 12074 let Inst{9-5} = Rn; 12075 let Inst{4-0} = Rt; 12076} 12077 12078//--- 12079// 128-bit System Instructions (FEAT_SYSINSTR128) 12080//--- 12081 12082// Instruction encoding: 12083// 12084// 31 19|18 16|15 12|11 8|7 5|4 0 12085// SYSP 1101010101001| op1| Cn| Cm|op2| Rt 12086 12087// Instruction syntax: 12088// 12089// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>} 12090 12091class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> : 12092 RtSystemI<L, oops, iops, asm, operands, pattern> { 12093 let Inst{22} = 0b1; // override BaseSystemI 12094} 12095 12096class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs> 12097 : RtSystemI128<L, outputs, inputs, asm, operands> { 12098 bits<3> op1; 12099 bits<4> Cn; 12100 bits<4> Cm; 12101 bits<3> op2; 12102 let Inst{20-19} = 0b01; 12103 let Inst{18-16} = op1; 12104 let Inst{15-12} = Cn; 12105 let Inst{11-8} = Cm; 12106 let Inst{7-5} = op2; 12107} 12108class SystemPXtI<bit L, string asm> : 12109 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs), 12110 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>; 12111 12112 12113//---------------------------------------------------------------------------- 12114// Allow the size specifier tokens to be upper case, not just lower. 12115def : TokenAlias<".4B", ".4b">; // Add dot product 12116def : TokenAlias<".8B", ".8b">; 12117def : TokenAlias<".4H", ".4h">; 12118def : TokenAlias<".2S", ".2s">; 12119def : TokenAlias<".1D", ".1d">; 12120def : TokenAlias<".16B", ".16b">; 12121def : TokenAlias<".8H", ".8h">; 12122def : TokenAlias<".4S", ".4s">; 12123def : TokenAlias<".2D", ".2d">; 12124def : TokenAlias<".1Q", ".1q">; 12125def : TokenAlias<".2H", ".2h">; 12126def : TokenAlias<".B", ".b">; 12127def : TokenAlias<".H", ".h">; 12128def : TokenAlias<".S", ".s">; 12129def : TokenAlias<".D", ".d">; 12130def : TokenAlias<".Q", ".q">; 12131