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 gi_extract_high_v16i8 : 137 GIComplexOperandMatcher<v8s8, "selectExtractHigh">, 138 GIComplexPatternEquiv<extract_high_v16i8>; 139def gi_extract_high_v8i16 : 140 GIComplexOperandMatcher<v4s16, "selectExtractHigh">, 141 GIComplexPatternEquiv<extract_high_v8i16>; 142def gi_extract_high_v4i32 : 143 GIComplexOperandMatcher<v2s32, "selectExtractHigh">, 144 GIComplexPatternEquiv<extract_high_v4i32>; 145 146def extract_high_v8f16 : 147 ComplexPattern<v4f16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 148def extract_high_v8bf16 : 149 ComplexPattern<v4bf16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 150def extract_high_v4f32 : 151 ComplexPattern<v2f32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 152def extract_high_v2f64 : 153 ComplexPattern<v1f64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 154 155def gi_extract_high_v8f16 : 156 GIComplexOperandMatcher<v4s16, "selectExtractHigh">, 157 GIComplexPatternEquiv<extract_high_v8f16>; 158def gi_extract_high_v4f32 : 159 GIComplexOperandMatcher<v2s32, "selectExtractHigh">, 160 GIComplexPatternEquiv<extract_high_v4f32>; 161 162def extract_high_dup_v8i16 : 163 BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>; 164def extract_high_dup_v4i32 : 165 BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>; 166 167def dup_v8i16 : 168 PatFrags<(ops node:$LHS, node:$RHS), 169 [(v4i16 (extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 0))), 170 (v4i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS))]>; 171def dup_v4i32 : 172 PatFrags<(ops node:$LHS, node:$RHS), 173 [(v2i32 (extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 0))), 174 (v2i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS))]>; 175def dup_v8f16 : 176 PatFrags<(ops node:$LHS, node:$RHS), 177 [(v4f16 (extract_subvector (v8f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS)), (i64 0))), 178 (v4f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS))]>; 179def dup_v4f32 : 180 PatFrags<(ops node:$LHS, node:$RHS), 181 [(v2f32 (extract_subvector (v4f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS)), (i64 0))), 182 (v2f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS))]>; 183 184// Match either a scalar_to_vector (from SDAG) or a vector_insert of undef (from GISel) 185def vec_ins_or_scal_vec : PatFrags<(ops node:$src), 186 [(vector_insert undef, node:$src, (i64 0)), 187 (scalar_to_vector node:$src)]>; 188 189//===----------------------------------------------------------------------===// 190// Asm Operand Classes. 191// 192 193// Shifter operand for arithmetic shifted encodings. 194def ShifterOperand : AsmOperandClass { 195 let Name = "Shifter"; 196} 197 198// Shifter operand for mov immediate encodings. 199def MovImm32ShifterOperand : AsmOperandClass { 200 let SuperClasses = [ShifterOperand]; 201 let Name = "MovImm32Shifter"; 202 let RenderMethod = "addShifterOperands"; 203 let DiagnosticType = "InvalidMovImm32Shift"; 204} 205def MovImm64ShifterOperand : AsmOperandClass { 206 let SuperClasses = [ShifterOperand]; 207 let Name = "MovImm64Shifter"; 208 let RenderMethod = "addShifterOperands"; 209 let DiagnosticType = "InvalidMovImm64Shift"; 210} 211 212// Shifter operand for arithmetic register shifted encodings. 213class ArithmeticShifterOperand<int width> : AsmOperandClass { 214 let SuperClasses = [ShifterOperand]; 215 let Name = "ArithmeticShifter" # width; 216 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 217 let RenderMethod = "addShifterOperands"; 218 let DiagnosticType = "AddSubRegShift" # width; 219} 220 221def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 222def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 223 224// Shifter operand for logical register shifted encodings. 225class LogicalShifterOperand<int width> : AsmOperandClass { 226 let SuperClasses = [ShifterOperand]; 227 let Name = "LogicalShifter" # width; 228 let PredicateMethod = "isLogicalShifter<" # width # ">"; 229 let RenderMethod = "addShifterOperands"; 230 let DiagnosticType = "AddSubRegShift" # width; 231} 232 233def LogicalShifterOperand32 : LogicalShifterOperand<32>; 234def LogicalShifterOperand64 : LogicalShifterOperand<64>; 235 236// Shifter operand for logical vector 128/64-bit shifted encodings. 237def LogicalVecShifterOperand : AsmOperandClass { 238 let SuperClasses = [ShifterOperand]; 239 let Name = "LogicalVecShifter"; 240 let RenderMethod = "addShifterOperands"; 241} 242def LogicalVecHalfWordShifterOperand : AsmOperandClass { 243 let SuperClasses = [LogicalVecShifterOperand]; 244 let Name = "LogicalVecHalfWordShifter"; 245 let RenderMethod = "addShifterOperands"; 246} 247 248// The "MSL" shifter on the vector MOVI instruction. 249def MoveVecShifterOperand : AsmOperandClass { 250 let SuperClasses = [ShifterOperand]; 251 let Name = "MoveVecShifter"; 252 let RenderMethod = "addShifterOperands"; 253} 254 255// Extend operand for arithmetic encodings. 256def ExtendOperand : AsmOperandClass { 257 let Name = "Extend"; 258 let DiagnosticType = "AddSubRegExtendLarge"; 259} 260def ExtendOperand64 : AsmOperandClass { 261 let SuperClasses = [ExtendOperand]; 262 let Name = "Extend64"; 263 let DiagnosticType = "AddSubRegExtendSmall"; 264} 265// 'extend' that's a lsl of a 64-bit register. 266def ExtendOperandLSL64 : AsmOperandClass { 267 let SuperClasses = [ExtendOperand]; 268 let Name = "ExtendLSL64"; 269 let RenderMethod = "addExtend64Operands"; 270 let DiagnosticType = "AddSubRegExtendLarge"; 271} 272 273// 8-bit floating-point immediate encodings. 274def FPImmOperand : AsmOperandClass { 275 let Name = "FPImm"; 276 let ParserMethod = "tryParseFPImm<true>"; 277 let DiagnosticType = "InvalidFPImm"; 278} 279 280def CondCode : AsmOperandClass { 281 let Name = "CondCode"; 282 let DiagnosticType = "InvalidCondCode"; 283} 284 285// A 32-bit register pasrsed as 64-bit 286def GPR32as64Operand : AsmOperandClass { 287 let Name = "GPR32as64"; 288 let ParserMethod = 289 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 290} 291def GPR32as64 : RegisterOperand<GPR32> { 292 let ParserMatchClass = GPR32as64Operand; 293} 294 295// A 64-bit register pasrsed as 32-bit 296def GPR64as32Operand : AsmOperandClass { 297 let Name = "GPR64as32"; 298 let ParserMethod = 299 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 300} 301def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 302 let ParserMatchClass = GPR64as32Operand; 303} 304 305// 8-bit immediate for AdvSIMD where 64-bit values of the form: 306// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 307// are encoded as the eight bit value 'abcdefgh'. 308def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 309 310class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 311 let Name = "UImm" # Width # "s" # Scale; 312 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 313 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 314 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 315} 316 317class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 318 let Name = "SImm" # Width # "s" # Scale; 319 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 320 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 321 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 322} 323 324//===----------------------------------------------------------------------===// 325// Operand Definitions. 326// 327 328// ADR[P] instruction labels. 329def AdrpOperand : AsmOperandClass { 330 let Name = "AdrpLabel"; 331 let ParserMethod = "tryParseAdrpLabel"; 332 let DiagnosticType = "InvalidLabel"; 333} 334def adrplabel : Operand<i64> { 335 let EncoderMethod = "getAdrLabelOpValue"; 336 let PrintMethod = "printAdrAdrpLabel"; 337 let ParserMatchClass = AdrpOperand; 338 let OperandType = "OPERAND_PCREL"; 339} 340 341def AdrOperand : AsmOperandClass { 342 let Name = "AdrLabel"; 343 let ParserMethod = "tryParseAdrLabel"; 344 let DiagnosticType = "InvalidLabel"; 345} 346def adrlabel : Operand<i64> { 347 let EncoderMethod = "getAdrLabelOpValue"; 348 let PrintMethod = "printAdrAdrpLabel"; 349 let ParserMatchClass = AdrOperand; 350 let OperandType = "OPERAND_PCREL"; 351} 352 353class SImmOperand<int width> : AsmOperandClass { 354 let Name = "SImm" # width; 355 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 356 let RenderMethod = "addImmOperands"; 357 let PredicateMethod = "isSImm<" # width # ">"; 358} 359 360class AsmImmRange<int Low, int High> : AsmOperandClass { 361 let Name = "Imm" # Low # "_" # High; 362 let DiagnosticType = "InvalidImm" # Low # "_" # High; 363 let RenderMethod = "addImmOperands"; 364 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 365} 366 367// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 368def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 369def simm10Scaled : Operand<i64> { 370 let ParserMatchClass = SImm10s8Operand; 371 let DecoderMethod = "DecodeSImm<10>"; 372 let PrintMethod = "printImmScale<8>"; 373} 374 375def simm9s16 : Operand<i64> { 376 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 377 let DecoderMethod = "DecodeSImm<9>"; 378 let PrintMethod = "printImmScale<16>"; 379} 380 381// uimm6 predicate - True if the immediate is in the range [0, 63]. 382def UImm6Operand : AsmOperandClass { 383 let Name = "UImm6"; 384 let DiagnosticType = "InvalidImm0_63"; 385} 386 387def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 388 let ParserMatchClass = UImm6Operand; 389} 390 391def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 392 let ParserMatchClass = AsmImmRange<0, 65535>; 393} 394 395def uimm6_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 396 let ParserMatchClass = UImm6Operand; 397} 398 399def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> { 400 let ParserMatchClass = UImm6Operand; 401} 402 403def UImm6Plus1Operand : AsmOperandClass { 404 let Name = "UImm6P1"; 405 let DiagnosticType = "InvalidImm1_64"; 406 let RenderMethod = "addImmOperands"; 407 let ParserMethod = "tryParseAdjImm0_63<-1>"; 408 let PredicateMethod = "isImmInRange<0,63>"; 409} 410 411def UImm6Minus1Operand : AsmOperandClass { 412 let Name = "UImm6M1"; 413 let DiagnosticType = "InvalidImmM1_62"; 414 let RenderMethod = "addImmOperands"; 415 let ParserMethod = "tryParseAdjImm0_63<1>"; 416 let PredicateMethod = "isImmInRange<0,63>"; 417} 418 419def uimm6p1_32b : Operand<i32> { 420 let ParserMatchClass = UImm6Plus1Operand; 421} 422 423def uimm6p1_64b : Operand<i64> { 424 let ParserMatchClass = UImm6Plus1Operand; 425} 426 427def uimm6m1_32b : Operand<i32> { 428 let ParserMatchClass = UImm6Minus1Operand; 429} 430 431def uimm6m1_64b : Operand<i64> { 432 let ParserMatchClass = UImm6Minus1Operand; 433} 434 435def SImm9Operand : SImmOperand<9>; 436def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 437 let ParserMatchClass = SImm9Operand; 438 let DecoderMethod = "DecodeSImm<9>"; 439} 440 441// imm0_255 predicate - True if the immediate is in the range [0,255]. 442def Imm0_255Operand : AsmImmRange<0,255>; 443 444def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 445 let ParserMatchClass = Imm0_255Operand; 446} 447def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> { 448 let ParserMatchClass = Imm0_255Operand; 449} 450 451def SImm8Operand : SImmOperand<8>; 452def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 453 let ParserMatchClass = SImm8Operand; 454 let DecoderMethod = "DecodeSImm<8>"; 455} 456def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> { 457 let ParserMatchClass = SImm8Operand; 458 let DecoderMethod = "DecodeSImm<8>"; 459} 460 461def SImm6Operand : SImmOperand<6>; 462def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 463 let ParserMatchClass = SImm6Operand; 464 let DecoderMethod = "DecodeSImm<6>"; 465} 466 467def SImm5Operand : SImmOperand<5>; 468def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 469 let ParserMatchClass = SImm5Operand; 470 let DecoderMethod = "DecodeSImm<5>"; 471} 472 473def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 474 let ParserMatchClass = SImm5Operand; 475 let DecoderMethod = "DecodeSImm<5>"; 476} 477 478def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 479 let ParserMatchClass = SImm5Operand; 480 let DecoderMethod = "DecodeSImm<5>"; 481 let PrintMethod = "printSImm<8>"; 482} 483 484def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 485 let ParserMatchClass = SImm5Operand; 486 let DecoderMethod = "DecodeSImm<5>"; 487 let PrintMethod = "printSImm<16>"; 488} 489 490// simm7sN predicate - True if the immediate is a multiple of N in the range 491// [-64 * N, 63 * N]. 492 493def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 494def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 495def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 496 497def simm7s4 : Operand<i32> { 498 let ParserMatchClass = SImm7s4Operand; 499 let PrintMethod = "printImmScale<4>"; 500} 501 502def simm7s8 : Operand<i32> { 503 let ParserMatchClass = SImm7s8Operand; 504 let PrintMethod = "printImmScale<8>"; 505} 506 507def simm7s16 : Operand<i32> { 508 let ParserMatchClass = SImm7s16Operand; 509 let PrintMethod = "printImmScale<16>"; 510} 511 512def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>; 513 514def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>; 515def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>; 516def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>; 517def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>; 518def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>; 519 520def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>; 521def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>; 522 523def UImmS1XForm : SDNodeXForm<imm, [{ 524 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 525}]>; 526def UImmS2XForm : SDNodeXForm<imm, [{ 527 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 528}]>; 529def UImmS4XForm : SDNodeXForm<imm, [{ 530 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 531}]>; 532def UImmS8XForm : SDNodeXForm<imm, [{ 533 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 534}]>; 535 536def UImmM2XForm : SDNodeXForm<imm, [{ 537 return CurDAG->getTargetConstant(N->getZExtValue() * 2, SDLoc(N), MVT::i32); 538}]>; 539 540def UImmM4XForm : SDNodeXForm<imm, [{ 541 return CurDAG->getTargetConstant(N->getZExtValue() * 4, SDLoc(N), MVT::i32); 542}]>; 543 544def UImmM8XForm : SDNodeXForm<imm, [{ 545 return CurDAG->getTargetConstant(N->getZExtValue() * 8, SDLoc(N), MVT::i32); 546}]>; 547 548// uimm5sN predicate - True if the immediate is a multiple of N in the range 549// [0 * N, 32 * N]. 550def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 551def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 552def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 553 554def uimm5s2 : Operand<i64>, ImmLeaf<i64, 555 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 556 UImmS2XForm> { 557 let ParserMatchClass = UImm5s2Operand; 558 let PrintMethod = "printImmScale<2>"; 559} 560def uimm5s4 : Operand<i64>, ImmLeaf<i64, 561 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 562 UImmS4XForm> { 563 let ParserMatchClass = UImm5s4Operand; 564 let PrintMethod = "printImmScale<4>"; 565} 566def uimm5s8 : Operand<i64>, ImmLeaf<i64, 567 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 568 UImmS8XForm> { 569 let ParserMatchClass = UImm5s8Operand; 570 let PrintMethod = "printImmScale<8>"; 571} 572 573// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 574// instead of ImmLeaf (Constant) 575def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 576 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 577 UImmS2XForm> { 578 let ParserMatchClass = UImm5s2Operand; 579 let PrintMethod = "printImmScale<2>"; 580} 581def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 582 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 583 UImmS4XForm> { 584 let ParserMatchClass = UImm5s4Operand; 585 let PrintMethod = "printImmScale<4>"; 586} 587def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 588 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 589 UImmS8XForm> { 590 let ParserMatchClass = UImm5s8Operand; 591 let PrintMethod = "printImmScale<8>"; 592} 593 594// uimm6sN predicate - True if the immediate is a multiple of N in the range 595// [0 * N, 64 * N]. 596def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 597def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 598def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 599def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 600def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 601 602def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 603 let ParserMatchClass = UImm6s1Operand; 604} 605def uimm6s2 : Operand<i64>, ImmLeaf<i64, 606[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 607 let PrintMethod = "printImmScale<2>"; 608 let ParserMatchClass = UImm6s2Operand; 609} 610def uimm6s4 : Operand<i64>, ImmLeaf<i64, 611[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 612 let PrintMethod = "printImmScale<4>"; 613 let ParserMatchClass = UImm6s4Operand; 614} 615def uimm6s8 : Operand<i64>, ImmLeaf<i64, 616[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 617 let PrintMethod = "printImmScale<8>"; 618 let ParserMatchClass = UImm6s8Operand; 619} 620def uimm6s16 : Operand<i64>, ImmLeaf<i64, 621[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 622 let PrintMethod = "printImmScale<16>"; 623 let ParserMatchClass = UImm6s16Operand; 624} 625 626def SImmS2XForm : SDNodeXForm<imm, [{ 627 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 628}]>; 629def SImmS3XForm : SDNodeXForm<imm, [{ 630 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 631}]>; 632def SImmS4XForm : SDNodeXForm<imm, [{ 633 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 634}]>; 635def SImmS16XForm : SDNodeXForm<imm, [{ 636 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 637}]>; 638def SImmS32XForm : SDNodeXForm<imm, [{ 639 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 640}]>; 641 642// simm6sN predicate - True if the immediate is a multiple of N in the range 643// [-32 * N, 31 * N]. 644def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 645def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 646 let ParserMatchClass = SImm6s1Operand; 647 let DecoderMethod = "DecodeSImm<6>"; 648} 649 650// simm4sN predicate - True if the immediate is a multiple of N in the range 651// [ -8* N, 7 * N]. 652def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 653def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 654def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 655def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 656def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 657def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 658 659def simm4s1 : Operand<i64>, ImmLeaf<i64, 660[{ return Imm >=-8 && Imm <= 7; }]> { 661 let ParserMatchClass = SImm4s1Operand; 662 let DecoderMethod = "DecodeSImm<4>"; 663} 664 665def simm4s2 : Operand<i64>, ImmLeaf<i64, 666[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 667 let PrintMethod = "printImmScale<2>"; 668 let ParserMatchClass = SImm4s2Operand; 669 let DecoderMethod = "DecodeSImm<4>"; 670} 671 672def simm4s3 : Operand<i64>, ImmLeaf<i64, 673[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 674 let PrintMethod = "printImmScale<3>"; 675 let ParserMatchClass = SImm4s3Operand; 676 let DecoderMethod = "DecodeSImm<4>"; 677} 678 679def simm4s4 : Operand<i64>, ImmLeaf<i64, 680[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 681 let PrintMethod = "printImmScale<4>"; 682 let ParserMatchClass = SImm4s4Operand; 683 let DecoderMethod = "DecodeSImm<4>"; 684} 685def simm4s16 : Operand<i64>, ImmLeaf<i64, 686[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 687 let PrintMethod = "printImmScale<16>"; 688 let ParserMatchClass = SImm4s16Operand; 689 let DecoderMethod = "DecodeSImm<4>"; 690} 691def simm4s32 : Operand<i64>, ImmLeaf<i64, 692[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 693 let PrintMethod = "printImmScale<32>"; 694 let ParserMatchClass = SImm4s32Operand; 695 let DecoderMethod = "DecodeSImm<4>"; 696} 697 698def Imm1_8Operand : AsmImmRange<1, 8>; 699def Imm1_16Operand : AsmImmRange<1, 16>; 700def Imm1_32Operand : AsmImmRange<1, 32>; 701def Imm1_64Operand : AsmImmRange<1, 64>; 702 703class BranchTarget<int N> : AsmOperandClass { 704 let Name = "BranchTarget" # N; 705 let DiagnosticType = "InvalidLabel"; 706 let PredicateMethod = "isBranchTarget<" # N # ">"; 707} 708 709class PCRelLabel<int N> : BranchTarget<N> { 710 let Name = "PCRelLabel" # N; 711} 712 713def BranchTarget14Operand : BranchTarget<14>; 714def BranchTarget26Operand : BranchTarget<26>; 715def PCRelLabel19Operand : PCRelLabel<19>; 716def PCRelLabel9Operand : PCRelLabel<9>; 717 718def MovWSymbolG3AsmOperand : AsmOperandClass { 719 let Name = "MovWSymbolG3"; 720 let RenderMethod = "addImmOperands"; 721} 722 723def movw_symbol_g3 : Operand<i32> { 724 let ParserMatchClass = MovWSymbolG3AsmOperand; 725} 726 727def MovWSymbolG2AsmOperand : AsmOperandClass { 728 let Name = "MovWSymbolG2"; 729 let RenderMethod = "addImmOperands"; 730} 731 732def movw_symbol_g2 : Operand<i32> { 733 let ParserMatchClass = MovWSymbolG2AsmOperand; 734} 735 736def MovWSymbolG1AsmOperand : AsmOperandClass { 737 let Name = "MovWSymbolG1"; 738 let RenderMethod = "addImmOperands"; 739} 740 741def movw_symbol_g1 : Operand<i32> { 742 let ParserMatchClass = MovWSymbolG1AsmOperand; 743} 744 745def MovWSymbolG0AsmOperand : AsmOperandClass { 746 let Name = "MovWSymbolG0"; 747 let RenderMethod = "addImmOperands"; 748} 749 750def movw_symbol_g0 : Operand<i32> { 751 let ParserMatchClass = MovWSymbolG0AsmOperand; 752} 753 754class fixedpoint_i32<ValueType FloatVT> 755 : Operand<FloatVT>, 756 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 757 let EncoderMethod = "getFixedPointScaleOpValue"; 758 let DecoderMethod = "DecodeFixedPointScaleImm32"; 759 let ParserMatchClass = Imm1_32Operand; 760} 761 762class fixedpoint_i64<ValueType FloatVT> 763 : Operand<FloatVT>, 764 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 765 let EncoderMethod = "getFixedPointScaleOpValue"; 766 let DecoderMethod = "DecodeFixedPointScaleImm64"; 767 let ParserMatchClass = Imm1_64Operand; 768} 769 770def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 771def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 772def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 773 774def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 775def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 776def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 777 778class fixedpoint_recip_i32<ValueType FloatVT> 779 : Operand<FloatVT>, 780 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> { 781 let EncoderMethod = "getFixedPointScaleOpValue"; 782 let DecoderMethod = "DecodeFixedPointScaleImm32"; 783} 784 785class fixedpoint_recip_i64<ValueType FloatVT> 786 : Operand<FloatVT>, 787 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<64>", [fpimm, ld]> { 788 let EncoderMethod = "getFixedPointScaleOpValue"; 789 let DecoderMethod = "DecodeFixedPointScaleImm64"; 790} 791 792def fixedpoint_recip_f16_i32 : fixedpoint_recip_i32<f16>; 793def fixedpoint_recip_f32_i32 : fixedpoint_recip_i32<f32>; 794def fixedpoint_recip_f64_i32 : fixedpoint_recip_i32<f64>; 795 796def fixedpoint_recip_f16_i64 : fixedpoint_recip_i64<f16>; 797def fixedpoint_recip_f32_i64 : fixedpoint_recip_i64<f32>; 798def fixedpoint_recip_f64_i64 : fixedpoint_recip_i64<f64>; 799 800def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 801 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 802}]> { 803 let EncoderMethod = "getVecShiftR8OpValue"; 804 let DecoderMethod = "DecodeVecShiftR8Imm"; 805 let ParserMatchClass = Imm1_8Operand; 806} 807def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 808 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 809}]> { 810 let EncoderMethod = "getVecShiftR16OpValue"; 811 let DecoderMethod = "DecodeVecShiftR16Imm"; 812 let ParserMatchClass = Imm1_16Operand; 813} 814def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 815 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 816}]> { 817 let EncoderMethod = "getVecShiftR16OpValue"; 818 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 819 let ParserMatchClass = Imm1_8Operand; 820} 821def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 822 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 823}]> { 824 let EncoderMethod = "getVecShiftR32OpValue"; 825 let DecoderMethod = "DecodeVecShiftR32Imm"; 826 let ParserMatchClass = Imm1_32Operand; 827} 828def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 829 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 830}]> { 831 let EncoderMethod = "getVecShiftR32OpValue"; 832 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 833 let ParserMatchClass = Imm1_16Operand; 834} 835def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 836 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 837}]> { 838 let EncoderMethod = "getVecShiftR64OpValue"; 839 let DecoderMethod = "DecodeVecShiftR64Imm"; 840 let ParserMatchClass = Imm1_64Operand; 841} 842def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 843 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 844}]> { 845 let EncoderMethod = "getVecShiftR64OpValue"; 846 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 847 let ParserMatchClass = Imm1_32Operand; 848} 849 850// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 851// (ImmLeaf) 852def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 853 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 854}]> { 855 let EncoderMethod = "getVecShiftR8OpValue"; 856 let DecoderMethod = "DecodeVecShiftR8Imm"; 857 let ParserMatchClass = Imm1_8Operand; 858} 859def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 860 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 861}]> { 862 let EncoderMethod = "getVecShiftR16OpValue"; 863 let DecoderMethod = "DecodeVecShiftR16Imm"; 864 let ParserMatchClass = Imm1_16Operand; 865} 866def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 867 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 868}]> { 869 let EncoderMethod = "getVecShiftR32OpValue"; 870 let DecoderMethod = "DecodeVecShiftR32Imm"; 871 let ParserMatchClass = Imm1_32Operand; 872} 873def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 874 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 875}]> { 876 let EncoderMethod = "getVecShiftR64OpValue"; 877 let DecoderMethod = "DecodeVecShiftR64Imm"; 878 let ParserMatchClass = Imm1_64Operand; 879} 880 881def Imm0_0Operand : AsmImmRange<0, 0>; 882def Imm0_1Operand : AsmImmRange<0, 1>; 883def Imm1_1Operand : AsmImmRange<1, 1>; 884def Imm0_3Operand : AsmImmRange<0, 3>; 885def Imm1_3Operand : AsmImmRange<1, 3>; 886def Imm0_7Operand : AsmImmRange<0, 7>; 887def Imm1_7Operand : AsmImmRange<1, 7>; 888def Imm0_15Operand : AsmImmRange<0, 15>; 889def Imm0_31Operand : AsmImmRange<0, 31>; 890def Imm0_63Operand : AsmImmRange<0, 63>; 891 892def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 893 return (((uint32_t)Imm) < 8); 894}]> { 895 let EncoderMethod = "getVecShiftL8OpValue"; 896 let DecoderMethod = "DecodeVecShiftL8Imm"; 897 let ParserMatchClass = Imm0_7Operand; 898} 899def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 900 return (((uint32_t)Imm) < 16); 901}]> { 902 let EncoderMethod = "getVecShiftL16OpValue"; 903 let DecoderMethod = "DecodeVecShiftL16Imm"; 904 let ParserMatchClass = Imm0_15Operand; 905} 906def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 907 return (((uint32_t)Imm) < 32); 908}]> { 909 let EncoderMethod = "getVecShiftL32OpValue"; 910 let DecoderMethod = "DecodeVecShiftL32Imm"; 911 let ParserMatchClass = Imm0_31Operand; 912} 913def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 914 return (((uint32_t)Imm) < 64); 915}]> { 916 let EncoderMethod = "getVecShiftL64OpValue"; 917 let DecoderMethod = "DecodeVecShiftL64Imm"; 918 let ParserMatchClass = Imm0_63Operand; 919} 920 921// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 922// (ImmLeaf) 923def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 924 return (((uint32_t)Imm) < 8); 925}]> { 926 let EncoderMethod = "getVecShiftL8OpValue"; 927 let DecoderMethod = "DecodeVecShiftL8Imm"; 928 let ParserMatchClass = Imm0_7Operand; 929} 930def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 931 return (((uint32_t)Imm) < 16); 932}]> { 933 let EncoderMethod = "getVecShiftL16OpValue"; 934 let DecoderMethod = "DecodeVecShiftL16Imm"; 935 let ParserMatchClass = Imm0_15Operand; 936} 937def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 938 return (((uint32_t)Imm) < 32); 939}]> { 940 let EncoderMethod = "getVecShiftL32OpValue"; 941 let DecoderMethod = "DecodeVecShiftL32Imm"; 942 let ParserMatchClass = Imm0_31Operand; 943} 944def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 945 return (((uint32_t)Imm) < 64); 946}]> { 947 let EncoderMethod = "getVecShiftL64OpValue"; 948 let DecoderMethod = "DecodeVecShiftL64Imm"; 949 let ParserMatchClass = Imm0_63Operand; 950} 951 952// Crazy immediate formats used by 32-bit and 64-bit logical immediate 953// instructions for splatting repeating bit patterns across the immediate. 954def logical_imm32_XFORM : SDNodeXForm<imm, [{ 955 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 956 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 957}]>; 958def logical_imm64_XFORM : SDNodeXForm<imm, [{ 959 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 960 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 961}]>; 962 963def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 964 GISDNodeXFormEquiv<logical_imm32_XFORM>; 965def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 966 GISDNodeXFormEquiv<logical_imm64_XFORM>; 967 968let DiagnosticType = "LogicalSecondSource" in { 969 def LogicalImm32Operand : AsmOperandClass { 970 let Name = "LogicalImm32"; 971 let PredicateMethod = "isLogicalImm<int32_t>"; 972 let RenderMethod = "addLogicalImmOperands<int32_t>"; 973 } 974 def LogicalImm64Operand : AsmOperandClass { 975 let Name = "LogicalImm64"; 976 let PredicateMethod = "isLogicalImm<int64_t>"; 977 let RenderMethod = "addLogicalImmOperands<int64_t>"; 978 } 979 def LogicalImm32NotOperand : AsmOperandClass { 980 let Name = "LogicalImm32Not"; 981 let PredicateMethod = "isLogicalImm<int32_t>"; 982 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 983 } 984 def LogicalImm64NotOperand : AsmOperandClass { 985 let Name = "LogicalImm64Not"; 986 let PredicateMethod = "isLogicalImm<int64_t>"; 987 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 988 } 989} 990 991def Imm0_127Operand : AsmImmRange<0, 127>; 992 993let OperandType = "OPERAND_IMMEDIATE" in { 994 995def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 996 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 997}], logical_imm32_XFORM> { 998 let PrintMethod = "printLogicalImm<int32_t>"; 999 let ParserMatchClass = LogicalImm32Operand; 1000} 1001def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 1002 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 1003}], logical_imm64_XFORM> { 1004 let PrintMethod = "printLogicalImm<int64_t>"; 1005 let ParserMatchClass = LogicalImm64Operand; 1006} 1007def logical_imm32_not : Operand<i32> { 1008 let ParserMatchClass = LogicalImm32NotOperand; 1009} 1010def logical_imm64_not : Operand<i64> { 1011 let ParserMatchClass = LogicalImm64NotOperand; 1012} 1013 1014// immXX_0_65535 predicates - True if the immediate is in the range [0,65535]. 1015let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 1016def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{ 1017 return ((uint32_t)Imm) < 65536; 1018}]>; 1019 1020def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{ 1021 return ((uint64_t)Imm) < 65536; 1022}]>; 1023 1024def imm64_0_65535 : Operand<i64>, ImmLeaf<i64, [{ 1025 return ((uint64_t)Imm) < 65536; 1026}]>; 1027} // ParserMatchClass 1028 1029def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 1030 return ((uint32_t)Imm) < 256; 1031}]> { 1032 let ParserMatchClass = Imm0_255Operand; 1033 let PrintMethod = "printImm"; 1034} 1035 1036// imm0_127 predicate - True if the immediate is in the range [0,127] 1037def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 1038 return ((uint32_t)Imm) < 128; 1039}]> { 1040 let ParserMatchClass = Imm0_127Operand; 1041 let PrintMethod = "printImm"; 1042} 1043 1044def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 1045 return ((uint64_t)Imm) < 128; 1046}]> { 1047 let ParserMatchClass = Imm0_127Operand; 1048 let PrintMethod = "printImm"; 1049} 1050 1051// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 1052// for all shift-amounts. 1053 1054// imm0_63 predicate - True if the immediate is in the range [0,63] 1055def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 1056 return ((uint64_t)Imm) < 64; 1057}]> { 1058 let ParserMatchClass = Imm0_63Operand; 1059} 1060 1061def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 1062 return ((uint64_t)Imm) < 64; 1063}]> { 1064 let ParserMatchClass = Imm0_63Operand; 1065} 1066 1067// imm0_31 predicate - True if the immediate is in the range [0,31] 1068def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 1069 return ((uint64_t)Imm) < 32; 1070}]> { 1071 let ParserMatchClass = Imm0_31Operand; 1072} 1073 1074// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 1075// instead of Constant (ImmLeaf) 1076def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 1077 return ((uint64_t)Imm) < 32; 1078}]> { 1079 let ParserMatchClass = Imm0_31Operand; 1080} 1081 1082// True if the 32-bit immediate is in the range [0,31] 1083def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 1084 return ((uint64_t)Imm) < 32; 1085}]> { 1086 let ParserMatchClass = Imm0_31Operand; 1087} 1088 1089// imm0_1 predicate - True if the immediate is in the range [0,1] 1090def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 1091 return ((uint64_t)Imm) < 2; 1092}]> { 1093 let ParserMatchClass = Imm0_1Operand; 1094} 1095 1096// timm0_1 - as above, but use TargetConstant (TImmLeaf) 1097def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 1098 return ((uint64_t)Imm) < 2; 1099}]> { 1100 let ParserMatchClass = Imm0_1Operand; 1101} 1102 1103// timm32_0_0 predicate - True if the 32-bit immediate is in the range [0,0] 1104def timm32_0_0 : Operand<i32>, TImmLeaf<i32, [{ 1105 return ((uint32_t)Imm) == 0; 1106}]> { 1107 let ParserMatchClass = Imm0_0Operand; 1108} 1109 1110// timm32_0_1 predicate - True if the 32-bit immediate is in the range [0,1] 1111def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{ 1112 return ((uint32_t)Imm) < 2; 1113}]> { 1114 let ParserMatchClass = Imm0_1Operand; 1115} 1116 1117// extq_timm32_0_1m8 - True if the 32-bit immediate is in the range [0,1], scale this immediate 1118// by a factor of 8 after a match is made. 1119def extq_timm32_0_1m8 : Operand<i32>, TImmLeaf<i32, [{ 1120 return ((uint32_t)Imm) < 2;}], UImmM8XForm> { 1121 let ParserMatchClass = Imm0_15Operand; 1122} 1123 1124// timm32_1_1 - True if the 32-bit immediate is in the range [1,1] 1125def timm32_1_1 : Operand<i32>, TImmLeaf<i32, [{ 1126 return ((uint32_t)Imm) == 1; 1127}]> { 1128 let ParserMatchClass = Imm1_1Operand; 1129} 1130 1131// timm32_1_3 predicate - True if the 32-bit immediate is in the range [1,3] 1132def timm32_1_3 : Operand<i32>, TImmLeaf<i32, [{ 1133 return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 4; 1134}]> { 1135 let ParserMatchClass = Imm1_3Operand; 1136} 1137 1138// imm0_15 predicate - True if the immediate is in the range [0,15] 1139def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 1140 return ((uint64_t)Imm) < 16; 1141}]> { 1142 let ParserMatchClass = Imm0_15Operand; 1143} 1144 1145// imm0_7 predicate - True if the immediate is in the range [0,7] 1146def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 1147 return ((uint64_t)Imm) < 8; 1148}]> { 1149 let ParserMatchClass = Imm0_7Operand; 1150} 1151 1152// imm0_3 predicate - True if the immediate is in the range [0,3] 1153def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 1154 return ((uint64_t)Imm) < 4; 1155}]> { 1156 let ParserMatchClass = Imm0_3Operand; 1157} 1158 1159// timm32_0_3 predicate - True if the 32-bit immediate is in the range [0,3] 1160def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{ 1161 return ((uint32_t)Imm) < 4; 1162}]> { 1163 let ParserMatchClass = Imm0_3Operand; 1164} 1165 1166// extq_timm32_0_3m4 - True if the 32-bit immediate is in the range [0,3], scale this immediate 1167// by a factor of 4 after a match is made. 1168def extq_timm32_0_3m4 : Operand<i32>, TImmLeaf<i32, [{ 1169 return ((uint32_t)Imm) < 4;}], UImmM4XForm> { 1170 let ParserMatchClass = Imm0_15Operand; 1171} 1172 1173// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 1174def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 1175 return ((uint32_t)Imm) < 8; 1176}]> { 1177 let ParserMatchClass = Imm0_7Operand; 1178} 1179 1180// extq_timm32_0_7m2 - True if the 32-bit immediate is in the range [0,7], scale this immediate 1181// by a factor of 2 after a match is made. 1182def extq_timm32_0_7m2 : Operand<i32>, TImmLeaf<i32, [{ 1183 return ((uint32_t)Imm) < 8;}], UImmM2XForm> { 1184 let ParserMatchClass = Imm0_15Operand; 1185} 1186 1187// timm32_1_7 predicate - True if the 32-bit immediate is in the range [1,7] 1188def timm32_1_7 : Operand<i32>, TImmLeaf<i32, [{ 1189 return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 8; 1190}]> { 1191 let ParserMatchClass = Imm1_7Operand; 1192} 1193 1194// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 1195def imm32_0_7 : Operand<i32>, ImmLeaf<i32, [{ 1196 return ((uint32_t)Imm) < 8; 1197}]> { 1198 let ParserMatchClass = Imm0_7Operand; 1199} 1200 1201// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1202def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 1203 return ((uint32_t)Imm) < 16; 1204}]> { 1205 let ParserMatchClass = Imm0_15Operand; 1206} 1207 1208// timm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1209def timm32_0_15 : Operand<i32>, TImmLeaf<i32, [{ 1210 return ((uint32_t)Imm) < 16; 1211}]> { 1212 let ParserMatchClass = Imm0_15Operand; 1213} 1214 1215// timm32_0_31 predicate - True if the 32-bit immediate is in the range [0,31] 1216def timm32_0_31 : Operand<i32>, TImmLeaf<i32, [{ 1217 return ((uint32_t)Imm) < 32; 1218}]> { 1219 let ParserMatchClass = Imm0_31Operand; 1220} 1221 1222// timm32_0_255 predicate - True if the 32-bit immediate is in the range [0,255] 1223def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{ 1224 return ((uint32_t)Imm) < 256; 1225}]> { 1226 let ParserMatchClass = Imm0_255Operand; 1227} 1228 1229} // let OperandType = "OPERAND_IMMEDIATE" 1230 1231// An arithmetic shifter operand: 1232// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 1233// {5-0} - imm6 1234class arith_shift<ValueType Ty, int width> : Operand<Ty> { 1235 let PrintMethod = "printShifter"; 1236 let ParserMatchClass = !cast<AsmOperandClass>( 1237 "ArithmeticShifterOperand" # width); 1238} 1239 1240def arith_shift32 : arith_shift<i32, 32>; 1241def arith_shift64 : arith_shift<i64, 64>; 1242 1243class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 1244 : Operand<Ty>, 1245 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 1246 let PrintMethod = "printShiftedRegister"; 1247 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 1248} 1249 1250def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 1251def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 1252 1253def gi_arith_shifted_reg32 : 1254 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 1255 GIComplexPatternEquiv<arith_shifted_reg32>; 1256 1257def gi_arith_shifted_reg64 : 1258 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1259 GIComplexPatternEquiv<arith_shifted_reg64>; 1260 1261// An arithmetic shifter operand: 1262// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1263// {5-0} - imm6 1264class logical_shift<int width> : Operand<i32> { 1265 let PrintMethod = "printShifter"; 1266 let ParserMatchClass = !cast<AsmOperandClass>( 1267 "LogicalShifterOperand" # width); 1268} 1269 1270def logical_shift32 : logical_shift<32>; 1271def logical_shift64 : logical_shift<64>; 1272 1273class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1274 : Operand<Ty>, 1275 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1276 let PrintMethod = "printShiftedRegister"; 1277 let MIOperandInfo = (ops regclass, shiftop); 1278} 1279 1280def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1281def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1282 1283def gi_logical_shifted_reg32 : 1284 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1285 GIComplexPatternEquiv<logical_shifted_reg32>; 1286 1287def gi_logical_shifted_reg64 : 1288 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1289 GIComplexPatternEquiv<logical_shifted_reg64>; 1290 1291// A logical vector shifter operand: 1292// {7-6} - shift type: 00 = lsl 1293// {5-0} - imm6: #0, #8, #16, or #24 1294def logical_vec_shift : Operand<i32> { 1295 let PrintMethod = "printShifter"; 1296 let EncoderMethod = "getVecShifterOpValue"; 1297 let ParserMatchClass = LogicalVecShifterOperand; 1298} 1299 1300// A logical vector half-word shifter operand: 1301// {7-6} - shift type: 00 = lsl 1302// {5-0} - imm6: #0 or #8 1303def logical_vec_hw_shift : Operand<i32> { 1304 let PrintMethod = "printShifter"; 1305 let EncoderMethod = "getVecShifterOpValue"; 1306 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1307} 1308 1309// A vector move shifter operand: 1310// {0} - imm1: #8 or #16 1311def move_vec_shift : Operand<i32> { 1312 let PrintMethod = "printShifter"; 1313 let EncoderMethod = "getMoveVecShifterOpValue"; 1314 let ParserMatchClass = MoveVecShifterOperand; 1315} 1316 1317let DiagnosticType = "AddSubSecondSource" in { 1318 def AddSubImmOperand : AsmOperandClass { 1319 let Name = "AddSubImm"; 1320 let ParserMethod = "tryParseImmWithOptionalShift"; 1321 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1322 } 1323 def AddSubImmNegOperand : AsmOperandClass { 1324 let Name = "AddSubImmNeg"; 1325 let ParserMethod = "tryParseImmWithOptionalShift"; 1326 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1327 } 1328} 1329// An ADD/SUB immediate shifter operand: 1330// second operand: 1331// {7-6} - shift type: 00 = lsl 1332// {5-0} - imm6: #0 or #12 1333class addsub_shifted_imm<ValueType Ty> 1334 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1335 let PrintMethod = "printAddSubImm"; 1336 let EncoderMethod = "getAddSubImmOpValue"; 1337 let ParserMatchClass = AddSubImmOperand; 1338 let MIOperandInfo = (ops i32imm, i32imm); 1339} 1340 1341class addsub_shifted_imm_neg<ValueType Ty> 1342 : Operand<Ty> { 1343 let EncoderMethod = "getAddSubImmOpValue"; 1344 let ParserMatchClass = AddSubImmNegOperand; 1345 let MIOperandInfo = (ops i32imm, i32imm); 1346} 1347 1348def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1349def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1350def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1351def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1352 1353def gi_addsub_shifted_imm32 : 1354 GIComplexOperandMatcher<s32, "selectArithImmed">, 1355 GIComplexPatternEquiv<addsub_shifted_imm32>; 1356 1357def gi_addsub_shifted_imm64 : 1358 GIComplexOperandMatcher<s64, "selectArithImmed">, 1359 GIComplexPatternEquiv<addsub_shifted_imm64>; 1360 1361class neg_addsub_shifted_imm<ValueType Ty> 1362 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1363 let PrintMethod = "printAddSubImm"; 1364 let EncoderMethod = "getAddSubImmOpValue"; 1365 let ParserMatchClass = AddSubImmOperand; 1366 let MIOperandInfo = (ops i32imm, i32imm); 1367} 1368 1369def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1370def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1371 1372def gi_neg_addsub_shifted_imm32 : 1373 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1374 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1375 1376def gi_neg_addsub_shifted_imm64 : 1377 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1378 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1379 1380// An extend operand: 1381// {5-3} - extend type 1382// {2-0} - imm3 1383def arith_extend : Operand<i32> { 1384 let PrintMethod = "printArithExtend"; 1385 let ParserMatchClass = ExtendOperand; 1386} 1387def arith_extend64 : Operand<i32> { 1388 let PrintMethod = "printArithExtend"; 1389 let ParserMatchClass = ExtendOperand64; 1390} 1391 1392// 'extend' that's a lsl of a 64-bit register. 1393def arith_extendlsl64 : Operand<i32> { 1394 let PrintMethod = "printArithExtend"; 1395 let ParserMatchClass = ExtendOperandLSL64; 1396} 1397 1398class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1399 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1400 let PrintMethod = "printExtendedRegister"; 1401 let MIOperandInfo = (ops GPR32, arith_extend); 1402} 1403 1404class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1405 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1406 let PrintMethod = "printExtendedRegister"; 1407 let MIOperandInfo = (ops GPR32, arith_extend64); 1408} 1409 1410def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1411def gi_arith_extended_reg32_i32 : 1412 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1413 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1414 1415def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1416def gi_arith_extended_reg32_i64 : 1417 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1418 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1419 1420def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1421def gi_arith_extended_reg32to64_i64 : 1422 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1423 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1424 1425def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>; 1426 1427// Floating-point immediate. 1428 1429def fpimm16XForm : SDNodeXForm<fpimm, [{ 1430 uint32_t Enc = AArch64_AM::getFP16Imm(N->getValueAPF()); 1431 return CurDAG->getTargetConstant(Enc, SDLoc(N), MVT::i32); 1432 }]>; 1433 1434def fpimm32XForm : SDNodeXForm<fpimm, [{ 1435 uint32_t Enc = AArch64_AM::getFP32Imm(N->getValueAPF()); 1436 return CurDAG->getTargetConstant(Enc, SDLoc(N), MVT::i32); 1437 }]>; 1438 1439def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{ 1440 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF() 1441 .bitcastToAPInt() 1442 .getZExtValue()); 1443 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1444 }]>; 1445 1446def fpimm64XForm : SDNodeXForm<fpimm, [{ 1447 uint32_t Enc = AArch64_AM::getFP64Imm(N->getValueAPF()); 1448 return CurDAG->getTargetConstant(Enc, SDLoc(N), MVT::i32); 1449 }]>; 1450 1451def fpimm16 : Operand<f16>, 1452 FPImmLeaf<f16, [{ 1453 return AArch64_AM::getFP16Imm(Imm) != -1; 1454 }], fpimm16XForm> { 1455 let ParserMatchClass = FPImmOperand; 1456 let PrintMethod = "printFPImmOperand"; 1457} 1458 1459def fpimmbf16 : Operand<bf16>, 1460 FPImmLeaf<bf16, [{ 1461 return AArch64_AM::getFP16Imm(Imm) != -1; 1462 }], fpimm16XForm>; 1463 1464def fpimm32 : Operand<f32>, 1465 FPImmLeaf<f32, [{ 1466 return AArch64_AM::getFP32Imm(Imm) != -1; 1467 }], fpimm32XForm> { 1468 let ParserMatchClass = FPImmOperand; 1469 let PrintMethod = "printFPImmOperand"; 1470} 1471 1472def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{ 1473 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue(); 1474 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc); 1475 }], fpimm32SIMDModImmType4XForm> { 1476} 1477 1478def fpimm64 : Operand<f64>, 1479 FPImmLeaf<f64, [{ 1480 return AArch64_AM::getFP64Imm(Imm) != -1; 1481 }], fpimm64XForm> { 1482 let ParserMatchClass = FPImmOperand; 1483 let PrintMethod = "printFPImmOperand"; 1484} 1485 1486def fpimm8 : Operand<i32> { 1487 let ParserMatchClass = FPImmOperand; 1488 let PrintMethod = "printFPImmOperand"; 1489} 1490 1491def fpimm0 : FPImmLeaf<fAny, [{ 1492 return Imm.isExactlyValue(+0.0); 1493}]>; 1494 1495def fpimm_minus0 : FPImmLeaf<fAny, [{ 1496 return Imm.isExactlyValue(-0.0); 1497}]>; 1498 1499def fpimm_half : FPImmLeaf<fAny, [{ 1500 return Imm.isExactlyValue(+0.5); 1501}]>; 1502 1503def fpimm_one : FPImmLeaf<fAny, [{ 1504 return Imm.isExactlyValue(+1.0); 1505}]>; 1506 1507def fpimm_two : FPImmLeaf<fAny, [{ 1508 return Imm.isExactlyValue(+2.0); 1509}]>; 1510 1511def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1512 GISDNodeXFormEquiv<fpimm16XForm>; 1513def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1514 GISDNodeXFormEquiv<fpimm32XForm>; 1515def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1516 GISDNodeXFormEquiv<fpimm64XForm>; 1517def gi_fpimm32SIMDModImmType4 : 1518 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1519 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1520 1521// Vector lane operands 1522class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1523 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1524 let DiagnosticType = "Invalid" # Name; 1525 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1526 let RenderMethod = "addVectorIndexOperands"; 1527} 1528 1529class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1530 : Operand<ty> { 1531 let ParserMatchClass = mc; 1532 let PrintMethod = "printVectorIndex"; 1533} 1534 1535multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1536 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1537 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1538} 1539 1540def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1541def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1542def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1543def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1544def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1545def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1546 1547let OperandNamespace = "AArch64" in { 1548 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1549 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1550 [{ return ((uint64_t)Imm) == 0; }]>; 1551 defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand, 1552 [{ return ((uint32_t)Imm) == 0; }]>; 1553 } 1554} 1555defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1556 [{ return ((uint64_t)Imm) == 1; }]>; 1557defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1558 [{ return ((uint64_t)Imm) < 16; }]>; 1559defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1560 [{ return ((uint64_t)Imm) < 8; }]>; 1561defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1562 [{ return ((uint64_t)Imm) < 4; }]>; 1563defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1564 [{ return ((uint64_t)Imm) < 2; }]>; 1565 1566defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1567 [{ return ((uint64_t)Imm) == 1; }]>; 1568defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1569 [{ return ((uint64_t)Imm) < 16; }]>; 1570defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1571 [{ return ((uint64_t)Imm) < 8; }]>; 1572defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1573 [{ return ((uint64_t)Imm) < 4; }]>; 1574defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1575 [{ return ((uint64_t)Imm) < 2; }]>; 1576 1577def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1578def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1579def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1580def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1581def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1582 1583defm sve_elm_idx_extdup_b 1584 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1585 [{ return ((uint64_t)Imm) < 64; }]>; 1586defm sve_elm_idx_extdup_h 1587 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1588 [{ return ((uint64_t)Imm) < 32; }]>; 1589defm sve_elm_idx_extdup_s 1590 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1591 [{ return ((uint64_t)Imm) < 16; }]>; 1592defm sve_elm_idx_extdup_d 1593 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1594 [{ return ((uint64_t)Imm) < 8; }]>; 1595defm sve_elm_idx_extdup_q 1596 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1597 [{ return ((uint64_t)Imm) < 4; }]>; 1598 1599def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{ 1600 return ((uint32_t)Imm) == 0; 1601}]> { 1602 let ParserMatchClass = Imm0_0Operand; 1603 let PrintMethod = "printMatrixIndex"; 1604 let OperandNamespace = "AArch64"; 1605 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1606} 1607def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{ 1608 return ((uint32_t)Imm) <= 1; 1609}]> { 1610 let ParserMatchClass = Imm0_1Operand; 1611 let PrintMethod = "printMatrixIndex"; 1612} 1613def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{ 1614 return ((uint32_t)Imm) <= 3; 1615}]> { 1616 let ParserMatchClass = Imm0_3Operand; 1617 let PrintMethod = "printMatrixIndex"; 1618} 1619def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{ 1620 return ((uint32_t)Imm) <= 7; 1621}]> { 1622 let ParserMatchClass = Imm0_7Operand; 1623 let PrintMethod = "printMatrixIndex"; 1624} 1625def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{ 1626 return ((uint32_t)Imm) <= 15; 1627}]> { 1628 let ParserMatchClass = Imm0_15Operand; 1629 let PrintMethod = "printMatrixIndex"; 1630} 1631 1632// SME2 vector select offset operands 1633 1634// uimm3s8 predicate 1635// True if the immediate is a multiple of 8 in the range [0,56]. 1636def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>; 1637 1638def uimm3s8 : Operand<i64>, ImmLeaf<i64, 1639[{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> { 1640 let PrintMethod = "printMatrixIndex<8>"; 1641 let ParserMatchClass = UImm3s8Operand; 1642} 1643 1644class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass { 1645 let Name = "UImm" # Width # "s" # Scale # "Range"; 1646 let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width; 1647 let RenderMethod = "addImmScaledRangeOperands<" # Scale # ">"; 1648 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ", " # OffsetVal # ", /*IsRange=*/true>"; 1649 let ParserMethod = "tryParseImmRange"; 1650} 1651 1652// Implicit immediate ranges 0:1 and 0:3, scale has no meaning 1653// since the immediate is zero 1654def UImm0s2RangeOperand : UImmScaledMemoryIndexedRange<0, 2, 1>; 1655def UImm0s4RangeOperand : UImmScaledMemoryIndexedRange<0, 4, 3>; 1656 1657def UImm1s2RangeOperand : UImmScaledMemoryIndexedRange<1, 2, 1>; 1658def UImm1s4RangeOperand : UImmScaledMemoryIndexedRange<1, 4, 3>; 1659def UImm2s2RangeOperand : UImmScaledMemoryIndexedRange<2, 2, 1>; 1660def UImm2s4RangeOperand : UImmScaledMemoryIndexedRange<2, 4, 3>; 1661def UImm3s2RangeOperand : UImmScaledMemoryIndexedRange<3, 2, 1>; 1662 1663def uimm0s2range : Operand<i64>, ImmLeaf<i64, 1664[{ return Imm == 0; }], UImmS1XForm> { 1665 let PrintMethod = "printImmRangeScale<2, 1>"; 1666 let ParserMatchClass = UImm0s2RangeOperand; 1667 let OperandNamespace = "AArch64"; 1668 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1669} 1670 1671def uimm0s4range : Operand<i64>, ImmLeaf<i64, 1672[{ return Imm == 0; }], UImmS1XForm> { 1673 let PrintMethod = "printImmRangeScale<4, 3>"; 1674 let ParserMatchClass = UImm0s4RangeOperand; 1675 let OperandNamespace = "AArch64"; 1676 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1677} 1678 1679def uimm1s2range : Operand<i64>, ImmLeaf<i64, 1680[{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> { 1681 let PrintMethod = "printImmRangeScale<2, 1>"; 1682 let ParserMatchClass = UImm1s2RangeOperand; 1683} 1684 1685def uimm1s4range : Operand<i64>, ImmLeaf<i64, 1686[{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> { 1687 let PrintMethod = "printImmRangeScale<4, 3>"; 1688 let ParserMatchClass = UImm1s4RangeOperand; 1689} 1690 1691def uimm2s2range : Operand<i64>, ImmLeaf<i64, 1692[{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> { 1693 let PrintMethod = "printImmRangeScale<2, 1>"; 1694 let ParserMatchClass = UImm2s2RangeOperand; 1695} 1696 1697def uimm2s4range : Operand<i64>, ImmLeaf<i64, 1698[{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> { 1699 let PrintMethod = "printImmRangeScale<4, 3>"; 1700 let ParserMatchClass = UImm2s4RangeOperand; 1701} 1702 1703def uimm3s2range : Operand<i64>, ImmLeaf<i64, 1704[{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> { 1705 let PrintMethod = "printImmRangeScale<2, 1>"; 1706 let ParserMatchClass = UImm3s2RangeOperand; 1707} 1708 1709 1710// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1711// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1712// are encoded as the eight bit value 'abcdefgh'. 1713def simdimmtype10 : Operand<i32>, 1714 FPImmLeaf<f64, [{ 1715 return AArch64_AM::isAdvSIMDModImmType10( 1716 Imm.bitcastToAPInt().getZExtValue()); 1717 }], SDNodeXForm<fpimm, [{ 1718 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1719 .bitcastToAPInt() 1720 .getZExtValue()); 1721 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1722 }]>> { 1723 let ParserMatchClass = SIMDImmType10Operand; 1724 let PrintMethod = "printSIMDType10Operand"; 1725} 1726 1727 1728//--- 1729// System management 1730//--- 1731 1732// Base encoding for system instruction operands. 1733let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1734class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1735 list<dag> pattern = []> 1736 : I<oops, iops, asm, operands, "", pattern> { 1737 let Inst{31-22} = 0b1101010100; 1738 let Inst{21} = L; 1739} 1740 1741// System instructions which do not have an Rt register. 1742class SimpleSystemI<bit L, dag iops, string asm, string operands, 1743 list<dag> pattern = []> 1744 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1745 let Inst{4-0} = 0b11111; 1746} 1747 1748// System instructions which have an Rt register. 1749class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1750 list<dag> pattern = []> 1751 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1752 Sched<[WriteSys]> { 1753 bits<5> Rt; 1754 let Inst{4-0} = Rt; 1755} 1756 1757// System instructions for transactional memory extension 1758class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1759 string asm, string operands, list<dag> pattern> 1760 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1761 Sched<[WriteSys]> { 1762 let Inst{20-12} = 0b000110011; 1763 let Inst{11-8} = CRm; 1764 let Inst{7-5} = op2; 1765 let DecoderMethod = ""; 1766 1767 let mayLoad = 1; 1768 let mayStore = 1; 1769} 1770 1771// System instructions for transactional memory - single input operand 1772class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1773 : TMBaseSystemI<0b1, CRm, 0b011, 1774 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1775 bits<5> Rt; 1776 let Inst{4-0} = Rt; 1777} 1778 1779// System instructions that pass a register argument 1780// This class assumes the register is for input rather than output. 1781class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1782 list<dag> pattern = []> 1783 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1784 let Inst{20-12} = 0b000110001; 1785 let Inst{11-8} = CRm; 1786 let Inst{7-5} = Op2; 1787} 1788 1789// System instructions for transactional memory - no operand 1790class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1791 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1792 let Inst{4-0} = 0b11111; 1793} 1794 1795// System instructions for exit from transactions 1796class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1797 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1798 Sched<[WriteSys]> { 1799 bits<16> imm; 1800 let Inst{31-24} = 0b11010100; 1801 let Inst{23-21} = op1; 1802 let Inst{20-5} = imm; 1803 let Inst{4-0} = 0b00000; 1804} 1805 1806class APASI : SimpleSystemI<0, (ins GPR64:$Xt), "apas", "\t$Xt">, Sched<[]> { 1807 bits<5> Xt; 1808 let Inst{20-5} = 0b0111001110000000; 1809 let Inst{4-0} = Xt; 1810 let DecoderNamespace = "APAS"; 1811} 1812 1813// Hint instructions that take both a CRm and a 3-bit immediate. 1814// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1815// model patterns with sufficiently fine granularity 1816let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1817 class HintI<string mnemonic> 1818 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1819 [(int_aarch64_hint imm0_127:$imm)]>, 1820 Sched<[WriteHint]> { 1821 bits <7> imm; 1822 let Inst{20-12} = 0b000110010; 1823 let Inst{11-5} = imm; 1824 } 1825 1826def PHintInstOperand : AsmOperandClass { 1827 let Name = "PHint"; 1828 let ParserMethod = "tryParsePHintInstOperand"; 1829} 1830 1831def phint_op : Operand<i32> { 1832 let ParserMatchClass = PHintInstOperand; 1833 let PrintMethod = "printPHintOp"; 1834} 1835 1836class STSHHI 1837 : SimpleSystemI<0, (ins phint_op:$policy), "stshh", "\t$policy", []>, 1838 Sched<[WriteHint]> { 1839 bits<3> policy; 1840 let Inst{20-12} = 0b000011001; 1841 let Inst{11-8} = 0b0110; 1842 let Inst{7-5} = policy; 1843} 1844 1845// System instructions taking a single literal operand which encodes into 1846// CRm. op2 differentiates the opcodes. 1847def BarrierAsmOperand : AsmOperandClass { 1848 let Name = "Barrier"; 1849 let ParserMethod = "tryParseBarrierOperand"; 1850} 1851def barrier_op : Operand<i32> { 1852 let PrintMethod = "printBarrierOption"; 1853 let ParserMatchClass = BarrierAsmOperand; 1854} 1855def BarriernXSAsmOperand : AsmOperandClass { 1856 let Name = "BarriernXS"; 1857 let ParserMethod = "tryParseBarriernXSOperand"; 1858} 1859def barrier_nxs_op : Operand<i32> { 1860 let PrintMethod = "printBarriernXSOption"; 1861 let ParserMatchClass = BarriernXSAsmOperand; 1862} 1863class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1864 list<dag> pattern = []> 1865 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1866 Sched<[WriteBarrier]> { 1867 bits<4> CRm; 1868 let Inst{20-12} = 0b000110011; 1869 let Inst{11-8} = CRm; 1870 let Inst{7-5} = opc; 1871} 1872 1873class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1874 : SimpleSystemI<0, (ins), asm, "", pattern>, 1875 Sched<[WriteHint]> { 1876 bits<4> CRm; 1877 let CRm = 0b0011; 1878 let Inst{31-12} = 0b11010101000000110010; 1879 let Inst{11-8} = CRm; 1880 let Inst{7-5} = op2; 1881 let Inst{4-0} = 0b11111; 1882} 1883 1884// MRS/MSR system instructions. These have different operand classes because 1885// a different subset of registers can be accessed through each instruction. 1886def MRSSystemRegisterOperand : AsmOperandClass { 1887 let Name = "MRSSystemRegister"; 1888 let ParserMethod = "tryParseSysReg"; 1889 let DiagnosticType = "MRS"; 1890} 1891// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1892def mrs_sysreg_op : Operand<i32> { 1893 let ParserMatchClass = MRSSystemRegisterOperand; 1894 let DecoderMethod = "DecodeMRSSystemRegister"; 1895 let PrintMethod = "printMRSSystemRegister"; 1896} 1897 1898def MSRSystemRegisterOperand : AsmOperandClass { 1899 let Name = "MSRSystemRegister"; 1900 let ParserMethod = "tryParseSysReg"; 1901 let DiagnosticType = "MSR"; 1902} 1903def msr_sysreg_op : Operand<i32> { 1904 let ParserMatchClass = MSRSystemRegisterOperand; 1905 let DecoderMethod = "DecodeMSRSystemRegister"; 1906 let PrintMethod = "printMSRSystemRegister"; 1907} 1908 1909def PSBHintOperand : AsmOperandClass { 1910 let Name = "PSBHint"; 1911 let ParserMethod = "tryParsePSBHint"; 1912} 1913def psbhint_op : Operand<i32> { 1914 let ParserMatchClass = PSBHintOperand; 1915 let PrintMethod = "printPSBHintOp"; 1916 let MCOperandPredicate = [{ 1917 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1918 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1919 if (!MCOp.isImm()) 1920 return false; 1921 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1922 }]; 1923} 1924 1925def BTIHintOperand : AsmOperandClass { 1926 let Name = "BTIHint"; 1927 let ParserMethod = "tryParseBTIHint"; 1928} 1929def btihint_op : Operand<i32> { 1930 let ParserMatchClass = BTIHintOperand; 1931 let PrintMethod = "printBTIHintOp"; 1932 let MCOperandPredicate = [{ 1933 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1934 if (!MCOp.isImm()) 1935 return false; 1936 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1937 }]; 1938} 1939 1940class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1941 "mrs", "\t$Rt, $systemreg"> { 1942 bits<16> systemreg; 1943 let Inst{20-5} = systemreg; 1944 let DecoderNamespace = "Fallback"; 1945 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1946 // require doing this. The alternative was to explicitly model each one, but 1947 // it feels like it is unnecessary because it seems there are no negative 1948 // consequences setting these flags for all. 1949 let Defs = [NZCV]; 1950} 1951 1952// FIXME: Some of these def NZCV, others don't. Best way to model that? 1953// Explicitly modeling each of the system register as a register class 1954// would do it, but feels like overkill at this point. 1955class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1956 "msr", "\t$systemreg, $Rt"> { 1957 bits<16> systemreg; 1958 let Inst{20-5} = systemreg; 1959 let DecoderNamespace = "Fallback"; 1960} 1961 1962def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1963 let Name = "SystemPStateFieldWithImm0_15"; 1964 let ParserMethod = "tryParseSysReg"; 1965} 1966def pstatefield4_op : Operand<i32> { 1967 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1968 let PrintMethod = "printSystemPStateField"; 1969 let MCOperandPredicate = [{ 1970 if (!MCOp.isImm()) 1971 return false; 1972 return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr; 1973 }]; 1974} 1975 1976// Instructions to modify PSTATE, no input reg 1977let Defs = [NZCV] in 1978class PstateWriteSimple<dag iops, string asm, string operands> 1979 : SimpleSystemI<0, iops, asm, operands> { 1980 1981 let Inst{20-19} = 0b00; 1982 let Inst{15-12} = 0b0100; 1983} 1984 1985class MSRpstateImm0_15 1986 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1987 "\t$pstatefield, $imm">, 1988 Sched<[WriteSys]> { 1989 1990 bits<6> pstatefield; 1991 bits<4> imm; 1992 let Inst{18-16} = pstatefield{5-3}; 1993 let Inst{11-8} = imm; 1994 let Inst{7-5} = pstatefield{2-0}; 1995 1996 let DecoderMethod = "DecodeSystemPStateImm0_15Instruction"; 1997 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1998 // Fail the decoder should attempt to decode the instruction as MSRI. 1999 let hasCompleteDecoder = false; 2000} 2001 2002def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 2003 let Name = "SystemPStateFieldWithImm0_1"; 2004 let ParserMethod = "tryParseSysReg"; 2005} 2006def pstatefield1_op : Operand<i32> { 2007 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 2008 let PrintMethod = "printSystemPStateField"; 2009 let MCOperandPredicate = [{ 2010 if (!MCOp.isImm()) 2011 return false; 2012 return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr; 2013 }]; 2014} 2015 2016class MSRpstateImm0_1 2017 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 2018 "\t$pstatefield, $imm">, 2019 Sched<[WriteSys]> { 2020 2021 bits<9> pstatefield; 2022 bit imm; 2023 let Inst{18-16} = pstatefield{5-3}; 2024 let Inst{11-9} = pstatefield{8-6}; 2025 let Inst{8} = imm; 2026 let Inst{7-5} = pstatefield{2-0}; 2027 2028 let DecoderMethod = "DecodeSystemPStateImm0_1Instruction"; 2029 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 2030 // Fail the decoder should attempt to decode the instruction as MSRI. 2031 let hasCompleteDecoder = false; 2032 let DecoderNamespace = "Fallback"; 2033} 2034 2035// SYS and SYSL generic system instructions. 2036def SysCRAsmOperand : AsmOperandClass { 2037 let Name = "SysCR"; 2038 let ParserMethod = "tryParseSysCROperand"; 2039} 2040 2041def sys_cr_op : Operand<i32> { 2042 let PrintMethod = "printSysCROperand"; 2043 let ParserMatchClass = SysCRAsmOperand; 2044} 2045 2046class SystemXtI<bit L, string asm> 2047 : RtSystemI<L, (outs), 2048 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 2049 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 2050 bits<3> op1; 2051 bits<4> Cn; 2052 bits<4> Cm; 2053 bits<3> op2; 2054 let Inst{20-19} = 0b01; 2055 let Inst{18-16} = op1; 2056 let Inst{15-12} = Cn; 2057 let Inst{11-8} = Cm; 2058 let Inst{7-5} = op2; 2059} 2060 2061class SystemLXtI<bit L, string asm> 2062 : RtSystemI<L, (outs), 2063 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 2064 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 2065 bits<3> op1; 2066 bits<4> Cn; 2067 bits<4> Cm; 2068 bits<3> op2; 2069 let Inst{20-19} = 0b01; 2070 let Inst{18-16} = op1; 2071 let Inst{15-12} = Cn; 2072 let Inst{11-8} = Cm; 2073 let Inst{7-5} = op2; 2074} 2075 2076def RangePrefetchOperand : AsmOperandClass { 2077 let Name = "RangePrefetch"; 2078 let ParserMethod = "tryParseRPRFMOperand"; 2079 let PredicateMethod = "isPrefetch"; 2080 let RenderMethod = "addPrefetchOperands"; 2081} 2082 2083def rprfop : Operand<i32>, TImmLeaf<i32, [{ 2084 return (((uint32_t)Imm) <= 63); 2085 }]> { 2086 let PrintMethod = "printRPRFMOperand"; 2087 let ParserMatchClass = RangePrefetchOperand; 2088} 2089 2090// Branch (register) instructions: 2091// 2092// case opc of 2093// 0001 blr 2094// 0000 br 2095// 0101 dret 2096// 0100 eret 2097// 0010 ret 2098// otherwise UNDEFINED 2099class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 2100 string operands, list<dag> pattern> 2101 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 2102 let Inst{31-25} = 0b1101011; 2103 let Inst{24-21} = opc; 2104 let Inst{20-16} = 0b11111; 2105 let Inst{15-10} = 0b000000; 2106 let Inst{4-0} = 0b00000; 2107} 2108 2109class BranchReg<bits<4> opc, string asm, list<dag> pattern> 2110 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 2111 bits<5> Rn; 2112 let Inst{9-5} = Rn; 2113} 2114 2115let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 2116class SpecialReturn<bits<4> opc, string asm> 2117 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 2118 let Inst{9-5} = 0b11111; 2119} 2120 2121let mayLoad = 1 in 2122class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 2123 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 2124 Sched<[]> { 2125 bits<5> Rn; 2126 bits<5> Rt; 2127 let Inst{31-30} = sz; 2128 let Inst{29-10} = 0b11100010111111110000; 2129 let Inst{9-5} = Rn; 2130 let Inst{4-0} = Rt; 2131} 2132 2133class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 2134 list<dag> pattern> 2135 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 2136 let isAuthenticated = 1; 2137 let Inst{31-25} = 0b1101011; 2138 let Inst{20-11} = 0b1111100001; 2139 let Inst{10} = M; 2140 let Inst{4-0} = 0b11111; 2141} 2142 2143class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 2144 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 2145 bits<5> Rn; 2146 bits<5> Rm; 2147 let Inst{24-22} = 0b100; 2148 let Inst{21} = op; 2149 let Inst{9-5} = Rn; 2150 let Inst{4-0} = Rm; 2151} 2152 2153class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 2154 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 2155 bits<5> Rn; 2156 let Inst{24} = 0; 2157 let Inst{23-21} = opc; 2158 let Inst{9-5} = Rn; 2159} 2160 2161let Uses = [LR,SP] in 2162class AuthReturn<bits<3> op, bits<1> M, string asm> 2163 : AuthBase<M, (outs), (ins), asm, "", []> { 2164 let Inst{24} = 0; 2165 let Inst{23-21} = op; 2166 let Inst{9-0} = 0b1111111111; 2167} 2168 2169let mayLoad = 1 in 2170class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 2171 string operands, string cstr> 2172 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 2173 bits<10> offset; 2174 bits<5> Rn; 2175 bits<5> Rt; 2176 let isAuthenticated = 1; 2177 let Inst{31-24} = 0b11111000; 2178 let Inst{23} = M; 2179 let Inst{22} = offset{9}; 2180 let Inst{21} = 1; 2181 let Inst{20-12} = offset{8-0}; 2182 let Inst{11} = W; 2183 let Inst{10} = 1; 2184 let Inst{9-5} = Rn; 2185 let Inst{4-0} = Rt; 2186 2187 let DecoderMethod = "DecodeAuthLoadInstruction"; 2188} 2189 2190multiclass AuthLoad<bit M, string asm, Operand opr> { 2191 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 2192 (ins GPR64sp:$Rn, opr:$offset), 2193 asm, "\t$Rt, [$Rn, $offset]", "">; 2194 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 2195 (ins GPR64sp:$Rn, opr:$offset), 2196 asm, "\t$Rt, [$Rn, $offset]!", 2197 "$Rn = $wback,@earlyclobber $wback">; 2198 2199 def : InstAlias<asm # "\t$Rt, [$Rn]", 2200 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 2201 2202 def : InstAlias<asm # "\t$Rt, [$wback]!", 2203 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 2204} 2205 2206//--- 2207// Conditional branch instruction. 2208//--- 2209 2210// Condition code. 2211// 4-bit immediate. Pretty-printed as <cc> 2212def ccode : Operand<i32> { 2213 let PrintMethod = "printCondCode"; 2214 let ParserMatchClass = CondCode; 2215} 2216def inv_ccode : Operand<i32> { 2217 // AL and NV are invalid in the aliases which use inv_ccode 2218 let PrintMethod = "printInverseCondCode"; 2219 let ParserMatchClass = CondCode; 2220 let MCOperandPredicate = [{ 2221 return MCOp.isImm() && 2222 MCOp.getImm() != AArch64CC::AL && 2223 MCOp.getImm() != AArch64CC::NV; 2224 }]; 2225} 2226 2227// Conditional branch target. 19-bit immediate. The low two bits of the target 2228// offset are implied zero and so are not part of the immediate. 2229def am_brcond : Operand<OtherVT> { 2230 let EncoderMethod = "getCondBranchTargetOpValue"; 2231 let DecoderMethod = "DecodePCRelLabel19"; 2232 let PrintMethod = "printAlignedLabel"; 2233 let ParserMatchClass = PCRelLabel19Operand; 2234 let OperandType = "OPERAND_PCREL"; 2235} 2236 2237// Conditional branch target. 9-bit immediate. The low two bits of the target 2238// offset are implied zero and so are not part of the immediate. 2239def am_brcmpcond : Operand<OtherVT> { 2240 let EncoderMethod = "getCondCompBranchTargetOpValue"; 2241 let DecoderMethod = "DecodePCRelLabel9"; 2242 let PrintMethod = "printAlignedLabel"; 2243 let ParserMatchClass = PCRelLabel9Operand; 2244 let OperandType = "OPERAND_PCREL"; 2245} 2246 2247 2248class BranchCond<bit bit4, string mnemonic> 2249 : I<(outs), (ins ccode:$cond, am_brcond:$target), 2250 mnemonic, ".$cond\t$target", "", 2251 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 2252 let isBranch = 1; 2253 let isTerminator = 1; 2254 let Uses = [NZCV]; 2255 2256 bits<4> cond; 2257 bits<19> target; 2258 let Inst{31-24} = 0b01010100; 2259 let Inst{23-5} = target; 2260 let Inst{4} = bit4; 2261 let Inst{3-0} = cond; 2262} 2263 2264//--- 2265// Compare-and-branch instructions. 2266//--- 2267class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 2268 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 2269 asm, "\t$Rt, $target", "", 2270 [(node regtype:$Rt, bb:$target)]>, 2271 Sched<[WriteBr]> { 2272 let isBranch = 1; 2273 let isTerminator = 1; 2274 2275 bits<5> Rt; 2276 bits<19> target; 2277 let Inst{30-25} = 0b011010; 2278 let Inst{24} = op; 2279 let Inst{23-5} = target; 2280 let Inst{4-0} = Rt; 2281} 2282 2283multiclass CmpBranch<bit op, string asm, SDNode node> { 2284 def W : BaseCmpBranch<GPR32, op, asm, node> { 2285 let Inst{31} = 0; 2286 } 2287 def X : BaseCmpBranch<GPR64, op, asm, node> { 2288 let Inst{31} = 1; 2289 } 2290} 2291 2292//--- 2293// Test-bit-and-branch instructions. 2294//--- 2295// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 2296// the target offset are implied zero and so are not part of the immediate. 2297def am_tbrcond : Operand<OtherVT> { 2298 let EncoderMethod = "getTestBranchTargetOpValue"; 2299 let PrintMethod = "printAlignedLabel"; 2300 let ParserMatchClass = BranchTarget14Operand; 2301 let OperandType = "OPERAND_PCREL"; 2302} 2303 2304// AsmOperand classes to emit (or not) special diagnostics 2305def TBZImm0_31Operand : AsmOperandClass { 2306 let Name = "TBZImm0_31"; 2307 let PredicateMethod = "isImmInRange<0,31>"; 2308 let RenderMethod = "addImmOperands"; 2309} 2310def TBZImm32_63Operand : AsmOperandClass { 2311 let Name = "Imm32_63"; 2312 let PredicateMethod = "isImmInRange<32,63>"; 2313 let DiagnosticType = "InvalidImm0_63"; 2314 let RenderMethod = "addImmOperands"; 2315} 2316 2317class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 2318 return (((uint32_t)Imm) < 32); 2319}]> { 2320 let ParserMatchClass = matcher; 2321} 2322 2323def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 2324def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 2325 2326def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 2327 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 2328}]> { 2329 let ParserMatchClass = TBZImm32_63Operand; 2330} 2331 2332class BaseTestBranch<RegisterClass regtype, Operand immtype, 2333 bit op, string asm, SDNode node> 2334 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 2335 asm, "\t$Rt, $bit_off, $target", "", 2336 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 2337 Sched<[WriteBr]> { 2338 let isBranch = 1; 2339 let isTerminator = 1; 2340 2341 bits<5> Rt; 2342 bits<6> bit_off; 2343 bits<14> target; 2344 2345 let Inst{30-25} = 0b011011; 2346 let Inst{24} = op; 2347 let Inst{23-19} = bit_off{4-0}; 2348 let Inst{18-5} = target; 2349 let Inst{4-0} = Rt; 2350 2351 let DecoderMethod = "DecodeTestAndBranch"; 2352} 2353 2354multiclass TestBranch<bit op, string asm, SDNode node> { 2355 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 2356 let Inst{31} = 0; 2357 } 2358 2359 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 2360 let Inst{31} = 1; 2361 } 2362 2363 // Alias X-reg with 0-31 imm to W-Reg. 2364 def : InstAlias<asm # "\t$Rd, $imm, $target", 2365 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 2366 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 2367 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 2368 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 2369 tbz_imm0_31_diag:$imm, bb:$target)>; 2370} 2371 2372//--- 2373// Unconditional branch (immediate) instructions. 2374//--- 2375def am_b_target : Operand<OtherVT> { 2376 let EncoderMethod = "getBranchTargetOpValue"; 2377 let PrintMethod = "printAlignedLabel"; 2378 let ParserMatchClass = BranchTarget26Operand; 2379 let OperandType = "OPERAND_PCREL"; 2380} 2381def am_bl_target : Operand<i64> { 2382 let EncoderMethod = "getBranchTargetOpValue"; 2383 let PrintMethod = "printAlignedLabel"; 2384 let ParserMatchClass = BranchTarget26Operand; 2385 let OperandType = "OPERAND_PCREL"; 2386} 2387 2388class BImm<bit op, dag iops, string asm, list<dag> pattern> 2389 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 2390 bits<26> addr; 2391 let Inst{31} = op; 2392 let Inst{30-26} = 0b00101; 2393 let Inst{25-0} = addr; 2394 2395 let DecoderMethod = "DecodeUnconditionalBranch"; 2396} 2397 2398class BranchImm<bit op, string asm, list<dag> pattern> 2399 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 2400class CallImm<bit op, string asm, list<dag> pattern> 2401 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2402 2403//--- 2404// Basic one-operand data processing instructions. 2405//--- 2406 2407let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2408class BaseOneOperandData<bit sf, bit S, bits<5> opc2, bits<6> opc, 2409 RegisterClass regtype, string asm, 2410 SDPatternOperator node> 2411 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2412 [(set regtype:$Rd, (node regtype:$Rn))]>, 2413 Sched<[WriteI, ReadI]> { 2414 bits<5> Rd; 2415 bits<5> Rn; 2416 2417 let Inst{31} = sf; 2418 let Inst{30} = 0b1; 2419 let Inst{29} = S; 2420 let Inst{28-21} = 0b11010110; 2421 let Inst{20-16} = opc2; 2422 let Inst{15-10} = opc; 2423 let Inst{9-5} = Rn; 2424 let Inst{4-0} = Rd; 2425} 2426 2427let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2428multiclass OneOperandData<bits<6> opc, string asm, 2429 SDPatternOperator node = null_frag> { 2430 def Wr : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2431 2432 def Xr : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2433} 2434 2435class OneWRegData<bits<6> opc, string asm, SDPatternOperator node> 2436 : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2437 2438class OneXRegData<bits<6> opc, string asm, SDPatternOperator node> 2439 : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2440 2441class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2442 SDPatternOperator op> 2443 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2444 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2445 Sched<[WriteI, ReadI]> { 2446 bits<5> Rd; 2447 bits<5> Rn; 2448 let Inst{31-15} = 0b11011010110000010; 2449 let Inst{14-12} = opcode_prefix; 2450 let Inst{11-10} = opcode; 2451 let Inst{9-5} = Rn; 2452 let Inst{4-0} = Rd; 2453} 2454 2455class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2456 SDPatternOperator op> 2457 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2458 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2459 Sched<[]> { 2460 bits<5> Rd; 2461 let Inst{31-15} = 0b11011010110000010; 2462 let Inst{14-12} = opcode_prefix; 2463 let Inst{11-10} = opcode; 2464 let Inst{9-5} = 0b11111; 2465 let Inst{4-0} = Rd; 2466} 2467 2468class SignAuthTwoOperand<bits<4> opc, string asm, 2469 SDPatternOperator OpNode> 2470 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2471 asm, "\t$Rd, $Rn, $Rm", "", 2472 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2473 Sched<[WriteI, ReadI, ReadI]> { 2474 bits<5> Rd; 2475 bits<5> Rn; 2476 bits<5> Rm; 2477 let Inst{31-21} = 0b10011010110; 2478 let Inst{20-16} = Rm; 2479 let Inst{15-14} = 0b00; 2480 let Inst{13-10} = opc; 2481 let Inst{9-5} = Rn; 2482 let Inst{4-0} = Rd; 2483} 2484 2485class ClearAuth<bits<1> data, string asm> 2486 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2487 bits<5> Rd; 2488 let Inst{31-11} = 0b110110101100000101000; 2489 let Inst{10} = data; 2490 let Inst{9-5} = 0b11111; 2491 let Inst{4-0} = Rd; 2492} 2493 2494// v9.5-A FEAT_PAuth_LR 2495 2496class SignAuthFixedRegs<bits<5> opcode2, bits<6> opcode, string asm> 2497 : I<(outs), (ins), asm, "", "", []>, 2498 Sched<[WriteI, ReadI]> { 2499 let Inst{31} = 0b1; // sf 2500 let Inst{30} = 0b1; 2501 let Inst{29} = 0b0; // S 2502 let Inst{28-21} = 0b11010110; 2503 let Inst{20-16} = opcode2; 2504 let Inst{15-10} = opcode; 2505 let Inst{9-5} = 0b11111; // Rn 2506 let Inst{4-0} = 0b11110; // Rd 2507} 2508 2509def PAuthPCRelLabel16Operand : PCRelLabel<16> { 2510 let Name = "PAuthPCRelLabel16"; 2511 let PredicateMethod = "isPAuthPCRelLabel16Operand"; 2512} 2513def am_pauth_pcrel : Operand<OtherVT> { 2514 let EncoderMethod = "getPAuthPCRelOpValue"; 2515 let DecoderMethod = "DecodePCRelLabel16"; 2516 let PrintMethod = "printAlignedLabel"; 2517 let ParserMatchClass = PAuthPCRelLabel16Operand; 2518 let OperandType = "OPERAND_PCREL"; 2519} 2520 2521class SignAuthPCRel<bits<2> opc, string asm> 2522 : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>, 2523 Sched<[]> { 2524 bits<16> label; 2525 let Inst{31} = 0b1; // sf 2526 let Inst{30-23} = 0b11100111; 2527 let Inst{22-21} = opc; 2528 let Inst{20-5} = label; // imm 2529 let Inst{4-0} = 0b11111; // Rd 2530} 2531 2532class SignAuthOneReg<bits<5> opcode2, bits<6> opcode, string asm> 2533 : I<(outs), (ins GPR64:$Rn), asm, "\t$Rn", "", []>, 2534 Sched<[]> { 2535 bits<5> Rn; 2536 let Inst{31} = 0b1; // sf 2537 let Inst{30} = 0b1; 2538 let Inst{29} = 0b0; // S 2539 let Inst{28-21} = 0b11010110; 2540 let Inst{20-16} = opcode2; 2541 let Inst{15-10} = opcode; 2542 let Inst{9-5} = Rn; 2543 let Inst{4-0} = 0b11110; // Rd 2544} 2545 2546class SignAuthReturnPCRel<bits<3> opc, bits<5> op2, string asm> 2547 : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>, 2548 Sched<[WriteAtomic]> { 2549 bits<16> label; 2550 let Inst{31-24} = 0b01010101; 2551 let Inst{23-21} = opc; 2552 let Inst{20-5} = label; // imm16 2553 let Inst{4-0} = op2; 2554} 2555 2556class SignAuthReturnReg<bits<6> op3, string asm> 2557 : I<(outs), (ins GPR64common:$Rm), asm, "\t$Rm", "", []>, 2558 Sched<[WriteAtomic]> { 2559 bits<5> Rm; 2560 let Inst{31-25} = 0b1101011; 2561 let Inst{24-21} = 0b0010; // opc 2562 let Inst{20-16} = 0b11111; // op2 2563 let Inst{15-10} = op3; 2564 let Inst{9-5} = 0b11111; // Rn 2565 let Inst{4-0} = Rm; // op4 (Rm) 2566} 2567 2568// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2569class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2570 : I<(outs), iops, asm, ops, "", []>, 2571 Sched<[WriteI, ReadI, ReadI]> { 2572 let Uses = [NZCV]; 2573 let Defs = [NZCV]; 2574 bits<5> Rn; 2575 let Inst{31} = sf; 2576 let Inst{30-15} = 0b0111010000000000; 2577 let Inst{14} = sz; 2578 let Inst{13-10} = 0b0010; 2579 let Inst{9-5} = Rn; 2580 let Inst{4-0} = 0b01101; 2581} 2582 2583class FlagRotate<dag iops, string asm, string ops> 2584 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2585 bits<6> imm; 2586 bits<4> mask; 2587 let Inst{20-15} = imm; 2588 let Inst{13-10} = 0b0001; 2589 let Inst{4} = 0b0; 2590 let Inst{3-0} = mask; 2591} 2592 2593//--- 2594// Basic two-operand data processing instructions. 2595//--- 2596class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2597 list<dag> pattern> 2598 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2599 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2600 Sched<[WriteI, ReadI, ReadI]> { 2601 let Uses = [NZCV]; 2602 bits<5> Rd; 2603 bits<5> Rn; 2604 bits<5> Rm; 2605 let Inst{30} = isSub; 2606 let Inst{28-21} = 0b11010000; 2607 let Inst{20-16} = Rm; 2608 let Inst{15-10} = 0; 2609 let Inst{9-5} = Rn; 2610 let Inst{4-0} = Rd; 2611} 2612 2613class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2614 SDNode OpNode> 2615 : BaseBaseAddSubCarry<isSub, regtype, asm, 2616 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2617 2618class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2619 SDNode OpNode> 2620 : BaseBaseAddSubCarry<isSub, regtype, asm, 2621 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]> { 2622 let Defs = [NZCV]; 2623} 2624 2625multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2626 SDNode OpNode, SDNode OpNode_setflags> { 2627 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2628 let Inst{31} = 0; 2629 let Inst{29} = 0; 2630 } 2631 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2632 let Inst{31} = 1; 2633 let Inst{29} = 0; 2634 } 2635 2636 // Sets flags. 2637 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2638 OpNode_setflags> { 2639 let Inst{31} = 0; 2640 let Inst{29} = 1; 2641 } 2642 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2643 OpNode_setflags> { 2644 let Inst{31} = 1; 2645 let Inst{29} = 1; 2646 } 2647} 2648 2649class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype, 2650 string asm, SDPatternOperator OpNode, 2651 RegisterClass in1regtype = regtype, 2652 RegisterClass in2regtype = regtype> 2653 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2654 asm, "\t$Rd, $Rn, $Rm", "", 2655 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2656 bits<5> Rd; 2657 bits<5> Rn; 2658 bits<5> Rm; 2659 let Inst{31} = sf; 2660 let Inst{30} = 0b0; 2661 let Inst{29} = S; 2662 let Inst{28-21} = 0b11010110; 2663 let Inst{20-16} = Rm; 2664 let Inst{15-10} = opc; 2665 let Inst{9-5} = Rn; 2666 let Inst{4-0} = Rd; 2667} 2668 2669class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm, 2670 SDPatternOperator OpNode> 2671 : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> { 2672 let Inst{10} = isSigned; 2673} 2674 2675multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2676 def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>, 2677 Sched<[WriteID32, ReadID, ReadID]>; 2678 2679 def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>, 2680 Sched<[WriteID64, ReadID, ReadID]>; 2681} 2682 2683class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm, 2684 SDPatternOperator OpNode = null_frag> 2685 : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>, 2686 Sched<[WriteIS, ReadI]> { 2687 let Inst{11-10} = shift_type; 2688} 2689 2690multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2691 def Wr : BaseShift<0b0, shift_type, GPR32, asm>; 2692 2693 def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>; 2694 2695 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2696 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2697 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2698 2699 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2700 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2701 2702 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2703 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2704 2705 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2706 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2707 2708 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2709 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2710 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2711 2712 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2713 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2714 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2715} 2716 2717class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2718 : InstAlias<asm#"\t$dst, $src1, $src2", 2719 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2720 2721class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2722 RegisterClass addtype, string asm, 2723 list<dag> pattern> 2724 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2725 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2726 bits<5> Rd; 2727 bits<5> Rn; 2728 bits<5> Rm; 2729 bits<5> Ra; 2730 let Inst{30-24} = 0b0011011; 2731 let Inst{23-21} = opc; 2732 let Inst{20-16} = Rm; 2733 let Inst{15} = isSub; 2734 let Inst{14-10} = Ra; 2735 let Inst{9-5} = Rn; 2736 let Inst{4-0} = Rd; 2737} 2738 2739multiclass MulAccum<bit isSub, string asm> { 2740 // MADD/MSUB generation is decided by MachineCombiner.cpp 2741 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2742 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2743 let Inst{31} = 0; 2744 } 2745 2746 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2747 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2748 let Inst{31} = 1; 2749 } 2750} 2751 2752class WideMulAccum<bit isSub, bits<3> opc, string asm, 2753 SDNode AccNode, SDNode ExtNode> 2754 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2755 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2756 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2757 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2758 let Inst{31} = 1; 2759} 2760 2761class MulHi<bits<3> opc, string asm, SDNode OpNode> 2762 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2763 asm, "\t$Rd, $Rn, $Rm", "", 2764 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2765 Sched<[WriteIM64, ReadIM, ReadIM]> { 2766 bits<5> Rd; 2767 bits<5> Rn; 2768 bits<5> Rm; 2769 let Inst{31-24} = 0b10011011; 2770 let Inst{23-21} = opc; 2771 let Inst{20-16} = Rm; 2772 let Inst{15} = 0; 2773 let Inst{14-10} = 0b11111; 2774 let Unpredictable{14-10} = 0b11111; 2775 let Inst{9-5} = Rn; 2776 let Inst{4-0} = Rd; 2777 2778 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2779 // (i.e. all bits 1) but is ignored by the processor. 2780 let PostEncoderMethod = "fixMulHigh"; 2781} 2782 2783class MulAccumWAlias<string asm, Instruction inst> 2784 : InstAlias<asm#"\t$dst, $src1, $src2", 2785 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2786class MulAccumXAlias<string asm, Instruction inst> 2787 : InstAlias<asm#"\t$dst, $src1, $src2", 2788 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2789class WideMulAccumAlias<string asm, Instruction inst> 2790 : InstAlias<asm#"\t$dst, $src1, $src2", 2791 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2792 2793class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2794 SDPatternOperator OpNode, string asm> 2795 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2796 asm, "\t$Rd, $Rn, $Rm", "", 2797 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2798 Sched<[WriteISReg, ReadI, ReadISReg]> { 2799 bits<5> Rd; 2800 bits<5> Rn; 2801 bits<5> Rm; 2802 2803 let Inst{31} = sf; 2804 let Inst{30-21} = 0b0011010110; 2805 let Inst{20-16} = Rm; 2806 let Inst{15-13} = 0b010; 2807 let Inst{12} = C; 2808 let Inst{11-10} = sz; 2809 let Inst{9-5} = Rn; 2810 let Inst{4-0} = Rd; 2811 let Predicates = [HasCRC]; 2812} 2813 2814//--- 2815// Address generation. 2816//--- 2817 2818class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2819 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2820 pattern>, 2821 Sched<[WriteI]> { 2822 bits<5> Xd; 2823 bits<21> label; 2824 let Inst{31} = page; 2825 let Inst{30-29} = label{1-0}; 2826 let Inst{28-24} = 0b10000; 2827 let Inst{23-5} = label{20-2}; 2828 let Inst{4-0} = Xd; 2829 2830 let DecoderMethod = "DecodeAdrInstruction"; 2831} 2832 2833//--- 2834// Move immediate. 2835//--- 2836 2837def movimm32_imm : Operand<i32> { 2838 let ParserMatchClass = AsmImmRange<0, 65535>; 2839 let EncoderMethod = "getMoveWideImmOpValue"; 2840 let PrintMethod = "printImm"; 2841} 2842def movimm32_shift : Operand<i32> { 2843 let PrintMethod = "printShifter"; 2844 let ParserMatchClass = MovImm32ShifterOperand; 2845} 2846def movimm64_shift : Operand<i32> { 2847 let PrintMethod = "printShifter"; 2848 let ParserMatchClass = MovImm64ShifterOperand; 2849} 2850 2851let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2852class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2853 string asm> 2854 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2855 asm, "\t$Rd, $imm$shift", "", []>, 2856 Sched<[WriteImm]> { 2857 bits<5> Rd; 2858 bits<16> imm; 2859 bits<6> shift; 2860 let Inst{30-29} = opc; 2861 let Inst{28-23} = 0b100101; 2862 let Inst{22-21} = shift{5-4}; 2863 let Inst{20-5} = imm; 2864 let Inst{4-0} = Rd; 2865 2866 let DecoderMethod = "DecodeMoveImmInstruction"; 2867} 2868 2869multiclass MoveImmediate<bits<2> opc, string asm> { 2870 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2871 let Inst{31} = 0; 2872 } 2873 2874 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2875 let Inst{31} = 1; 2876 } 2877} 2878 2879let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2880class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2881 string asm> 2882 : I<(outs regtype:$Rd), 2883 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2884 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2885 Sched<[WriteI, ReadI]> { 2886 bits<5> Rd; 2887 bits<16> imm; 2888 bits<6> shift; 2889 let Inst{30-29} = opc; 2890 let Inst{28-23} = 0b100101; 2891 let Inst{22-21} = shift{5-4}; 2892 let Inst{20-5} = imm; 2893 let Inst{4-0} = Rd; 2894 2895 let DecoderMethod = "DecodeMoveImmInstruction"; 2896} 2897 2898multiclass InsertImmediate<bits<2> opc, string asm> { 2899 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2900 let Inst{31} = 0; 2901 } 2902 2903 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2904 let Inst{31} = 1; 2905 } 2906} 2907 2908//--- 2909// Add/Subtract 2910//--- 2911 2912class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2913 string asm_inst, string asm_ops, 2914 dag inputs, dag pattern> 2915 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2916 Sched<[WriteI, ReadI]> { 2917 bits<5> Rd; 2918 bits<5> Rn; 2919 let Inst{30} = isSub; 2920 let Inst{29} = setFlags; 2921 let Inst{28-24} = 0b10001; 2922 let Inst{9-5} = Rn; 2923 let Inst{4-0} = Rd; 2924} 2925 2926class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2927 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2928 string asm_inst, SDPatternOperator OpNode> 2929 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2930 (ins srcRegtype:$Rn, immtype:$imm), 2931 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2932 bits<14> imm; 2933 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2934 let Inst{21-10} = imm{11-0}; 2935 let DecoderMethod = "DecodeAddSubImmShift"; 2936 let hasPostISelHook = 1; 2937} 2938 2939class BaseAddSubRegPseudo<RegisterClass regtype, 2940 SDPatternOperator OpNode> 2941 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2942 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2943 Sched<[WriteI, ReadI, ReadI]>; 2944 2945class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2946 arith_shifted_reg shifted_regtype, string asm, 2947 SDPatternOperator OpNode> 2948 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 2949 asm, "\t$Rd, $Rn, $Rm_and_shift", "", 2950 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>, 2951 Sched<[WriteISReg, ReadI, ReadISReg]> { 2952 bits<5> Rd; 2953 bits<5> Rn; 2954 bits<5> Rm; 2955 bits<8> shift; 2956 let Inst{30} = isSub; 2957 let Inst{29} = setFlags; 2958 let Inst{28-24} = 0b01011; 2959 let Inst{23-22} = shift{7-6}; 2960 let Inst{21} = 0; 2961 let Inst{20-16} = Rm; 2962 let Inst{15-10} = shift{5-0}; 2963 let Inst{9-5} = Rn; 2964 let Inst{4-0} = Rd; 2965 2966 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2967} 2968 2969class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2970 RegisterClass src1Regtype, Operand src2Regtype, 2971 string asm, SDPatternOperator OpNode> 2972 : I<(outs dstRegtype:$Rd), 2973 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend), 2974 asm, "\t$Rd, $Rn, $Rm_and_extend", "", 2975 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>, 2976 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2977 bits<5> Rd; 2978 bits<5> Rn; 2979 bits<5> Rm; 2980 bits<6> extend; 2981 let Inst{30} = isSub; 2982 let Inst{29} = setFlags; 2983 let Inst{28-24} = 0b01011; 2984 let Inst{23-21} = 0b001; 2985 let Inst{20-16} = Rm; 2986 let Inst{15-13} = extend{5-3}; 2987 let Inst{12-10} = extend{2-0}; 2988 let Inst{9-5} = Rn; 2989 let Inst{4-0} = Rd; 2990 2991 let DecoderMethod = "DecodeAddSubERegInstruction"; 2992} 2993 2994let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2995class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2996 RegisterClass src1Regtype, RegisterClass src2Regtype, 2997 Operand ext_op, string asm> 2998 : I<(outs dstRegtype:$Rd), 2999 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 3000 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 3001 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 3002 bits<5> Rd; 3003 bits<5> Rn; 3004 bits<5> Rm; 3005 bits<6> ext; 3006 let Inst{30} = isSub; 3007 let Inst{29} = setFlags; 3008 let Inst{28-24} = 0b01011; 3009 let Inst{23-21} = 0b001; 3010 let Inst{20-16} = Rm; 3011 let Inst{15} = ext{5}; 3012 let Inst{12-10} = ext{2-0}; 3013 let Inst{9-5} = Rn; 3014 let Inst{4-0} = Rd; 3015 3016 let DecoderMethod = "DecodeAddSubERegInstruction"; 3017} 3018 3019// Aliases for register+register add/subtract. 3020class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 3021 RegisterClass src1Regtype, RegisterClass src2Regtype, 3022 int shiftExt> 3023 : InstAlias<asm#"\t$dst, $src1, $src2", 3024 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 3025 shiftExt)>; 3026 3027multiclass AddSub<bit isSub, string mnemonic, string alias, 3028 SDPatternOperator OpNode = null_frag> { 3029 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 3030 // Add/Subtract immediate 3031 // Increase the weight of the immediate variant to try to match it before 3032 // the extended register variant. 3033 // We used to match the register variant before the immediate when the 3034 // register argument could be implicitly zero-extended. 3035 let AddedComplexity = 6 in 3036 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 3037 mnemonic, OpNode> { 3038 let Inst{31} = 0; 3039 } 3040 let AddedComplexity = 6 in 3041 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 3042 mnemonic, OpNode> { 3043 let Inst{31} = 1; 3044 } 3045 3046 // Add/Subtract register - Only used for CodeGen 3047 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 3048 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 3049 3050 // Add/Subtract shifted register 3051 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 3052 OpNode> { 3053 let Inst{31} = 0; 3054 } 3055 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 3056 OpNode> { 3057 let Inst{31} = 1; 3058 } 3059 } 3060 3061 // Add/Subtract extended register 3062 let AddedComplexity = 1, hasSideEffects = 0 in { 3063 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 3064 arith_extended_reg32_i32, mnemonic, OpNode> { 3065 let Inst{31} = 0; 3066 } 3067 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 3068 arith_extended_reg32to64_i64, mnemonic, OpNode> { 3069 let Inst{31} = 1; 3070 } 3071 } 3072 3073 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 3074 arith_extendlsl64, mnemonic> { 3075 // UXTX and SXTX only. 3076 let Inst{14-13} = 0b11; 3077 let Inst{31} = 1; 3078 } 3079 3080 // add Rd, Rb, -imm -> sub Rd, Rn, imm 3081 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3082 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 3083 addsub_shifted_imm32_neg:$imm), 0>; 3084 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3085 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 3086 addsub_shifted_imm64_neg:$imm), 0>; 3087 3088 // Register/register aliases with no shift when SP is not used. 3089 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 3090 GPR32, GPR32, GPR32, 0>; 3091 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 3092 GPR64, GPR64, GPR64, 0>; 3093 3094 // Register/register aliases with no shift when either the destination or 3095 // first source register is SP. 3096 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 3097 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 3098 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 3099 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 3100 def : AddSubRegAlias<mnemonic, 3101 !cast<Instruction>(NAME#"Xrx64"), 3102 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 3103 def : AddSubRegAlias<mnemonic, 3104 !cast<Instruction>(NAME#"Xrx64"), 3105 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 3106} 3107 3108multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 3109 string alias, string cmpAlias> { 3110 let isCompare = 1, Defs = [NZCV] in { 3111 // Add/Subtract immediate 3112 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 3113 mnemonic, OpNode> { 3114 let Inst{31} = 0; 3115 } 3116 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 3117 mnemonic, OpNode> { 3118 let Inst{31} = 1; 3119 } 3120 3121 // Add/Subtract register 3122 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 3123 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 3124 3125 // Add/Subtract shifted register 3126 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 3127 OpNode> { 3128 let Inst{31} = 0; 3129 } 3130 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 3131 OpNode> { 3132 let Inst{31} = 1; 3133 } 3134 3135 // Add/Subtract extended register 3136 let AddedComplexity = 1 in { 3137 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 3138 arith_extended_reg32_i32, mnemonic, OpNode> { 3139 let Inst{31} = 0; 3140 } 3141 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 3142 arith_extended_reg32_i64, mnemonic, OpNode> { 3143 let Inst{31} = 1; 3144 } 3145 } 3146 3147 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 3148 arith_extendlsl64, mnemonic> { 3149 // UXTX and SXTX only. 3150 let Inst{14-13} = 0b11; 3151 let Inst{31} = 1; 3152 } 3153 } // Defs = [NZCV] 3154 3155 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 3156 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3157 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 3158 addsub_shifted_imm32_neg:$imm), 0>; 3159 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3160 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 3161 addsub_shifted_imm64_neg:$imm), 0>; 3162 3163 // Compare aliases 3164 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 3165 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 3166 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 3167 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 3168 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 3169 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 3170 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 3171 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 3172 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 3173 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 3174 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 3175 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 3176 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 3177 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 3178 3179 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 3180 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 3181 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 3182 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 3183 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 3184 3185 // Compare shorthands 3186 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 3187 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 3188 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 3189 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 3190 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 3191 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 3192 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 3193 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 3194 3195 // Register/register aliases with no shift when SP is not used. 3196 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 3197 GPR32, GPR32, GPR32, 0>; 3198 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 3199 GPR64, GPR64, GPR64, 0>; 3200 3201 // Register/register aliases with no shift when the first source register 3202 // is SP. 3203 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 3204 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 3205 def : AddSubRegAlias<mnemonic, 3206 !cast<Instruction>(NAME#"Xrx64"), 3207 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 3208} 3209 3210class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 3211 : BaseAddSubImm< 3212 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 3213 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 3214 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 3215 bits<6> imm6; 3216 bits<4> imm4; 3217 let Inst{31} = 1; 3218 let Inst{23-22} = 0b10; 3219 let Inst{21-16} = imm6; 3220 let Inst{15-14} = 0b00; 3221 let Inst{13-10} = imm4; 3222 let Unpredictable{15-14} = 0b11; 3223} 3224 3225class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 3226 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode, 3227 GPR64sp, GPR64sp>; 3228 3229//--- 3230// Extract 3231//--- 3232def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 3233 SDTCisPtrTy<3>]>; 3234def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 3235 3236class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 3237 list<dag> patterns> 3238 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 3239 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 3240 Sched<[WriteExtr, ReadExtrHi]> { 3241 bits<5> Rd; 3242 bits<5> Rn; 3243 bits<5> Rm; 3244 bits<6> imm; 3245 3246 let Inst{30-23} = 0b00100111; 3247 let Inst{21} = 0; 3248 let Inst{20-16} = Rm; 3249 let Inst{15-10} = imm; 3250 let Inst{9-5} = Rn; 3251 let Inst{4-0} = Rd; 3252} 3253 3254multiclass ExtractImm<string asm> { 3255 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 3256 [(set GPR32:$Rd, 3257 (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 3258 let Inst{31} = 0; 3259 let Inst{22} = 0; 3260 // imm<5> must be zero. 3261 let imm{5} = 0; 3262 } 3263 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 3264 [(set GPR64:$Rd, 3265 (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 3266 3267 let Inst{31} = 1; 3268 let Inst{22} = 1; 3269 } 3270} 3271 3272//--- 3273// Bitfield 3274//--- 3275 3276let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3277class BaseBitfieldImm<bits<2> opc, 3278 RegisterClass regtype, Operand imm_type, string asm> 3279 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 3280 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 3281 Sched<[WriteIS, ReadI]> { 3282 bits<5> Rd; 3283 bits<5> Rn; 3284 bits<6> immr; 3285 bits<6> imms; 3286 3287 let Inst{30-29} = opc; 3288 let Inst{28-23} = 0b100110; 3289 let Inst{21-16} = immr; 3290 let Inst{15-10} = imms; 3291 let Inst{9-5} = Rn; 3292 let Inst{4-0} = Rd; 3293} 3294 3295multiclass BitfieldImm<bits<2> opc, string asm> { 3296 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 3297 let Inst{31} = 0; 3298 let Inst{22} = 0; 3299 // imms<5> and immr<5> must be zero, else ReservedValue(). 3300 let Inst{21} = 0; 3301 let Inst{15} = 0; 3302 } 3303 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 3304 let Inst{31} = 1; 3305 let Inst{22} = 1; 3306 } 3307} 3308 3309let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3310class BaseBitfieldImmWith2RegArgs<bits<2> opc, 3311 RegisterClass regtype, Operand imm_type, string asm> 3312 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 3313 imm_type:$imms), 3314 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 3315 Sched<[WriteIS, ReadI]> { 3316 bits<5> Rd; 3317 bits<5> Rn; 3318 bits<6> immr; 3319 bits<6> imms; 3320 3321 let Inst{30-29} = opc; 3322 let Inst{28-23} = 0b100110; 3323 let Inst{21-16} = immr; 3324 let Inst{15-10} = imms; 3325 let Inst{9-5} = Rn; 3326 let Inst{4-0} = Rd; 3327} 3328 3329multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 3330 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 3331 let Inst{31} = 0; 3332 let Inst{22} = 0; 3333 // imms<5> and immr<5> must be zero, else ReservedValue(). 3334 let Inst{21} = 0; 3335 let Inst{15} = 0; 3336 } 3337 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 3338 let Inst{31} = 1; 3339 let Inst{22} = 1; 3340 } 3341} 3342 3343//--- 3344// Logical 3345//--- 3346 3347// Logical (immediate) 3348class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 3349 RegisterClass sregtype, Operand imm_type, string asm, 3350 list<dag> pattern> 3351 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 3352 asm, "\t$Rd, $Rn, $imm", "", pattern>, 3353 Sched<[WriteI, ReadI]> { 3354 bits<5> Rd; 3355 bits<5> Rn; 3356 bits<13> imm; 3357 let Inst{30-29} = opc; 3358 let Inst{28-23} = 0b100100; 3359 let Inst{22} = imm{12}; 3360 let Inst{21-16} = imm{11-6}; 3361 let Inst{15-10} = imm{5-0}; 3362 let Inst{9-5} = Rn; 3363 let Inst{4-0} = Rd; 3364 3365 let DecoderMethod = "DecodeLogicalImmInstruction"; 3366} 3367 3368// Logical (shifted register) 3369class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 3370 logical_shifted_reg shifted_regtype, string asm, 3371 list<dag> pattern> 3372 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 3373 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>, 3374 Sched<[WriteISReg, ReadI, ReadISReg]> { 3375 bits<5> Rd; 3376 bits<5> Rn; 3377 bits<5> Rm; 3378 bits<8> shift; 3379 let Inst{30-29} = opc; 3380 let Inst{28-24} = 0b01010; 3381 let Inst{23-22} = shift{7-6}; 3382 let Inst{21} = N; 3383 let Inst{20-16} = Rm; 3384 let Inst{15-10} = shift{5-0}; 3385 let Inst{9-5} = Rn; 3386 let Inst{4-0} = Rd; 3387 3388 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 3389} 3390 3391// Aliases for register+register logical instructions. 3392class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 3393 : InstAlias<asm#"\t$dst, $src1, $src2", 3394 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 3395 3396multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 3397 string Alias> { 3398 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3399 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 3400 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 3401 logical_imm32:$imm))]> { 3402 let Inst{31} = 0; 3403 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3404 } 3405 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3406 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 3407 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 3408 logical_imm64:$imm))]> { 3409 let Inst{31} = 1; 3410 } 3411 3412 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3413 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 3414 logical_imm32_not:$imm), 0>; 3415 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3416 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 3417 logical_imm64_not:$imm), 0>; 3418} 3419 3420multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 3421 string Alias> { 3422 let isCompare = 1, Defs = [NZCV] in { 3423 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 3424 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 3425 let Inst{31} = 0; 3426 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3427 } 3428 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 3429 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 3430 let Inst{31} = 1; 3431 } 3432 } // end Defs = [NZCV] 3433 3434 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3435 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 3436 logical_imm32_not:$imm), 0>; 3437 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3438 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 3439 logical_imm64_not:$imm), 0>; 3440} 3441 3442class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 3443 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3444 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 3445 Sched<[WriteI, ReadI, ReadI]>; 3446 3447// Split from LogicalImm as not all instructions have both. 3448multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 3449 SDPatternOperator OpNode, int AddedComplexityVal = 0> { 3450 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in { 3451 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3452 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3453 } 3454 3455 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3456 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3457 logical_shifted_reg32:$Rm_and_shift))]> { 3458 let Inst{31} = 0; 3459 } 3460 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3461 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3462 logical_shifted_reg64:$Rm_and_shift))]> { 3463 let Inst{31} = 1; 3464 } 3465 3466 def : LogicalRegAlias<mnemonic, 3467 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3468 def : LogicalRegAlias<mnemonic, 3469 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3470} 3471 3472// Split from LogicalReg to allow setting NZCV Defs 3473multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3474 SDPatternOperator OpNode = null_frag> { 3475 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3476 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3477 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3478 3479 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3480 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> { 3481 let Inst{31} = 0; 3482 } 3483 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3484 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> { 3485 let Inst{31} = 1; 3486 } 3487 } // Defs = [NZCV] 3488 3489 def : LogicalRegAlias<mnemonic, 3490 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3491 def : LogicalRegAlias<mnemonic, 3492 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3493} 3494 3495//--- 3496// Conditionally set flags 3497//--- 3498 3499let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3500class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3501 string mnemonic, SDNode OpNode> 3502 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3503 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3504 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3505 (i32 imm:$cond), NZCV))]>, 3506 Sched<[WriteI, ReadI]> { 3507 let Uses = [NZCV]; 3508 let Defs = [NZCV]; 3509 3510 bits<5> Rn; 3511 bits<5> imm; 3512 bits<4> nzcv; 3513 bits<4> cond; 3514 3515 let Inst{30} = op; 3516 let Inst{29-21} = 0b111010010; 3517 let Inst{20-16} = imm; 3518 let Inst{15-12} = cond; 3519 let Inst{11-10} = 0b10; 3520 let Inst{9-5} = Rn; 3521 let Inst{4} = 0b0; 3522 let Inst{3-0} = nzcv; 3523} 3524 3525let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3526class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3527 SDNode OpNode> 3528 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3529 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3530 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3531 (i32 imm:$cond), NZCV))]>, 3532 Sched<[WriteI, ReadI, ReadI]> { 3533 let Uses = [NZCV]; 3534 let Defs = [NZCV]; 3535 3536 bits<5> Rn; 3537 bits<5> Rm; 3538 bits<4> nzcv; 3539 bits<4> cond; 3540 3541 let Inst{30} = op; 3542 let Inst{29-21} = 0b111010010; 3543 let Inst{20-16} = Rm; 3544 let Inst{15-12} = cond; 3545 let Inst{11-10} = 0b00; 3546 let Inst{9-5} = Rn; 3547 let Inst{4} = 0b0; 3548 let Inst{3-0} = nzcv; 3549} 3550 3551multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3552 // immediate operand variants 3553 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3554 let Inst{31} = 0; 3555 } 3556 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3557 let Inst{31} = 1; 3558 } 3559 // register operand variants 3560 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3561 let Inst{31} = 0; 3562 } 3563 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3564 let Inst{31} = 1; 3565 } 3566} 3567 3568//--- 3569// Conditional select 3570//--- 3571 3572class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3573 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3574 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3575 [(set regtype:$Rd, 3576 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3577 Sched<[WriteI, ReadI, ReadI]> { 3578 let Uses = [NZCV]; 3579 3580 bits<5> Rd; 3581 bits<5> Rn; 3582 bits<5> Rm; 3583 bits<4> cond; 3584 3585 let Inst{30} = op; 3586 let Inst{29-21} = 0b011010100; 3587 let Inst{20-16} = Rm; 3588 let Inst{15-12} = cond; 3589 let Inst{11-10} = op2; 3590 let Inst{9-5} = Rn; 3591 let Inst{4-0} = Rd; 3592} 3593 3594multiclass CondSelect<bit op, bits<2> op2, string asm> { 3595 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3596 let Inst{31} = 0; 3597 } 3598 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3599 let Inst{31} = 1; 3600 } 3601} 3602 3603class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3604 PatFrag frag> 3605 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3606 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3607 [(set regtype:$Rd, 3608 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3609 (i32 imm:$cond), NZCV))]>, 3610 Sched<[WriteI, ReadI, ReadI]> { 3611 let Uses = [NZCV]; 3612 3613 bits<5> Rd; 3614 bits<5> Rn; 3615 bits<5> Rm; 3616 bits<4> cond; 3617 3618 let Inst{30} = op; 3619 let Inst{29-21} = 0b011010100; 3620 let Inst{20-16} = Rm; 3621 let Inst{15-12} = cond; 3622 let Inst{11-10} = op2; 3623 let Inst{9-5} = Rn; 3624 let Inst{4-0} = Rd; 3625} 3626 3627def inv_cond_XFORM : SDNodeXForm<imm, [{ 3628 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3629 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3630 MVT::i32); 3631}]>; 3632 3633multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3634 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3635 let Inst{31} = 0; 3636 } 3637 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3638 let Inst{31} = 1; 3639 } 3640 3641 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3642 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3643 (inv_cond_XFORM imm:$cond))>; 3644 3645 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3646 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3647 (inv_cond_XFORM imm:$cond))>; 3648} 3649 3650//--- 3651// Special Mask Value 3652//--- 3653def maski8_or_more : Operand<i32>, 3654 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3655} 3656def maski16_or_more : Operand<i32>, 3657 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3658} 3659 3660 3661//--- 3662// Load/store 3663//--- 3664 3665// (unsigned immediate) 3666// Indexed for 8-bit registers. offset is in range [0,4095]. 3667def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3668def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3669def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3670def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3671def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3672 3673// (unsigned immediate) 3674// Indexed for 8-bit registers. offset is in range [0,63]. 3675def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3676def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3677def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3678def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3679 3680def gi_am_indexed8 : 3681 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3682 GIComplexPatternEquiv<am_indexed8>; 3683def gi_am_indexed16 : 3684 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3685 GIComplexPatternEquiv<am_indexed16>; 3686def gi_am_indexed32 : 3687 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3688 GIComplexPatternEquiv<am_indexed32>; 3689def gi_am_indexed64 : 3690 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3691 GIComplexPatternEquiv<am_indexed64>; 3692def gi_am_indexed128 : 3693 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3694 GIComplexPatternEquiv<am_indexed128>; 3695 3696class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3697 let Name = "UImm12Offset" # Scale; 3698 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3699 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3700 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3701} 3702 3703def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3704def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3705def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3706def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3707def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3708 3709class uimm12_scaled<int Scale> : Operand<i64> { 3710 let ParserMatchClass 3711 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3712 let EncoderMethod 3713 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3714 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3715} 3716 3717def uimm12s1 : uimm12_scaled<1>; 3718def uimm12s2 : uimm12_scaled<2>; 3719def uimm12s4 : uimm12_scaled<4>; 3720def uimm12s8 : uimm12_scaled<8>; 3721def uimm12s16 : uimm12_scaled<16>; 3722 3723class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3724 string asm, list<dag> pattern> 3725 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3726 bits<5> Rt; 3727 3728 bits<5> Rn; 3729 bits<12> offset; 3730 3731 let Inst{31-30} = sz; 3732 let Inst{29-27} = 0b111; 3733 let Inst{26} = V; 3734 let Inst{25-24} = 0b01; 3735 let Inst{23-22} = opc; 3736 let Inst{21-10} = offset; 3737 let Inst{9-5} = Rn; 3738 let Inst{4-0} = Rt; 3739 3740 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3741} 3742 3743multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3744 Operand indextype, string asm, list<dag> pattern> { 3745 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3746 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3747 (ins GPR64sp:$Rn, indextype:$offset), 3748 asm, pattern>, 3749 Sched<[WriteLD]>; 3750 3751 def : InstAlias<asm # "\t$Rt, [$Rn]", 3752 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3753} 3754 3755multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3756 Operand indextype, string asm, list<dag> pattern> { 3757 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3758 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3759 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3760 asm, pattern>, 3761 Sched<[WriteST]>; 3762 3763 def : InstAlias<asm # "\t$Rt, [$Rn]", 3764 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3765} 3766 3767// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3768// substitute zero-registers automatically. 3769// 3770// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3771// into StoreUI. 3772multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3773 Operand indextype, string asm, list<dag> pattern> { 3774 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3775 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3776 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3777 asm, pattern>, 3778 Sched<[WriteST]>; 3779 3780 def : InstAlias<asm # "\t$Rt, [$Rn]", 3781 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3782} 3783 3784def PrefetchOperand : AsmOperandClass { 3785 let Name = "Prefetch"; 3786 let ParserMethod = "tryParsePrefetch"; 3787} 3788def prfop : Operand<i32> { 3789 let PrintMethod = "printPrefetchOp"; 3790 let ParserMatchClass = PrefetchOperand; 3791} 3792 3793let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3794class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3795 : BaseLoadStoreUI<sz, V, opc, 3796 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3797 asm, pat>, 3798 Sched<[WriteLD]>; 3799 3800//--- 3801// Load literal 3802//--- 3803 3804// Load literal address: 19-bit immediate. The low two bits of the target 3805// offset are implied zero and so are not part of the immediate. 3806def am_ldrlit : Operand<iPTR> { 3807 let EncoderMethod = "getLoadLiteralOpValue"; 3808 let DecoderMethod = "DecodePCRelLabel19"; 3809 let PrintMethod = "printAlignedLabel"; 3810 let ParserMatchClass = PCRelLabel19Operand; 3811 let OperandType = "OPERAND_PCREL"; 3812} 3813 3814let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3815class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3816 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3817 asm, "\t$Rt, $label", "", pat>, 3818 Sched<[WriteLD]> { 3819 bits<5> Rt; 3820 bits<19> label; 3821 let Inst{31-30} = opc; 3822 let Inst{29-27} = 0b011; 3823 let Inst{26} = V; 3824 let Inst{25-24} = 0b00; 3825 let Inst{23-5} = label; 3826 let Inst{4-0} = Rt; 3827} 3828 3829let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3830class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3831 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3832 asm, "\t$Rt, $label", "", pat>, 3833 Sched<[WriteLD]> { 3834 bits<5> Rt; 3835 bits<19> label; 3836 let Inst{31-30} = opc; 3837 let Inst{29-27} = 0b011; 3838 let Inst{26} = V; 3839 let Inst{25-24} = 0b00; 3840 let Inst{23-5} = label; 3841 let Inst{4-0} = Rt; 3842} 3843 3844//--- 3845// Load/store register offset 3846//--- 3847 3848def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3849def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3850def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3851def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3852def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3853 3854def gi_ro_Xindexed8 : 3855 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3856 GIComplexPatternEquiv<ro_Xindexed8>; 3857def gi_ro_Xindexed16 : 3858 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3859 GIComplexPatternEquiv<ro_Xindexed16>; 3860def gi_ro_Xindexed32 : 3861 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3862 GIComplexPatternEquiv<ro_Xindexed32>; 3863def gi_ro_Xindexed64 : 3864 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3865 GIComplexPatternEquiv<ro_Xindexed64>; 3866def gi_ro_Xindexed128 : 3867 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3868 GIComplexPatternEquiv<ro_Xindexed128>; 3869 3870def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3871def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3872def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3873def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3874def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3875 3876def gi_ro_Windexed8 : 3877 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3878 GIComplexPatternEquiv<ro_Windexed8>; 3879def gi_ro_Windexed16 : 3880 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3881 GIComplexPatternEquiv<ro_Windexed16>; 3882def gi_ro_Windexed32 : 3883 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3884 GIComplexPatternEquiv<ro_Windexed32>; 3885def gi_ro_Windexed64 : 3886 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3887 GIComplexPatternEquiv<ro_Windexed64>; 3888def gi_ro_Windexed128 : 3889 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3890 GIComplexPatternEquiv<ro_Windexed128>; 3891 3892class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3893 let Name = "Mem" # Reg # "Extend" # Width; 3894 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3895 let RenderMethod = "addMemExtendOperands"; 3896 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3897} 3898 3899def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3900 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3901 // the trivial shift. 3902 let RenderMethod = "addMemExtend8Operands"; 3903} 3904def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3905def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3906def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3907def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3908 3909def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3910 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3911 // the trivial shift. 3912 let RenderMethod = "addMemExtend8Operands"; 3913} 3914def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3915def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3916def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3917def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3918 3919class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3920 : Operand<i32> { 3921 let ParserMatchClass = ParserClass; 3922 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3923 let DecoderMethod = "DecodeMemExtend"; 3924 let EncoderMethod = "getMemExtendOpValue"; 3925 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3926} 3927 3928def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3929def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3930def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3931def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3932def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3933 3934def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3935def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3936def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3937def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3938def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3939 3940class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3941 Operand wextend, Operand xextend> { 3942 // CodeGen-level pattern covering the entire addressing mode. 3943 ComplexPattern Wpat = windex; 3944 ComplexPattern Xpat = xindex; 3945 3946 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3947 Operand Wext = wextend; 3948 Operand Xext = xextend; 3949} 3950 3951def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3952def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3953def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3954def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3955def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3956 ro_Xextend128>; 3957 3958class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3959 dag outs, list<dag> pat> 3960 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3961 bits<5> Rt; 3962 bits<5> Rn; 3963 bits<5> Rm; 3964 bits<2> extend; 3965 let Inst{31-30} = sz; 3966 let Inst{29-27} = 0b111; 3967 let Inst{26} = V; 3968 let Inst{25-24} = 0b00; 3969 let Inst{23-22} = opc; 3970 let Inst{21} = 1; 3971 let Inst{20-16} = Rm; 3972 let Inst{15} = extend{1}; // sign extend Rm? 3973 let Inst{14} = 1; 3974 let Inst{12} = extend{0}; // do shift? 3975 let Inst{11-10} = 0b10; 3976 let Inst{9-5} = Rn; 3977 let Inst{4-0} = Rt; 3978} 3979 3980class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3981 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3982 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3983 3984multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3985 string asm, ValueType Ty, SDPatternOperator loadop> { 3986 let AddedComplexity = 10 in 3987 def roW : LoadStore8RO<sz, V, opc, asm, 3988 (outs regtype:$Rt), 3989 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3990 [(set (Ty regtype:$Rt), 3991 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3992 ro_Wextend8:$extend)))]>, 3993 Sched<[WriteLDIdx, ReadAdrBase]> { 3994 let Inst{13} = 0b0; 3995 } 3996 3997 let AddedComplexity = 10 in 3998 def roX : LoadStore8RO<sz, V, opc, asm, 3999 (outs regtype:$Rt), 4000 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 4001 [(set (Ty regtype:$Rt), 4002 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 4003 ro_Xextend8:$extend)))]>, 4004 Sched<[WriteLDIdx, ReadAdrBase]> { 4005 let Inst{13} = 0b1; 4006 } 4007 4008 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4009} 4010 4011multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4012 string asm, ValueType Ty, SDPatternOperator storeop> { 4013 let AddedComplexity = 10 in 4014 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 4015 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 4016 [(storeop (Ty regtype:$Rt), 4017 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 4018 ro_Wextend8:$extend))]>, 4019 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4020 let Inst{13} = 0b0; 4021 } 4022 4023 let AddedComplexity = 10 in 4024 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 4025 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 4026 [(storeop (Ty regtype:$Rt), 4027 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 4028 ro_Xextend8:$extend))]>, 4029 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4030 let Inst{13} = 0b1; 4031 } 4032 4033 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4034} 4035 4036class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4037 dag outs, list<dag> pat> 4038 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4039 bits<5> Rt; 4040 bits<5> Rn; 4041 bits<5> Rm; 4042 bits<2> extend; 4043 let Inst{31-30} = sz; 4044 let Inst{29-27} = 0b111; 4045 let Inst{26} = V; 4046 let Inst{25-24} = 0b00; 4047 let Inst{23-22} = opc; 4048 let Inst{21} = 1; 4049 let Inst{20-16} = Rm; 4050 let Inst{15} = extend{1}; // sign extend Rm? 4051 let Inst{14} = 1; 4052 let Inst{12} = extend{0}; // do shift? 4053 let Inst{11-10} = 0b10; 4054 let Inst{9-5} = Rn; 4055 let Inst{4-0} = Rt; 4056} 4057 4058multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4059 string asm, ValueType Ty, SDPatternOperator loadop> { 4060 let AddedComplexity = 10 in 4061 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 4062 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 4063 [(set (Ty regtype:$Rt), 4064 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 4065 ro_Wextend16:$extend)))]>, 4066 Sched<[WriteLDIdx, ReadAdrBase]> { 4067 let Inst{13} = 0b0; 4068 } 4069 4070 let AddedComplexity = 10 in 4071 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 4072 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 4073 [(set (Ty regtype:$Rt), 4074 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 4075 ro_Xextend16:$extend)))]>, 4076 Sched<[WriteLDIdx, ReadAdrBase]> { 4077 let Inst{13} = 0b1; 4078 } 4079 4080 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4081} 4082 4083multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4084 string asm, ValueType Ty, SDPatternOperator storeop> { 4085 let AddedComplexity = 10 in 4086 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 4087 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 4088 [(storeop (Ty regtype:$Rt), 4089 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 4090 ro_Wextend16:$extend))]>, 4091 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4092 let Inst{13} = 0b0; 4093 } 4094 4095 let AddedComplexity = 10 in 4096 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 4097 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 4098 [(storeop (Ty regtype:$Rt), 4099 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 4100 ro_Xextend16:$extend))]>, 4101 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4102 let Inst{13} = 0b1; 4103 } 4104 4105 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4106} 4107 4108class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4109 dag outs, list<dag> pat> 4110 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4111 bits<5> Rt; 4112 bits<5> Rn; 4113 bits<5> Rm; 4114 bits<2> extend; 4115 let Inst{31-30} = sz; 4116 let Inst{29-27} = 0b111; 4117 let Inst{26} = V; 4118 let Inst{25-24} = 0b00; 4119 let Inst{23-22} = opc; 4120 let Inst{21} = 1; 4121 let Inst{20-16} = Rm; 4122 let Inst{15} = extend{1}; // sign extend Rm? 4123 let Inst{14} = 1; 4124 let Inst{12} = extend{0}; // do shift? 4125 let Inst{11-10} = 0b10; 4126 let Inst{9-5} = Rn; 4127 let Inst{4-0} = Rt; 4128} 4129 4130multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4131 string asm, ValueType Ty, SDPatternOperator loadop> { 4132 let AddedComplexity = 10 in 4133 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 4134 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 4135 [(set (Ty regtype:$Rt), 4136 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 4137 ro_Wextend32:$extend)))]>, 4138 Sched<[WriteLDIdx, ReadAdrBase]> { 4139 let Inst{13} = 0b0; 4140 } 4141 4142 let AddedComplexity = 10 in 4143 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 4144 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 4145 [(set (Ty regtype:$Rt), 4146 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 4147 ro_Xextend32:$extend)))]>, 4148 Sched<[WriteLDIdx, ReadAdrBase]> { 4149 let Inst{13} = 0b1; 4150 } 4151 4152 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4153} 4154 4155multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4156 string asm, ValueType Ty, SDPatternOperator storeop> { 4157 let AddedComplexity = 10 in 4158 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 4159 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 4160 [(storeop (Ty regtype:$Rt), 4161 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 4162 ro_Wextend32:$extend))]>, 4163 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4164 let Inst{13} = 0b0; 4165 } 4166 4167 let AddedComplexity = 10 in 4168 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 4169 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 4170 [(storeop (Ty regtype:$Rt), 4171 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 4172 ro_Xextend32:$extend))]>, 4173 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4174 let Inst{13} = 0b1; 4175 } 4176 4177 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4178} 4179 4180class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4181 dag outs, list<dag> pat> 4182 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4183 bits<5> Rt; 4184 bits<5> Rn; 4185 bits<5> Rm; 4186 bits<2> extend; 4187 let Inst{31-30} = sz; 4188 let Inst{29-27} = 0b111; 4189 let Inst{26} = V; 4190 let Inst{25-24} = 0b00; 4191 let Inst{23-22} = opc; 4192 let Inst{21} = 1; 4193 let Inst{20-16} = Rm; 4194 let Inst{15} = extend{1}; // sign extend Rm? 4195 let Inst{14} = 1; 4196 let Inst{12} = extend{0}; // do shift? 4197 let Inst{11-10} = 0b10; 4198 let Inst{9-5} = Rn; 4199 let Inst{4-0} = Rt; 4200} 4201 4202multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4203 string asm, ValueType Ty, SDPatternOperator loadop> { 4204 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4205 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4206 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4207 [(set (Ty regtype:$Rt), 4208 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4209 ro_Wextend64:$extend)))]>, 4210 Sched<[WriteLDIdx, ReadAdrBase]> { 4211 let Inst{13} = 0b0; 4212 } 4213 4214 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4215 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4216 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4217 [(set (Ty regtype:$Rt), 4218 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4219 ro_Xextend64:$extend)))]>, 4220 Sched<[WriteLDIdx, ReadAdrBase]> { 4221 let Inst{13} = 0b1; 4222 } 4223 4224 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4225} 4226 4227multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4228 string asm, ValueType Ty, SDPatternOperator storeop> { 4229 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4230 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 4231 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4232 [(storeop (Ty regtype:$Rt), 4233 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4234 ro_Wextend64:$extend))]>, 4235 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4236 let Inst{13} = 0b0; 4237 } 4238 4239 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4240 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 4241 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4242 [(storeop (Ty regtype:$Rt), 4243 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4244 ro_Xextend64:$extend))]>, 4245 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4246 let Inst{13} = 0b1; 4247 } 4248 4249 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4250} 4251 4252class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4253 dag outs, list<dag> pat> 4254 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4255 bits<5> Rt; 4256 bits<5> Rn; 4257 bits<5> Rm; 4258 bits<2> extend; 4259 let Inst{31-30} = sz; 4260 let Inst{29-27} = 0b111; 4261 let Inst{26} = V; 4262 let Inst{25-24} = 0b00; 4263 let Inst{23-22} = opc; 4264 let Inst{21} = 1; 4265 let Inst{20-16} = Rm; 4266 let Inst{15} = extend{1}; // sign extend Rm? 4267 let Inst{14} = 1; 4268 let Inst{12} = extend{0}; // do shift? 4269 let Inst{11-10} = 0b10; 4270 let Inst{9-5} = Rn; 4271 let Inst{4-0} = Rt; 4272} 4273 4274multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4275 string asm, ValueType Ty, SDPatternOperator loadop> { 4276 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4277 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4278 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4279 [(set (Ty regtype:$Rt), 4280 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 4281 ro_Wextend128:$extend)))]>, 4282 Sched<[WriteLDIdx, ReadAdrBase]> { 4283 let Inst{13} = 0b0; 4284 } 4285 4286 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4287 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4288 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4289 [(set (Ty regtype:$Rt), 4290 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 4291 ro_Xextend128:$extend)))]>, 4292 Sched<[WriteLDIdx, ReadAdrBase]> { 4293 let Inst{13} = 0b1; 4294 } 4295 4296 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4297} 4298 4299multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4300 string asm> { 4301 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4302 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 4303 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4304 []>, 4305 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4306 let Inst{13} = 0b0; 4307 } 4308 4309 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4310 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 4311 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4312 []>, 4313 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4314 let Inst{13} = 0b1; 4315 } 4316 4317 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4318} 4319 4320let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4321class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 4322 string asm, list<dag> pat> 4323 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 4324 Sched<[WriteLD]> { 4325 bits<5> Rt; 4326 bits<5> Rn; 4327 bits<5> Rm; 4328 bits<2> extend; 4329 let Inst{31-30} = sz; 4330 let Inst{29-27} = 0b111; 4331 let Inst{26} = V; 4332 let Inst{25-24} = 0b00; 4333 let Inst{23-22} = opc; 4334 let Inst{21} = 1; 4335 let Inst{20-16} = Rm; 4336 let Inst{15} = extend{1}; // sign extend Rm? 4337 let Inst{14} = 1; 4338 let Inst{12} = extend{0}; // do shift? 4339 let Inst{11-10} = 0b10; 4340 let Inst{9-5} = Rn; 4341 let Inst{4-0} = Rt; 4342 let DecoderMethod = "DecodePRFMRegInstruction"; 4343 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When 4344 // the decoder method returns Fail, the decoder should attempt to decode the 4345 // instruction as RPRFM. 4346 let hasCompleteDecoder = 0; 4347} 4348 4349multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 4350 def roW : BasePrefetchRO<sz, V, opc, (outs), 4351 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4352 asm, [(AArch64Prefetch timm:$Rt, 4353 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4354 ro_Wextend64:$extend))]> { 4355 let Inst{13} = 0b0; 4356 } 4357 4358 def roX : BasePrefetchRO<sz, V, opc, (outs), 4359 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4360 asm, [(AArch64Prefetch timm:$Rt, 4361 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4362 ro_Xextend64:$extend))]> { 4363 let Inst{13} = 0b1; 4364 } 4365 4366 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 4367 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 4368 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 4369} 4370 4371//--- 4372// Load/store unscaled immediate 4373//--- 4374 4375def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 4376def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 4377def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 4378def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 4379def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 4380 4381def gi_am_unscaled8 : 4382 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 4383 GIComplexPatternEquiv<am_unscaled8>; 4384def gi_am_unscaled16 : 4385 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 4386 GIComplexPatternEquiv<am_unscaled16>; 4387def gi_am_unscaled32 : 4388 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 4389 GIComplexPatternEquiv<am_unscaled32>; 4390def gi_am_unscaled64 : 4391 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 4392 GIComplexPatternEquiv<am_unscaled64>; 4393def gi_am_unscaled128 : 4394 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 4395 GIComplexPatternEquiv<am_unscaled128>; 4396 4397 4398class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4399 string asm, list<dag> pattern> 4400 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 4401 bits<5> Rt; 4402 bits<5> Rn; 4403 bits<9> offset; 4404 let Inst{31-30} = sz; 4405 let Inst{29-27} = 0b111; 4406 let Inst{26} = V; 4407 let Inst{25-24} = 0b00; 4408 let Inst{23-22} = opc; 4409 let Inst{21} = 0; 4410 let Inst{20-12} = offset; 4411 let Inst{11-10} = 0b00; 4412 let Inst{9-5} = Rn; 4413 let Inst{4-0} = Rt; 4414 4415 let DecoderMethod = "DecodeSignedLdStInstruction"; 4416} 4417 4418// Armv8.4 LDAPR & STLR with Immediate Offset instruction 4419multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4420 DAGOperand regtype > { 4421 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 4422 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 4423 Sched<[WriteST]> { 4424 let Inst{29} = 0; 4425 let Inst{24} = 1; 4426 } 4427 def : InstAlias<asm # "\t$Rt, [$Rn]", 4428 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4429} 4430 4431multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4432 DAGOperand regtype > { 4433 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 4434 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4435 asm, []>, 4436 Sched<[WriteST]> { 4437 let Inst{29} = 0; 4438 let Inst{24} = 1; 4439 } 4440 def : InstAlias<asm # "\t$Rt, [$Rn]", 4441 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4442} 4443 4444multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4445 string asm, list<dag> pattern> { 4446 let AddedComplexity = 1 in // try this before LoadUI 4447 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 4448 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 4449 Sched<[WriteLD]>; 4450 4451 def : InstAlias<asm # "\t$Rt, [$Rn]", 4452 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4453} 4454 4455multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4456 string asm, list<dag> pattern> { 4457 let AddedComplexity = 1 in // try this before StoreUI 4458 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4459 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4460 asm, pattern>, 4461 Sched<[WriteST]>; 4462 4463 def : InstAlias<asm # "\t$Rt, [$Rn]", 4464 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4465} 4466 4467multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4468 list<dag> pat> { 4469 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4470 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4471 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4472 asm, pat>, 4473 Sched<[WriteLD]>; 4474 4475 def : InstAlias<asm # "\t$Rt, [$Rn]", 4476 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4477} 4478 4479//--- 4480// Load/store unscaled immediate, unprivileged 4481//--- 4482 4483class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4484 dag oops, dag iops, string asm> 4485 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4486 bits<5> Rt; 4487 bits<5> Rn; 4488 bits<9> offset; 4489 let Inst{31-30} = sz; 4490 let Inst{29-27} = 0b111; 4491 let Inst{26} = V; 4492 let Inst{25-24} = 0b00; 4493 let Inst{23-22} = opc; 4494 let Inst{21} = 0; 4495 let Inst{20-12} = offset; 4496 let Inst{11-10} = 0b10; 4497 let Inst{9-5} = Rn; 4498 let Inst{4-0} = Rt; 4499 4500 let DecoderMethod = "DecodeSignedLdStInstruction"; 4501} 4502 4503multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4504 RegisterClass regtype, string asm> { 4505 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4506 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4507 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4508 Sched<[WriteLD]>; 4509 4510 def : InstAlias<asm # "\t$Rt, [$Rn]", 4511 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4512} 4513 4514multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4515 RegisterClass regtype, string asm> { 4516 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4517 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4518 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4519 asm>, 4520 Sched<[WriteST]>; 4521 4522 def : InstAlias<asm # "\t$Rt, [$Rn]", 4523 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4524} 4525 4526//--- 4527// Load/store pre-indexed 4528//--- 4529 4530class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4531 string asm, string cstr, list<dag> pat> 4532 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4533 bits<5> Rt; 4534 bits<5> Rn; 4535 bits<9> offset; 4536 let Inst{31-30} = sz; 4537 let Inst{29-27} = 0b111; 4538 let Inst{26} = V; 4539 let Inst{25-24} = 0; 4540 let Inst{23-22} = opc; 4541 let Inst{21} = 0; 4542 let Inst{20-12} = offset; 4543 let Inst{11-10} = 0b11; 4544 let Inst{9-5} = Rn; 4545 let Inst{4-0} = Rt; 4546 4547 let DecoderMethod = "DecodeSignedLdStInstruction"; 4548} 4549 4550let hasSideEffects = 0 in { 4551let mayStore = 0, mayLoad = 1 in 4552class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4553 string asm> 4554 : BaseLoadStorePreIdx<sz, V, opc, 4555 (outs GPR64sp:$wback, regtype:$Rt), 4556 (ins GPR64sp:$Rn, simm9:$offset), asm, 4557 "$Rn = $wback,@earlyclobber $wback", []>, 4558 Sched<[WriteAdr, WriteLD]>; 4559 4560let mayStore = 1, mayLoad = 0 in 4561class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4562 string asm, SDPatternOperator storeop, ValueType Ty> 4563 : BaseLoadStorePreIdx<sz, V, opc, 4564 (outs GPR64sp:$wback), 4565 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4566 asm, "$Rn = $wback,@earlyclobber $wback", 4567 [(set GPR64sp:$wback, 4568 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4569 Sched<[WriteAdr, WriteST]>; 4570} // hasSideEffects = 0 4571 4572//--- 4573// Load/store post-indexed 4574//--- 4575 4576class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4577 string asm, string cstr, list<dag> pat> 4578 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4579 bits<5> Rt; 4580 bits<5> Rn; 4581 bits<9> offset; 4582 let Inst{31-30} = sz; 4583 let Inst{29-27} = 0b111; 4584 let Inst{26} = V; 4585 let Inst{25-24} = 0b00; 4586 let Inst{23-22} = opc; 4587 let Inst{21} = 0b0; 4588 let Inst{20-12} = offset; 4589 let Inst{11-10} = 0b01; 4590 let Inst{9-5} = Rn; 4591 let Inst{4-0} = Rt; 4592 4593 let DecoderMethod = "DecodeSignedLdStInstruction"; 4594} 4595 4596let hasSideEffects = 0 in { 4597let mayStore = 0, mayLoad = 1 in 4598class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4599 string asm> 4600 : BaseLoadStorePostIdx<sz, V, opc, 4601 (outs GPR64sp:$wback, regtype:$Rt), 4602 (ins GPR64sp:$Rn, simm9:$offset), 4603 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4604 Sched<[WriteAdr, WriteLD]>; 4605 4606let mayStore = 1, mayLoad = 0 in 4607class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4608 string asm, SDPatternOperator storeop, ValueType Ty> 4609 : BaseLoadStorePostIdx<sz, V, opc, 4610 (outs GPR64sp:$wback), 4611 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4612 asm, "$Rn = $wback,@earlyclobber $wback", 4613 [(set GPR64sp:$wback, 4614 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4615 Sched<[WriteAdr, WriteST]>; 4616} // hasSideEffects = 0 4617 4618 4619//--- 4620// Load/store pair 4621//--- 4622 4623// (indexed, offset) 4624 4625class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4626 string asm> 4627 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4628 bits<5> Rt; 4629 bits<5> Rt2; 4630 bits<5> Rn; 4631 bits<7> offset; 4632 let Inst{31-30} = opc; 4633 let Inst{29-27} = 0b101; 4634 let Inst{26} = V; 4635 let Inst{25-23} = 0b010; 4636 let Inst{22} = L; 4637 let Inst{21-15} = offset; 4638 let Inst{14-10} = Rt2; 4639 let Inst{9-5} = Rn; 4640 let Inst{4-0} = Rt; 4641 4642 let DecoderMethod = "DecodePairLdStInstruction"; 4643} 4644 4645multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4646 Operand indextype, string asm> { 4647 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4648 def i : BaseLoadStorePairOffset<opc, V, 1, 4649 (outs regtype:$Rt, regtype:$Rt2), 4650 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4651 Sched<[WriteLD, WriteLDHi]>; 4652 4653 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4654 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4655 GPR64sp:$Rn, 0)>; 4656} 4657 4658 4659multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4660 Operand indextype, string asm> { 4661 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4662 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4663 (ins regtype:$Rt, regtype:$Rt2, 4664 GPR64sp:$Rn, indextype:$offset), 4665 asm>, 4666 Sched<[WriteSTP]>; 4667 4668 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4669 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4670 GPR64sp:$Rn, 0)>; 4671} 4672 4673// (pre-indexed) 4674class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4675 string asm> 4676 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4677 bits<5> Rt; 4678 bits<5> Rt2; 4679 bits<5> Rn; 4680 bits<7> offset; 4681 let Inst{31-30} = opc; 4682 let Inst{29-27} = 0b101; 4683 let Inst{26} = V; 4684 let Inst{25-23} = 0b011; 4685 let Inst{22} = L; 4686 let Inst{21-15} = offset; 4687 let Inst{14-10} = Rt2; 4688 let Inst{9-5} = Rn; 4689 let Inst{4-0} = Rt; 4690 4691 let DecoderMethod = "DecodePairLdStInstruction"; 4692} 4693 4694let hasSideEffects = 0 in { 4695let mayStore = 0, mayLoad = 1 in 4696class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4697 Operand indextype, string asm> 4698 : BaseLoadStorePairPreIdx<opc, V, 1, 4699 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4700 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4701 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4702 4703let mayStore = 1, mayLoad = 0 in 4704class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4705 Operand indextype, string asm> 4706 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4707 (ins regtype:$Rt, regtype:$Rt2, 4708 GPR64sp:$Rn, indextype:$offset), 4709 asm>, 4710 Sched<[WriteAdr, WriteSTP]>; 4711} // hasSideEffects = 0 4712 4713// (post-indexed) 4714 4715class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4716 string asm> 4717 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4718 bits<5> Rt; 4719 bits<5> Rt2; 4720 bits<5> Rn; 4721 bits<7> offset; 4722 let Inst{31-30} = opc; 4723 let Inst{29-27} = 0b101; 4724 let Inst{26} = V; 4725 let Inst{25-23} = 0b001; 4726 let Inst{22} = L; 4727 let Inst{21-15} = offset; 4728 let Inst{14-10} = Rt2; 4729 let Inst{9-5} = Rn; 4730 let Inst{4-0} = Rt; 4731 4732 let DecoderMethod = "DecodePairLdStInstruction"; 4733} 4734 4735let hasSideEffects = 0 in { 4736let mayStore = 0, mayLoad = 1 in 4737class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4738 Operand idxtype, string asm> 4739 : BaseLoadStorePairPostIdx<opc, V, 1, 4740 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4741 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4742 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4743 4744let mayStore = 1, mayLoad = 0 in 4745class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4746 Operand idxtype, string asm> 4747 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4748 (ins regtype:$Rt, regtype:$Rt2, 4749 GPR64sp:$Rn, idxtype:$offset), 4750 asm>, 4751 Sched<[WriteAdr, WriteSTP]>; 4752} // hasSideEffects = 0 4753 4754// (no-allocate) 4755 4756class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4757 string asm> 4758 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4759 bits<5> Rt; 4760 bits<5> Rt2; 4761 bits<5> Rn; 4762 bits<7> offset; 4763 let Inst{31-30} = opc; 4764 let Inst{29-27} = 0b101; 4765 let Inst{26} = V; 4766 let Inst{25-23} = 0b000; 4767 let Inst{22} = L; 4768 let Inst{21-15} = offset; 4769 let Inst{14-10} = Rt2; 4770 let Inst{9-5} = Rn; 4771 let Inst{4-0} = Rt; 4772 4773 let DecoderMethod = "DecodePairLdStInstruction"; 4774} 4775 4776multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4777 Operand indextype, string asm> { 4778 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4779 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4780 (outs regtype:$Rt, regtype:$Rt2), 4781 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4782 Sched<[WriteLD, WriteLDHi]>; 4783 4784 4785 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4786 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4787 GPR64sp:$Rn, 0)>; 4788} 4789 4790multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4791 Operand indextype, string asm> { 4792 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4793 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4794 (ins regtype:$Rt, regtype:$Rt2, 4795 GPR64sp:$Rn, indextype:$offset), 4796 asm>, 4797 Sched<[WriteSTP]>; 4798 4799 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4800 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4801 GPR64sp:$Rn, 0)>; 4802} 4803 4804// armv9.6-a load/store no-allocate pair FEAT_LSUI (no-allocate) 4805 4806class BaseLoadStorePairNoAllocLSUI<bits<2> opc, bit V, bit L, dag oops, dag iops, 4807 string asm> 4808 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4809 bits<5> Rt; 4810 bits<5> Rt2; 4811 bits<5> Rn; 4812 bits<7> offset; 4813 let Inst{31-30} = opc; 4814 let Inst{29-27} = 0b101; 4815 let Inst{26} = V; 4816 let Inst{25-23} = 0b000; 4817 let Inst{22} = L; 4818 let Inst{21-15} = offset; 4819 let Inst{14-10} = Rt2; 4820 let Inst{9-5} = Rn; 4821 let Inst{4-0} = Rt; 4822 4823 let DecoderMethod = "DecodePairLdStInstruction"; 4824} 4825 4826multiclass LoadPairNoAllocLSUI<bits<2> opc, bit V, DAGOperand regtype, 4827 Operand indextype, string asm> { 4828 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4829 def i : BaseLoadStorePairNoAllocLSUI<opc, V, 1, 4830 (outs regtype:$Rt, regtype:$Rt2), 4831 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4832 Sched<[WriteLD, WriteLDHi]>; 4833 4834 4835 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4836 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4837 GPR64sp:$Rn, 0)>; 4838} 4839 4840multiclass StorePairNoAllocLSUI<bits<2> opc, bit V, DAGOperand regtype, 4841 Operand indextype, string asm> { 4842 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4843 def i : BaseLoadStorePairNoAllocLSUI<opc, V, 0, (outs), 4844 (ins regtype:$Rt, regtype:$Rt2, 4845 GPR64sp:$Rn, indextype:$offset), 4846 asm>, 4847 Sched<[WriteSTP]>; 4848 4849 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4850 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4851 GPR64sp:$Rn, 0)>; 4852} 4853 4854//--- 4855// Load/store exclusive 4856//--- 4857 4858// True exclusive operations write to and/or read from the system's exclusive 4859// monitors, which as far as a compiler is concerned can be modelled as a 4860// random shared memory address. Hence LoadExclusive mayStore. 4861// 4862// Since these instructions have the undefined register bits set to 1 in 4863// their canonical form, we need a post encoder method to set those bits 4864// to 1 when encoding these instructions. We do this using the 4865// fixLoadStoreExclusive function. This function has template parameters: 4866// 4867// fixLoadStoreExclusive<int hasRs, int hasRt2> 4868// 4869// hasRs indicates that the instruction uses the Rs field, so we won't set 4870// it to 1 (and the same for Rt2). We don't need template parameters for 4871// the other register fields since Rt and Rn are always used. 4872// 4873let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4874class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4875 dag oops, dag iops, string asm, string operands> 4876 : I<oops, iops, asm, operands, "", []> { 4877 let Inst{31-30} = sz; 4878 let Inst{29-24} = 0b001000; 4879 let Inst{23} = o2; 4880 let Inst{22} = L; 4881 let Inst{21} = o1; 4882 let Inst{15} = o0; 4883 4884 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4885} 4886 4887// Neither Rs nor Rt2 operands. 4888class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4889 dag oops, dag iops, string asm, string operands> 4890 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4891 bits<5> Rt; 4892 bits<5> Rn; 4893 let Inst{20-16} = 0b11111; 4894 let Unpredictable{20-16} = 0b11111; 4895 let Inst{14-10} = 0b11111; 4896 let Unpredictable{14-10} = 0b11111; 4897 let Inst{9-5} = Rn; 4898 let Inst{4-0} = Rt; 4899 4900 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4901} 4902 4903// Simple load acquires don't set the exclusive monitor 4904let mayLoad = 1, mayStore = 0 in 4905class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4906 RegisterClass regtype, string asm> 4907 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4908 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4909 Sched<[WriteLD]>; 4910 4911class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4912 RegisterClass regtype, string asm> 4913 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4914 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4915 Sched<[WriteLD]>; 4916 4917class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4918 RegisterClass regtype, string asm> 4919 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4920 (outs regtype:$Rt, regtype:$Rt2), 4921 (ins GPR64sp0:$Rn), asm, 4922 "\t$Rt, $Rt2, [$Rn]">, 4923 Sched<[WriteLD, WriteLDHi]> { 4924 bits<5> Rt; 4925 bits<5> Rt2; 4926 bits<5> Rn; 4927 let Inst{20-16} = 0b11111; 4928 let Unpredictable{20-16} = 0b11111; 4929 let Inst{14-10} = Rt2; 4930 let Inst{9-5} = Rn; 4931 let Inst{4-0} = Rt; 4932 4933 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4934} 4935 4936// Armv9.6-a load-store exclusive instructions 4937let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4938class BaseLoadStoreExclusiveLSUI<bits<2> sz, bit L, bit o0, 4939 dag oops, dag iops, string asm, string operands> 4940 : I<oops, iops, asm, operands, "", []> { 4941 let Inst{31-30} = sz; 4942 let Inst{29-23} = 0b0010010; 4943 let Inst{22} = L; 4944 let Inst{21} = 0b0; 4945 let Inst{15} = o0; 4946} 4947 4948 4949// Neither Rs nor Rt2 operands. 4950 4951class LoadExclusiveLSUI<bits<2> sz, bit L, bit o0, 4952 RegisterClass regtype, string asm> 4953 : BaseLoadStoreExclusiveLSUI<sz, L, o0, (outs regtype:$Rt), 4954 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4955 Sched<[WriteLD]> 4956{ 4957 bits<5> Rt; 4958 bits<5> Rn; 4959 let Inst{20-16} = 0b11111; 4960 let Unpredictable{20-16} = 0b11111; 4961 let Inst{14-10} = 0b11111; 4962 let Unpredictable{14-10} = 0b11111; 4963 let Inst{9-5} = Rn; 4964 let Inst{4-0} = Rt; 4965 4966 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4967} 4968 4969 class StoreExclusiveLSUI<bits<2> sz, bit L, bit o0, 4970 RegisterClass regtype, string asm> 4971 : BaseLoadStoreExclusiveLSUI<sz, L, o0, (outs GPR32:$Ws), 4972 (ins regtype:$Rt, GPR64sp0:$Rn), 4973 asm, "\t$Ws, $Rt, [$Rn]">, 4974 Sched<[WriteSTX]> { 4975 bits<5> Ws; 4976 bits<5> Rt; 4977 bits<5> Rn; 4978 let Inst{20-16} = Ws; 4979 let Inst{15} = o0; 4980 let Inst{14-10} = 0b11111; 4981 let Unpredictable{14-10} = 0b11111; 4982 let Inst{9-5} = Rn; 4983 let Inst{4-0} = Rt; 4984 4985 let Constraints = "@earlyclobber $Ws"; 4986 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4987 } 4988 4989// Armv9.6-a load-store unprivileged instructions 4990class BaseLoadUnprivilegedLSUI<bits<2> sz, dag oops, dag iops, string asm> 4991 : I<oops, iops, asm, "\t$Rt, [$Rn]", "", []> { 4992 bits<5> Rt; 4993 bits<5> Rn; 4994 let Inst{31-30} = sz; 4995 let Inst{29-23} = 0b0010010; 4996 let Inst{22} = 0b1; 4997 let Inst{21} = 0b0; 4998 let Inst{20-16} = 0b11111; 4999 let Unpredictable{20-16} = 0b11111; 5000 let Inst{15} = 0b0; 5001 let Inst{14-10} = 0b11111; 5002 let Unpredictable{14-10} = 0b11111; 5003 let Inst{9-5} = Rn; 5004 let Inst{4-0} = Rt; 5005 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 5006} 5007 5008multiclass LoadUnprivilegedLSUI<bits<2> sz, RegisterClass regtype, string asm> { 5009 def r : BaseLoadUnprivilegedLSUI<sz, (outs regtype:$Rt), 5010 (ins GPR64sp0:$Rn), asm>, 5011 Sched<[WriteLD]>; 5012 5013} 5014 5015class BaseStoreUnprivilegedLSUI<bits<2> sz, dag oops, dag iops, string asm> 5016 : I<oops, iops, asm, "\t$Ws, $Rt, [$Rn]", "", []> { 5017 bits<5> Rt; 5018 bits<5> Rn; 5019 bits<5> Ws; 5020 let Inst{31-30} = sz; 5021 let Inst{29-23} = 0b0010010; 5022 let Inst{22} = 0b0; 5023 let Inst{21} = 0b0; 5024 let Inst{20-16} = Ws; 5025 let Inst{15} = 0b0; 5026 let Inst{14-10} = 0b11111; 5027 let Unpredictable{14-10} = 0b11111; 5028 let Inst{9-5} = Rn; 5029 let Inst{4-0} = Rt; 5030 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 5031 let mayStore = 1; 5032} 5033 5034multiclass StoreUnprivilegedLSUI<bits<2> sz, RegisterClass regtype, string asm> { 5035 def r : BaseStoreUnprivilegedLSUI<sz, (outs GPR32: $Ws), 5036 (ins regtype:$Rt, GPR64sp0:$Rn), 5037 asm>, 5038 Sched<[WriteSTX]>; 5039} 5040 5041// Simple store release operations do not check the exclusive monitor. 5042let mayLoad = 0, mayStore = 1 in 5043class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 5044 RegisterClass regtype, string asm> 5045 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 5046 (ins regtype:$Rt, GPR64sp:$Rn), 5047 asm, "\t$Rt, [$Rn]">, 5048 Sched<[WriteST]>; 5049 5050let mayLoad = 1, mayStore = 1 in 5051class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 5052 RegisterClass regtype, string asm> 5053 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 5054 (ins regtype:$Rt, GPR64sp0:$Rn), 5055 asm, "\t$Ws, $Rt, [$Rn]">, 5056 Sched<[WriteSTX]> { 5057 bits<5> Ws; 5058 bits<5> Rt; 5059 bits<5> Rn; 5060 let Inst{20-16} = Ws; 5061 let Inst{9-5} = Rn; 5062 let Inst{4-0} = Rt; 5063 5064 let Constraints = "@earlyclobber $Ws"; 5065 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 5066} 5067 5068class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 5069 RegisterClass regtype, string asm> 5070 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 5071 (outs GPR32:$Ws), 5072 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 5073 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 5074 Sched<[WriteSTX]> { 5075 bits<5> Ws; 5076 bits<5> Rt; 5077 bits<5> Rt2; 5078 bits<5> Rn; 5079 let Inst{20-16} = Ws; 5080 let Inst{14-10} = Rt2; 5081 let Inst{9-5} = Rn; 5082 let Inst{4-0} = Rt; 5083 5084 let Constraints = "@earlyclobber $Ws"; 5085} 5086 5087// Armv8.5-A Memory Tagging Extension 5088class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 5089 string asm_opnds, string cstr, dag oops, dag iops> 5090 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 5091 Sched<[]> { 5092 bits<5> Rn; 5093 5094 let Inst{31-24} = 0b11011001; 5095 let Inst{23-22} = opc1; 5096 let Inst{21} = 1; 5097 // Inst{20-12} defined by subclass 5098 let Inst{11-10} = opc2; 5099 let Inst{9-5} = Rn; 5100 // Inst{4-0} defined by subclass 5101} 5102 5103class MemTagVector<bit Load, string asm_insn, string asm_opnds, 5104 dag oops, dag iops> 5105 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 5106 "", oops, iops> { 5107 bits<5> Rt; 5108 5109 let Inst{20-12} = 0b000000000; 5110 let Inst{4-0} = Rt; 5111 5112 let mayLoad = Load; 5113} 5114 5115class MemTagLoad<string asm_insn, string asm_opnds> 5116 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 5117 (outs GPR64:$wback), 5118 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 5119 bits<5> Rt; 5120 bits<9> offset; 5121 5122 let Inst{20-12} = offset; 5123 let Inst{4-0} = Rt; 5124 5125 let mayLoad = 1; 5126} 5127 5128class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 5129 string asm_opnds, string cstr, dag oops, dag iops> 5130 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 5131 bits<5> Rt; 5132 bits<9> offset; 5133 5134 let Inst{20-12} = offset; 5135 let Inst{4-0} = Rt; 5136 5137 let mayStore = 1; 5138} 5139 5140multiclass MemTagStore<bits<2> opc1, string insn> { 5141 def i : 5142 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 5143 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 5144 def PreIndex : 5145 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 5146 "$Rn = $wback", 5147 (outs GPR64sp:$wback), 5148 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 5149 def PostIndex : 5150 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 5151 "$Rn = $wback", 5152 (outs GPR64sp:$wback), 5153 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 5154 5155 def : InstAlias<insn # "\t$Rt, [$Rn]", 5156 (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 5157} 5158 5159//--- 5160// Exception generation 5161//--- 5162 5163let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 5164class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 5165 list<dag> pattern = []> 5166 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 5167 Sched<[WriteSys]> { 5168 bits<16> imm; 5169 let Inst{31-24} = 0b11010100; 5170 let Inst{23-21} = op1; 5171 let Inst{20-5} = imm; 5172 let Inst{4-2} = 0b000; 5173 let Inst{1-0} = ll; 5174} 5175 5176//--- 5177// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 5178//-- 5179let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 5180class UDFType<bits<16> opc, string asm> 5181 : I<(outs), (ins uimm16:$imm), 5182 asm, "\t$imm", "", []>, 5183 Sched<[]> { 5184 bits<16> imm; 5185 let Inst{31-16} = opc; 5186 let Inst{15-0} = imm; 5187} 5188} 5189let Predicates = [HasFPARMv8] in { 5190 5191//--- 5192// Floating point to integer conversion 5193//--- 5194 5195let mayRaiseFPException = 1, Uses = [FPCR] in 5196class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 5197 RegisterClass srcType, RegisterClass dstType, 5198 string asm, list<dag> pattern> 5199 : I<(outs dstType:$Rd), (ins srcType:$Rn), 5200 asm, "\t$Rd, $Rn", "", pattern>, 5201 Sched<[WriteFCvt]> { 5202 bits<5> Rd; 5203 bits<5> Rn; 5204 let Inst{30-29} = 0b00; 5205 let Inst{28-24} = 0b11110; 5206 let Inst{23-22} = type; 5207 let Inst{21} = 1; 5208 let Inst{20-19} = rmode; 5209 let Inst{18-16} = opcode; 5210 let Inst{15-10} = 0; 5211 let Inst{9-5} = Rn; 5212 let Inst{4-0} = Rd; 5213} 5214 5215let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5216class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 5217 RegisterClass srcType, RegisterClass dstType, 5218 Operand immType, string asm, list<dag> pattern> 5219 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 5220 asm, "\t$Rd, $Rn, $scale", "", pattern>, 5221 Sched<[WriteFCvt]> { 5222 bits<5> Rd; 5223 bits<5> Rn; 5224 bits<6> scale; 5225 let Inst{30-29} = 0b00; 5226 let Inst{28-24} = 0b11110; 5227 let Inst{23-22} = type; 5228 let Inst{21} = 0; 5229 let Inst{20-19} = rmode; 5230 let Inst{18-16} = opcode; 5231 let Inst{15-10} = scale; 5232 let Inst{9-5} = Rn; 5233 let Inst{4-0} = Rd; 5234} 5235 5236multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 5237 SDPatternOperator OpN> { 5238 // Unscaled half-precision to 32-bit 5239 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 5240 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 5241 let Inst{31} = 0; // 32-bit GPR flag 5242 let Predicates = [HasFullFP16]; 5243 } 5244 5245 // Unscaled half-precision to 64-bit 5246 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 5247 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 5248 let Inst{31} = 1; // 64-bit GPR flag 5249 let Predicates = [HasFullFP16]; 5250 } 5251 5252 // Unscaled single-precision to 32-bit 5253 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 5254 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 5255 let Inst{31} = 0; // 32-bit GPR flag 5256 } 5257 5258 // Unscaled single-precision to 64-bit 5259 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 5260 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 5261 let Inst{31} = 1; // 64-bit GPR flag 5262 } 5263 5264 // Unscaled double-precision to 32-bit 5265 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 5266 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 5267 let Inst{31} = 0; // 32-bit GPR flag 5268 } 5269 5270 // Unscaled double-precision to 64-bit 5271 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 5272 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 5273 let Inst{31} = 1; // 64-bit GPR flag 5274 } 5275} 5276 5277multiclass FPToIntegerSIMDScalar<bits<2> rmode, bits<3> opcode, string asm> { 5278 // double-precision to 32-bit SIMD/FPR 5279 def SDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, FPR32, asm, 5280 []> { 5281 let Inst{31} = 0; // 32-bit FPR flag 5282 } 5283 5284 // half-precision to 32-bit SIMD/FPR 5285 def SHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, FPR32, asm, 5286 []> { 5287 let Inst{31} = 0; // 32-bit FPR flag 5288 } 5289 5290 // half-precision to 64-bit SIMD/FPR 5291 def DHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, FPR64, asm, 5292 []> { 5293 let Inst{31} = 1; // 64-bit FPR flag 5294 } 5295 5296 // single-precision to 64-bit SIMD/FPR 5297 def DSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, FPR64, asm, 5298 []> { 5299 let Inst{31} = 1; // 64-bit FPR flag 5300 } 5301} 5302 5303multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 5304 SDPatternOperator OpN> { 5305 // Scaled half-precision to 32-bit 5306 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 5307 fixedpoint_f16_i32, asm, 5308 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 5309 fixedpoint_f16_i32:$scale)))]> { 5310 let Inst{31} = 0; // 32-bit GPR flag 5311 let scale{5} = 1; 5312 let Predicates = [HasFullFP16]; 5313 } 5314 5315 // Scaled half-precision to 64-bit 5316 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 5317 fixedpoint_f16_i64, asm, 5318 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 5319 fixedpoint_f16_i64:$scale)))]> { 5320 let Inst{31} = 1; // 64-bit GPR flag 5321 let Predicates = [HasFullFP16]; 5322 } 5323 5324 // Scaled single-precision to 32-bit 5325 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 5326 fixedpoint_f32_i32, asm, 5327 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 5328 fixedpoint_f32_i32:$scale)))]> { 5329 let Inst{31} = 0; // 32-bit GPR flag 5330 let scale{5} = 1; 5331 } 5332 5333 // Scaled single-precision to 64-bit 5334 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 5335 fixedpoint_f32_i64, asm, 5336 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 5337 fixedpoint_f32_i64:$scale)))]> { 5338 let Inst{31} = 1; // 64-bit GPR flag 5339 } 5340 5341 // Scaled double-precision to 32-bit 5342 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 5343 fixedpoint_f64_i32, asm, 5344 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 5345 fixedpoint_f64_i32:$scale)))]> { 5346 let Inst{31} = 0; // 32-bit GPR flag 5347 let scale{5} = 1; 5348 } 5349 5350 // Scaled double-precision to 64-bit 5351 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 5352 fixedpoint_f64_i64, asm, 5353 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 5354 fixedpoint_f64_i64:$scale)))]> { 5355 let Inst{31} = 1; // 64-bit GPR flag 5356 } 5357} 5358 5359//--- 5360// Integer to floating point conversion 5361//--- 5362 5363let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5364class BaseIntegerToFP<bits<2> rmode, bits<3> opcode, 5365 RegisterClass srcType, RegisterClass dstType, 5366 Operand immType, string asm, list<dag> pattern> 5367 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 5368 asm, "\t$Rd, $Rn, $scale", "", pattern>, 5369 Sched<[WriteFCvt]> { 5370 bits<5> Rd; 5371 bits<5> Rn; 5372 bits<6> scale; 5373 let Inst{30-24} = 0b0011110; 5374 let Inst{21} = 0b0; 5375 let Inst{20-19} = rmode; 5376 let Inst{18-16} = opcode; 5377 let Inst{15-10} = scale; 5378 let Inst{9-5} = Rn; 5379 let Inst{4-0} = Rd; 5380} 5381 5382let mayRaiseFPException = 1, Uses = [FPCR] in 5383class BaseIntegerToFPUnscaled<bits<2> rmode, bits<3> opcode, 5384 RegisterClass srcType, RegisterClass dstType, 5385 ValueType dvt, string asm, SDPatternOperator node> 5386 : I<(outs dstType:$Rd), (ins srcType:$Rn), 5387 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 5388 Sched<[WriteFCvt]> { 5389 bits<5> Rd; 5390 bits<5> Rn; 5391 bits<6> scale; 5392 let Inst{30-24} = 0b0011110; 5393 let Inst{21} = 0b1; 5394 let Inst{20-19} = rmode; 5395 let Inst{18-16} = opcode; 5396 let Inst{15-10} = 0b000000; 5397 let Inst{9-5} = Rn; 5398 let Inst{4-0} = Rd; 5399} 5400 5401multiclass IntegerToFP<bits<2> rmode, bits<3> opcode, string asm, SDPatternOperator node> { 5402 // Unscaled 5403 def UWHri: BaseIntegerToFPUnscaled<rmode, opcode, GPR32, FPR16, f16, asm, node> { 5404 let Inst{31} = 0; // 32-bit GPR flag 5405 let Inst{23-22} = 0b11; // 16-bit FPR flag 5406 let Predicates = [HasFullFP16]; 5407 } 5408 5409 def UWSri: BaseIntegerToFPUnscaled<rmode, opcode, GPR32, FPR32, f32, asm, node> { 5410 let Inst{31} = 0; // 32-bit GPR flag 5411 let Inst{23-22} = 0b00; // 32-bit FPR flag 5412 } 5413 5414 def UWDri: BaseIntegerToFPUnscaled<rmode, opcode, GPR32, FPR64, f64, asm, node> { 5415 let Inst{31} = 0; // 32-bit GPR flag 5416 let Inst{23-22} = 0b01; // 64-bit FPR flag 5417 } 5418 5419 def UXHri: BaseIntegerToFPUnscaled<rmode, opcode, GPR64, FPR16, f16, asm, node> { 5420 let Inst{31} = 1; // 64-bit GPR flag 5421 let Inst{23-22} = 0b11; // 16-bit FPR flag 5422 let Predicates = [HasFullFP16]; 5423 } 5424 5425 def UXSri: BaseIntegerToFPUnscaled<rmode, opcode, GPR64, FPR32, f32, asm, node> { 5426 let Inst{31} = 1; // 64-bit GPR flag 5427 let Inst{23-22} = 0b00; // 32-bit FPR flag 5428 } 5429 5430 def UXDri: BaseIntegerToFPUnscaled<rmode, opcode, GPR64, FPR64, f64, asm, node> { 5431 let Inst{31} = 1; // 64-bit GPR flag 5432 let Inst{23-22} = 0b01; // 64-bit FPR flag 5433 } 5434 5435 // Scaled 5436 def SWHri: BaseIntegerToFP<rmode, opcode, GPR32, FPR16, fixedpoint_recip_f16_i32, asm, 5437 [(set (f16 FPR16:$Rd), 5438 (fmul (node GPR32:$Rn), 5439 fixedpoint_recip_f16_i32:$scale))]> { 5440 let Inst{31} = 0; // 32-bit GPR flag 5441 let Inst{23-22} = 0b11; // 16-bit FPR flag 5442 let scale{5} = 1; 5443 let Predicates = [HasFullFP16]; 5444 } 5445 5446 def SWSri: BaseIntegerToFP<rmode, opcode, GPR32, FPR32, fixedpoint_recip_f32_i32, asm, 5447 [(set FPR32:$Rd, 5448 (fmul (node GPR32:$Rn), 5449 fixedpoint_recip_f32_i32:$scale))]> { 5450 let Inst{31} = 0; // 32-bit GPR flag 5451 let Inst{23-22} = 0b00; // 32-bit FPR flag 5452 let scale{5} = 1; 5453 } 5454 5455 def SWDri: BaseIntegerToFP<rmode, opcode, GPR32, FPR64, fixedpoint_recip_f64_i32, asm, 5456 [(set FPR64:$Rd, 5457 (fmul (node GPR32:$Rn), 5458 fixedpoint_recip_f64_i32:$scale))]> { 5459 let Inst{31} = 0; // 32-bit GPR flag 5460 let Inst{23-22} = 0b01; // 64-bit FPR flag 5461 let scale{5} = 1; 5462 } 5463 5464 def SXHri: BaseIntegerToFP<rmode, opcode, GPR64, FPR16, fixedpoint_recip_f16_i64, asm, 5465 [(set (f16 FPR16:$Rd), 5466 (fmul (node GPR64:$Rn), 5467 fixedpoint_recip_f16_i64:$scale))]> { 5468 let Inst{31} = 1; // 64-bit GPR flag 5469 let Inst{23-22} = 0b11; // 16-bit FPR flag 5470 let Predicates = [HasFullFP16]; 5471 } 5472 5473 def SXSri: BaseIntegerToFP<rmode, opcode, GPR64, FPR32, fixedpoint_recip_f32_i64, asm, 5474 [(set FPR32:$Rd, 5475 (fmul (node GPR64:$Rn), 5476 fixedpoint_recip_f32_i64:$scale))]> { 5477 let Inst{31} = 1; // 64-bit GPR flag 5478 let Inst{23-22} = 0b00; // 32-bit FPR flag 5479 } 5480 5481 def SXDri: BaseIntegerToFP<rmode, opcode, GPR64, FPR64, fixedpoint_recip_f64_i64, asm, 5482 [(set FPR64:$Rd, 5483 (fmul (node GPR64:$Rn), 5484 fixedpoint_recip_f64_i64:$scale))]> { 5485 let Inst{31} = 1; // 64-bit GPR flag 5486 let Inst{23-22} = 0b01; // 64-bit FPR flag 5487 } 5488} 5489 5490multiclass IntegerToFPSIMDScalar<bits<2> rmode, bits<3> opcode, string asm, SDPatternOperator node = null_frag> { 5491 // 32-bit to half-precision 5492 def HSr: BaseIntegerToFPUnscaled<rmode, opcode, FPR32, FPR16, f16, asm, node> { 5493 let Inst{31} = 0; // 32-bit FPR flag 5494 let Inst{23-22} = 0b11; // 16-bit FPR flag 5495 } 5496 5497 // 32-bit to double-precision 5498 def DSr: BaseIntegerToFPUnscaled<rmode, opcode, FPR32, FPR64, f64, asm, node> { 5499 let Inst{31} = 0; // 32-bit FPR flag 5500 let Inst{23-22} = 0b01; // 64-bit FPR flag 5501 } 5502 5503 // 64-bit to half-precision 5504 def HDr: BaseIntegerToFPUnscaled<rmode, opcode, FPR64, FPR16, f16, asm, node> { 5505 let Inst{31} = 1; // 64-bit FPR flag 5506 let Inst{23-22} = 0b11; // 16-bit FPR flag 5507 } 5508 5509 // 64-bit to single-precision 5510 def SDr: BaseIntegerToFPUnscaled<rmode, opcode, FPR64, FPR32, f32, asm, node> { 5511 let Inst{31} = 1; // 64-bit FPR flag 5512 let Inst{23-22} = 0b00; // 32-bit FPR flag 5513 } 5514} 5515 5516//--- 5517// Unscaled integer <-> floating point conversion (i.e. FMOV) 5518//--- 5519 5520let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5521class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 5522 RegisterClass srcType, RegisterClass dstType, 5523 string asm> 5524 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 5525 // We use COPY_TO_REGCLASS for these bitconvert operations. 5526 // copyPhysReg() expands the resultant COPY instructions after 5527 // regalloc is done. This gives greater freedom for the allocator 5528 // and related passes (coalescing, copy propagation, et. al.) to 5529 // be more effective. 5530 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 5531 Sched<[WriteFCopy]> { 5532 bits<5> Rd; 5533 bits<5> Rn; 5534 let Inst{30-24} = 0b0011110; 5535 let Inst{21} = 1; 5536 let Inst{20-19} = rmode; 5537 let Inst{18-16} = opcode; 5538 let Inst{15-10} = 0b000000; 5539 let Inst{9-5} = Rn; 5540 let Inst{4-0} = Rd; 5541} 5542 5543let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5544class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 5545 RegisterClass srcType, RegisterOperand dstType, string asm, 5546 string kind> 5547 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5548 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 5549 Sched<[WriteFCopy]> { 5550 bits<5> Rd; 5551 bits<5> Rn; 5552 let Inst{30-23} = 0b00111101; 5553 let Inst{21} = 1; 5554 let Inst{20-19} = rmode; 5555 let Inst{18-16} = opcode; 5556 let Inst{15-10} = 0b000000; 5557 let Inst{9-5} = Rn; 5558 let Inst{4-0} = Rd; 5559 5560 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5561} 5562 5563let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5564class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 5565 RegisterOperand srcType, RegisterClass dstType, string asm, 5566 string kind> 5567 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5568 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 5569 Sched<[WriteFCopy]> { 5570 bits<5> Rd; 5571 bits<5> Rn; 5572 let Inst{30-23} = 0b00111101; 5573 let Inst{21} = 1; 5574 let Inst{20-19} = rmode; 5575 let Inst{18-16} = opcode; 5576 let Inst{15-10} = 0b000000; 5577 let Inst{9-5} = Rn; 5578 let Inst{4-0} = Rd; 5579 5580 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5581} 5582 5583 5584multiclass UnscaledConversion<string asm> { 5585 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 5586 let Inst{31} = 0; // 32-bit GPR flag 5587 let Inst{23-22} = 0b11; // 16-bit FPR flag 5588 let Predicates = [HasFullFP16]; 5589 } 5590 5591 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 5592 let Inst{31} = 1; // 64-bit GPR flag 5593 let Inst{23-22} = 0b11; // 16-bit FPR flag 5594 let Predicates = [HasFullFP16]; 5595 } 5596 5597 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 5598 let Inst{31} = 0; // 32-bit GPR flag 5599 let Inst{23-22} = 0b00; // 32-bit FPR flag 5600 } 5601 5602 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 5603 let Inst{31} = 1; // 64-bit GPR flag 5604 let Inst{23-22} = 0b01; // 64-bit FPR flag 5605 } 5606 5607 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 5608 let Inst{31} = 0; // 32-bit GPR flag 5609 let Inst{23-22} = 0b11; // 16-bit FPR flag 5610 let Predicates = [HasFullFP16]; 5611 } 5612 5613 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 5614 let Inst{31} = 1; // 64-bit GPR flag 5615 let Inst{23-22} = 0b11; // 16-bit FPR flag 5616 let Predicates = [HasFullFP16]; 5617 } 5618 5619 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 5620 let Inst{31} = 0; // 32-bit GPR flag 5621 let Inst{23-22} = 0b00; // 32-bit FPR flag 5622 } 5623 5624 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 5625 let Inst{31} = 1; // 64-bit GPR flag 5626 let Inst{23-22} = 0b01; // 64-bit FPR flag 5627 } 5628 5629 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 5630 asm, ".d"> { 5631 let Inst{31} = 1; 5632 let Inst{22} = 0; 5633 } 5634 5635 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 5636 asm, ".d"> { 5637 let Inst{31} = 1; 5638 let Inst{22} = 0; 5639 } 5640} 5641 5642//--- 5643// Floating point conversion 5644//--- 5645 5646let mayRaiseFPException = 1, Uses = [FPCR] in 5647class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 5648 RegisterClass srcType, string asm, list<dag> pattern> 5649 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 5650 Sched<[WriteFCvt]> { 5651 bits<5> Rd; 5652 bits<5> Rn; 5653 let Inst{31-24} = 0b00011110; 5654 let Inst{23-22} = type; 5655 let Inst{21-17} = 0b10001; 5656 let Inst{16-15} = opcode; 5657 let Inst{14-10} = 0b10000; 5658 let Inst{9-5} = Rn; 5659 let Inst{4-0} = Rd; 5660} 5661 5662multiclass FPConversion<string asm> { 5663 // Double-precision to Half-precision 5664 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 5665 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 5666 5667 // Double-precision to Single-precision 5668 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 5669 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5670 5671 // Half-precision to Double-precision 5672 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5673 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5674 5675 // Half-precision to Single-precision 5676 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5677 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5678 5679 // Single-precision to Double-precision 5680 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5681 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5682 5683 // Single-precision to Half-precision 5684 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5685 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5686} 5687 5688//--- 5689// Single operand floating point data processing 5690//--- 5691 5692let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5693class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5694 ValueType vt, string asm, SDPatternOperator node> 5695 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5696 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5697 Sched<[WriteF]> { 5698 bits<5> Rd; 5699 bits<5> Rn; 5700 let Inst{31-24} = 0b00011110; 5701 let Inst{21} = 0b1; 5702 let Inst{20-15} = opcode; 5703 let Inst{14-10} = 0b10000; 5704 let Inst{9-5} = Rn; 5705 let Inst{4-0} = Rd; 5706} 5707 5708multiclass SingleOperandFPData<bits<4> opcode, string asm, 5709 SDPatternOperator node = null_frag, 5710 int fpexceptions = 1> { 5711 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 5712 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5713 let Inst{23-22} = 0b11; // 16-bit size flag 5714 let Predicates = [HasFullFP16]; 5715 } 5716 5717 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5718 let Inst{23-22} = 0b00; // 32-bit size flag 5719 } 5720 5721 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5722 let Inst{23-22} = 0b01; // 64-bit size flag 5723 } 5724 } 5725} 5726 5727multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5728 SDPatternOperator node = null_frag> 5729 : SingleOperandFPData<opcode, asm, node, 0>; 5730 5731let mayRaiseFPException = 1, Uses = [FPCR] in 5732multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5733 SDPatternOperator node = null_frag>{ 5734 5735 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5736 let Inst{23-22} = 0b00; // 32-bit registers 5737 } 5738 5739 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5740 let Inst{23-22} = 0b01; // 64-bit registers 5741 } 5742} 5743 5744// FRInt[32|64][Z|N] instructions 5745multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5746 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5747 5748//--- 5749// Two operand floating point data processing 5750//--- 5751 5752let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5753class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5754 string asm, list<dag> pat> 5755 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5756 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5757 Sched<[WriteF]> { 5758 bits<5> Rd; 5759 bits<5> Rn; 5760 bits<5> Rm; 5761 let Inst{31-24} = 0b00011110; 5762 let Inst{21} = 1; 5763 let Inst{20-16} = Rm; 5764 let Inst{15-12} = opcode; 5765 let Inst{11-10} = 0b10; 5766 let Inst{9-5} = Rn; 5767 let Inst{4-0} = Rd; 5768} 5769 5770multiclass TwoOperandFPData<bits<4> opcode, string asm, 5771 SDPatternOperator node = null_frag> { 5772 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5773 [(set (f16 FPR16:$Rd), 5774 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5775 let Inst{23-22} = 0b11; // 16-bit size flag 5776 let Predicates = [HasFullFP16]; 5777 } 5778 5779 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5780 [(set (f32 FPR32:$Rd), 5781 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5782 let Inst{23-22} = 0b00; // 32-bit size flag 5783 } 5784 5785 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5786 [(set (f64 FPR64:$Rd), 5787 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5788 let Inst{23-22} = 0b01; // 64-bit size flag 5789 } 5790} 5791 5792multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5793 SDPatternOperator node> { 5794 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5795 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5796 let Inst{23-22} = 0b11; // 16-bit size flag 5797 let Predicates = [HasFullFP16]; 5798 } 5799 5800 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5801 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5802 let Inst{23-22} = 0b00; // 32-bit size flag 5803 } 5804 5805 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5806 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5807 let Inst{23-22} = 0b01; // 64-bit size flag 5808 } 5809} 5810 5811 5812//--- 5813// Three operand floating point data processing 5814//--- 5815 5816let mayRaiseFPException = 1, Uses = [FPCR] in 5817class BaseThreeOperandFPData<bit isNegated, bit isSub, 5818 RegisterClass regtype, string asm, list<dag> pat> 5819 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5820 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5821 Sched<[WriteFMul]> { 5822 bits<5> Rd; 5823 bits<5> Rn; 5824 bits<5> Rm; 5825 bits<5> Ra; 5826 let Inst{31-24} = 0b00011111; 5827 let Inst{21} = isNegated; 5828 let Inst{20-16} = Rm; 5829 let Inst{15} = isSub; 5830 let Inst{14-10} = Ra; 5831 let Inst{9-5} = Rn; 5832 let Inst{4-0} = Rd; 5833} 5834 5835multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5836 SDPatternOperator node> { 5837 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5838 [(set (f16 FPR16:$Rd), 5839 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5840 let Inst{23-22} = 0b11; // 16-bit size flag 5841 let Predicates = [HasFullFP16]; 5842 } 5843 5844 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5845 [(set FPR32:$Rd, 5846 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5847 let Inst{23-22} = 0b00; // 32-bit size flag 5848 } 5849 5850 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5851 [(set FPR64:$Rd, 5852 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5853 let Inst{23-22} = 0b01; // 64-bit size flag 5854 } 5855 5856 let Predicates = [HasFullFP16] in { 5857 def : Pat<(f16 (node (f16 FPR16:$Rn), 5858 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))), 5859 (f16 FPR16:$Ra))), 5860 (!cast<Instruction>(NAME # Hrrr) 5861 FPR16:$Rn, (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>; 5862 5863 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))), 5864 (f16 FPR16:$Rm), 5865 (f16 FPR16:$Ra))), 5866 (!cast<Instruction>(NAME # Hrrr) 5867 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>; 5868 5869 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))), 5870 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))), 5871 (f16 FPR16:$Ra))), 5872 (!cast<Instruction>(NAME # Hrrr) 5873 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), 5874 (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>; 5875 } 5876 5877 def : Pat<(f32 (node (f32 FPR32:$Rn), 5878 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))), 5879 (f32 FPR32:$Ra))), 5880 (!cast<Instruction>(NAME # Srrr) 5881 FPR32:$Rn, (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>; 5882 5883 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))), 5884 (f32 FPR32:$Rm), 5885 (f32 FPR32:$Ra))), 5886 (!cast<Instruction>(NAME # Srrr) 5887 (EXTRACT_SUBREG V128:$Rn, ssub), FPR32:$Rm, FPR32:$Ra)>; 5888 5889 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))), 5890 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))), 5891 (f32 FPR32:$Ra))), 5892 (!cast<Instruction>(NAME # Srrr) 5893 (EXTRACT_SUBREG V128:$Rn, ssub), 5894 (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>; 5895 5896 def : Pat<(f64 (node (f64 FPR64:$Rn), 5897 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))), 5898 (f64 FPR64:$Ra))), 5899 (!cast<Instruction>(NAME # Drrr) 5900 FPR64:$Rn, (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>; 5901 5902 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))), 5903 (f64 FPR64:$Rm), 5904 (f64 FPR64:$Ra))), 5905 (!cast<Instruction>(NAME # Drrr) 5906 (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>; 5907 5908 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))), 5909 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))), 5910 (f64 FPR64:$Ra))), 5911 (!cast<Instruction>(NAME # Drrr) 5912 (EXTRACT_SUBREG V128:$Rn, dsub), 5913 (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>; 5914} 5915 5916//--- 5917// Floating point data comparisons 5918//--- 5919 5920let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5921class BaseOneOperandFPComparison<bit signalAllNans, 5922 RegisterClass regtype, string asm, 5923 list<dag> pat> 5924 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5925 Sched<[WriteFCmp]> { 5926 bits<5> Rn; 5927 let Inst{31-24} = 0b00011110; 5928 let Inst{21} = 1; 5929 5930 let Inst{15-10} = 0b001000; 5931 let Inst{9-5} = Rn; 5932 let Inst{4} = signalAllNans; 5933 let Inst{3-0} = 0b1000; 5934 5935 // Rm should be 0b00000 canonically, but we need to accept any value. 5936 let PostEncoderMethod = "fixOneOperandFPComparison"; 5937} 5938 5939let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5940class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5941 string asm, list<dag> pat> 5942 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5943 Sched<[WriteFCmp]> { 5944 bits<5> Rm; 5945 bits<5> Rn; 5946 let Inst{31-24} = 0b00011110; 5947 let Inst{21} = 1; 5948 let Inst{20-16} = Rm; 5949 let Inst{15-10} = 0b001000; 5950 let Inst{9-5} = Rn; 5951 let Inst{4} = signalAllNans; 5952 let Inst{3-0} = 0b0000; 5953} 5954 5955multiclass FPComparison<bit signalAllNans, string asm, 5956 SDPatternOperator OpNode = null_frag> { 5957 let Defs = [NZCV] in { 5958 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5959 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5960 let Inst{23-22} = 0b11; 5961 let Predicates = [HasFullFP16]; 5962 } 5963 5964 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5965 [(set NZCV, (OpNode (f16 FPR16:$Rn), fpimm0))]> { 5966 let Inst{23-22} = 0b11; 5967 let Predicates = [HasFullFP16]; 5968 } 5969 5970 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5971 [(set NZCV, (OpNode FPR32:$Rn, (f32 FPR32:$Rm)))]> { 5972 let Inst{23-22} = 0b00; 5973 } 5974 5975 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5976 [(set NZCV, (OpNode (f32 FPR32:$Rn), fpimm0))]> { 5977 let Inst{23-22} = 0b00; 5978 } 5979 5980 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5981 [(set NZCV, (OpNode FPR64:$Rn, (f64 FPR64:$Rm)))]> { 5982 let Inst{23-22} = 0b01; 5983 } 5984 5985 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5986 [(set NZCV, (OpNode (f64 FPR64:$Rn), fpimm0))]> { 5987 let Inst{23-22} = 0b01; 5988 } 5989 } // Defs = [NZCV] 5990} 5991 5992//--- 5993// Floating point conditional comparisons 5994//--- 5995 5996let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5997class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5998 string mnemonic, list<dag> pat> 5999 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 6000 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 6001 Sched<[WriteFCmp]> { 6002 let Uses = [NZCV]; 6003 let Defs = [NZCV]; 6004 6005 bits<5> Rn; 6006 bits<5> Rm; 6007 bits<4> nzcv; 6008 bits<4> cond; 6009 6010 let Inst{31-24} = 0b00011110; 6011 let Inst{21} = 1; 6012 let Inst{20-16} = Rm; 6013 let Inst{15-12} = cond; 6014 let Inst{11-10} = 0b01; 6015 let Inst{9-5} = Rn; 6016 let Inst{4} = signalAllNans; 6017 let Inst{3-0} = nzcv; 6018} 6019 6020multiclass FPCondComparison<bit signalAllNans, string mnemonic, 6021 SDPatternOperator OpNode = null_frag> { 6022 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 6023 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 6024 (i32 imm:$cond), NZCV))]> { 6025 let Inst{23-22} = 0b11; 6026 let Predicates = [HasFullFP16]; 6027 } 6028 6029 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 6030 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 6031 (i32 imm:$cond), NZCV))]> { 6032 let Inst{23-22} = 0b00; 6033 } 6034 6035 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 6036 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 6037 (i32 imm:$cond), NZCV))]> { 6038 let Inst{23-22} = 0b01; 6039 } 6040} 6041 6042//--- 6043// Floating point conditional select 6044//--- 6045 6046class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 6047 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 6048 asm, "\t$Rd, $Rn, $Rm, $cond", "", 6049 [(set regtype:$Rd, 6050 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 6051 (i32 imm:$cond), NZCV))]>, 6052 Sched<[WriteF]> { 6053 bits<5> Rd; 6054 bits<5> Rn; 6055 bits<5> Rm; 6056 bits<4> cond; 6057 6058 let Inst{31-24} = 0b00011110; 6059 let Inst{21} = 1; 6060 let Inst{20-16} = Rm; 6061 let Inst{15-12} = cond; 6062 let Inst{11-10} = 0b11; 6063 let Inst{9-5} = Rn; 6064 let Inst{4-0} = Rd; 6065} 6066 6067multiclass FPCondSelect<string asm> { 6068 let Uses = [NZCV] in { 6069 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 6070 let Inst{23-22} = 0b11; 6071 let Predicates = [HasFullFP16]; 6072 } 6073 6074 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 6075 let Inst{23-22} = 0b00; 6076 } 6077 6078 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 6079 let Inst{23-22} = 0b01; 6080 } 6081 } // Uses = [NZCV] 6082} 6083 6084//--- 6085// Floating move immediate 6086//--- 6087 6088class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 6089 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 6090 [(set regtype:$Rd, fpimmtype:$imm)]>, 6091 Sched<[WriteFImm]> { 6092 bits<5> Rd; 6093 bits<8> imm; 6094 let Inst{31-24} = 0b00011110; 6095 let Inst{21} = 1; 6096 let Inst{20-13} = imm; 6097 let Inst{12-5} = 0b10000000; 6098 let Inst{4-0} = Rd; 6099} 6100 6101multiclass FPMoveImmediate<string asm> { 6102 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 6103 let Inst{23-22} = 0b11; 6104 let Predicates = [HasFullFP16]; 6105 } 6106 6107 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 6108 let Inst{23-22} = 0b00; 6109 } 6110 6111 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 6112 let Inst{23-22} = 0b01; 6113 } 6114} 6115} // end of 'let Predicates = [HasFPARMv8]' 6116 6117//---------------------------------------------------------------------------- 6118// AdvSIMD 6119//---------------------------------------------------------------------------- 6120 6121let Predicates = [HasNEON] in { 6122 6123//---------------------------------------------------------------------------- 6124// AdvSIMD three register vector instructions 6125//---------------------------------------------------------------------------- 6126 6127let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6128class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 6129 RegisterOperand regtype, string asm, string kind, 6130 list<dag> pattern> 6131 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6132 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6133 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 6134 Sched<[!if(Q, WriteVq, WriteVd)]> { 6135 bits<5> Rd; 6136 bits<5> Rn; 6137 bits<5> Rm; 6138 let Inst{31} = 0; 6139 let Inst{30} = Q; 6140 let Inst{29} = U; 6141 let Inst{28-24} = 0b01110; 6142 let Inst{23-21} = size; 6143 let Inst{20-16} = Rm; 6144 let Inst{15-11} = opcode; 6145 let Inst{10} = 1; 6146 let Inst{9-5} = Rn; 6147 let Inst{4-0} = Rd; 6148} 6149 6150let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6151class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 6152 RegisterOperand regtype, string asm, string kind, 6153 list<dag> pattern> 6154 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 6155 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6156 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6157 Sched<[!if(Q, WriteVq, WriteVd)]> { 6158 bits<5> Rd; 6159 bits<5> Rn; 6160 bits<5> Rm; 6161 let Inst{31} = 0; 6162 let Inst{30} = Q; 6163 let Inst{29} = U; 6164 let Inst{28-24} = 0b01110; 6165 let Inst{23-21} = size; 6166 let Inst{20-16} = Rm; 6167 let Inst{15-11} = opcode; 6168 let Inst{10} = 1; 6169 let Inst{9-5} = Rn; 6170 let Inst{4-0} = Rd; 6171} 6172 6173let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6174class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 6175 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 6176 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 6177 6178multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 6179 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 6180 [(set (v8i8 V64:$dst), 6181 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6182 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 6183 [(set (v16i8 V128:$dst), 6184 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 6185 (v16i8 V128:$Rm)))]>; 6186 6187 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 6188 (v4i16 V64:$RHS))), 6189 (!cast<Instruction>(NAME#"v8i8") 6190 V64:$LHS, V64:$MHS, V64:$RHS)>; 6191 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 6192 (v2i32 V64:$RHS))), 6193 (!cast<Instruction>(NAME#"v8i8") 6194 V64:$LHS, V64:$MHS, V64:$RHS)>; 6195 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 6196 (v1i64 V64:$RHS))), 6197 (!cast<Instruction>(NAME#"v8i8") 6198 V64:$LHS, V64:$MHS, V64:$RHS)>; 6199 6200 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 6201 (v8i16 V128:$RHS))), 6202 (!cast<Instruction>(NAME#"v16i8") 6203 V128:$LHS, V128:$MHS, V128:$RHS)>; 6204 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 6205 (v4i32 V128:$RHS))), 6206 (!cast<Instruction>(NAME#"v16i8") 6207 V128:$LHS, V128:$MHS, V128:$RHS)>; 6208 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 6209 (v2i64 V128:$RHS))), 6210 (!cast<Instruction>(NAME#"v16i8") 6211 V128:$LHS, V128:$MHS, V128:$RHS)>; 6212} 6213 6214// All operand sizes distinguished in the encoding. 6215multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 6216 SDPatternOperator OpNode> { 6217 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 6218 asm, ".8b", 6219 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6220 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 6221 asm, ".16b", 6222 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 6223 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 6224 asm, ".4h", 6225 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6226 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 6227 asm, ".8h", 6228 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6229 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 6230 asm, ".2s", 6231 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6232 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 6233 asm, ".4s", 6234 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6235 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 6236 asm, ".2d", 6237 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6238} 6239 6240multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 6241 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 6242 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 6243 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 6244 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 6245 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 6246 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 6247 6248 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 6249 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 6250 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 6251 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 6252 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 6253 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 6254 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 6255 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 6256} 6257 6258// As above, but D sized elements unsupported. 6259multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 6260 SDPatternOperator OpNode> { 6261 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 6262 asm, ".8b", 6263 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 6264 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 6265 asm, ".16b", 6266 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 6267 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 6268 asm, ".4h", 6269 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 6270 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 6271 asm, ".8h", 6272 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 6273 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 6274 asm, ".2s", 6275 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 6276 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 6277 asm, ".4s", 6278 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 6279} 6280 6281multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 6282 SDPatternOperator OpNode> { 6283 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 6284 asm, ".8b", 6285 [(set (v8i8 V64:$dst), 6286 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6287 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 6288 asm, ".16b", 6289 [(set (v16i8 V128:$dst), 6290 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 6291 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 6292 asm, ".4h", 6293 [(set (v4i16 V64:$dst), 6294 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6295 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 6296 asm, ".8h", 6297 [(set (v8i16 V128:$dst), 6298 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6299 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 6300 asm, ".2s", 6301 [(set (v2i32 V64:$dst), 6302 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6303 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 6304 asm, ".4s", 6305 [(set (v4i32 V128:$dst), 6306 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6307} 6308 6309// As above, but only B sized elements supported. 6310multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 6311 SDPatternOperator OpNode> { 6312 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 6313 asm, ".8b", 6314 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6315 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 6316 asm, ".16b", 6317 [(set (v16i8 V128:$Rd), 6318 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 6319} 6320 6321// As above, but only floating point elements supported. 6322let mayRaiseFPException = 1, Uses = [FPCR] in 6323multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 6324 string asm, SDPatternOperator OpNode> { 6325 let Predicates = [HasNEON, HasFullFP16] in { 6326 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 6327 asm, ".4h", 6328 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 6329 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 6330 asm, ".8h", 6331 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 6332 } // Predicates = [HasNEON, HasFullFP16] 6333 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 6334 asm, ".2s", 6335 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6336 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 6337 asm, ".4s", 6338 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6339 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 6340 asm, ".2d", 6341 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6342} 6343 6344let mayRaiseFPException = 1, Uses = [FPCR] in 6345multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 6346 string asm, 6347 SDPatternOperator OpNode> { 6348 let Predicates = [HasNEON, HasFullFP16] in { 6349 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 6350 asm, ".4h", 6351 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 6352 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 6353 asm, ".8h", 6354 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 6355 } // Predicates = [HasNEON, HasFullFP16] 6356 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 6357 asm, ".2s", 6358 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6359 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 6360 asm, ".4s", 6361 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6362 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 6363 asm, ".2d", 6364 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6365} 6366 6367let mayRaiseFPException = 1, Uses = [FPCR] in 6368multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 6369 string asm, SDPatternOperator OpNode> { 6370 let Predicates = [HasNEON, HasFullFP16] in { 6371 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 6372 asm, ".4h", 6373 [(set (v4f16 V64:$dst), 6374 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 6375 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 6376 asm, ".8h", 6377 [(set (v8f16 V128:$dst), 6378 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 6379 } // Predicates = [HasNEON, HasFullFP16] 6380 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 6381 asm, ".2s", 6382 [(set (v2f32 V64:$dst), 6383 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6384 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 6385 asm, ".4s", 6386 [(set (v4f32 V128:$dst), 6387 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6388 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 6389 asm, ".2d", 6390 [(set (v2f64 V128:$dst), 6391 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6392} 6393 6394// As above, but D and B sized elements unsupported. 6395let mayRaiseFPException = 1, Uses = [FPCR] in 6396multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 6397 SDPatternOperator OpNode> { 6398 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 6399 asm, ".4h", 6400 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6401 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 6402 asm, ".8h", 6403 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6404 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 6405 asm, ".2s", 6406 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6407 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 6408 asm, ".4s", 6409 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6410} 6411 6412// Logical three vector ops share opcode bits, and only use B sized elements. 6413multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 6414 SDPatternOperator OpNode = null_frag> { 6415 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 6416 asm, ".8b", 6417 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 6418 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 6419 asm, ".16b", 6420 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 6421 6422 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 6423 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6424 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 6425 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6426 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 6427 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6428 6429 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 6430 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6431 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 6432 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6433 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 6434 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6435} 6436 6437multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 6438 string asm, SDPatternOperator OpNode = null_frag> { 6439 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 6440 asm, ".8b", 6441 [(set (v8i8 V64:$dst), 6442 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6443 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 6444 asm, ".16b", 6445 [(set (v16i8 V128:$dst), 6446 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 6447 (v16i8 V128:$Rm)))]>; 6448 6449 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 6450 (v4i16 V64:$RHS))), 6451 (!cast<Instruction>(NAME#"v8i8") 6452 V64:$LHS, V64:$MHS, V64:$RHS)>; 6453 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 6454 (v2i32 V64:$RHS))), 6455 (!cast<Instruction>(NAME#"v8i8") 6456 V64:$LHS, V64:$MHS, V64:$RHS)>; 6457 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 6458 (v1i64 V64:$RHS))), 6459 (!cast<Instruction>(NAME#"v8i8") 6460 V64:$LHS, V64:$MHS, V64:$RHS)>; 6461 6462 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 6463 (v8i16 V128:$RHS))), 6464 (!cast<Instruction>(NAME#"v16i8") 6465 V128:$LHS, V128:$MHS, V128:$RHS)>; 6466 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 6467 (v4i32 V128:$RHS))), 6468 (!cast<Instruction>(NAME#"v16i8") 6469 V128:$LHS, V128:$MHS, V128:$RHS)>; 6470 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 6471 (v2i64 V128:$RHS))), 6472 (!cast<Instruction>(NAME#"v16i8") 6473 V128:$LHS, V128:$MHS, V128:$RHS)>; 6474} 6475 6476// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 6477// bytes from S-sized elements. 6478class BaseSIMDThreeSameVectorDot<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 6479 string kind1, string kind2, RegisterOperand RegType, 6480 ValueType AccumType, ValueType InputType, 6481 SDPatternOperator OpNode> : 6482 BaseSIMDThreeSameVectorTied<Q, U, {sz, 0b0}, {0b1, opc}, RegType, asm, kind1, 6483 [(set (AccumType RegType:$dst), 6484 (OpNode (AccumType RegType:$Rd), 6485 (InputType RegType:$Rn), 6486 (InputType RegType:$Rm)))]> { 6487 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6488} 6489 6490multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 6491 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, 0b10, {0b001, Mixed}, asm, ".2s", ".8b", V64, 6492 v2i32, v8i8, OpNode>; 6493 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, 0b10, {0b001, Mixed}, asm, ".4s", ".16b", V128, 6494 v4i32, v16i8, OpNode>; 6495} 6496 6497// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 6498// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 6499// 8H to 4S, when Q=1). 6500let mayRaiseFPException = 1, Uses = [FPCR] in 6501class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 6502 string kind2, RegisterOperand RegType, 6503 ValueType AccumType, ValueType InputType, 6504 SDPatternOperator OpNode> : 6505 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 6506 [(set (AccumType RegType:$dst), 6507 (OpNode (AccumType RegType:$Rd), 6508 (InputType RegType:$Rn), 6509 (InputType RegType:$Rm)))]> { 6510 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6511 let Inst{13} = b13; 6512} 6513 6514multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 6515 SDPatternOperator OpNode> { 6516 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 6517 v2f32, v4f16, OpNode>; 6518 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 6519 v4f32, v8f16, OpNode>; 6520} 6521 6522multiclass SIMDThreeSameVectorMLA<bit Q, string asm, SDPatternOperator op> { 6523 6524 def v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b", 6525 V128, v8f16, v16i8, op>; 6526} 6527 6528multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm, SDPatternOperator op> { 6529 def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b", 6530 V128, v4f32, v16i8, op>; 6531} 6532 6533// FP8 assembly/disassembly classes 6534 6535//---------------------------------------------------------------------------- 6536// FP8 Advanced SIMD three-register extension 6537//---------------------------------------------------------------------------- 6538class BaseSIMDThreeVectors<bit Q, bit U, bits<2> size, bits<4> op, 6539 RegisterOperand regtype1, 6540 RegisterOperand regtype2, string asm, 6541 string kind1, string kind2> 6542 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, regtype2:$Rm), asm, 6543 "\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2, "", []>, Sched<[]> { 6544 bits<5> Rd; 6545 bits<5> Rn; 6546 bits<5> Rm; 6547 let Inst{31} = 0; 6548 let Inst{30} = Q; 6549 let Inst{29} = U; 6550 let Inst{28-24} = 0b01110; 6551 let Inst{23-22} = size; 6552 let Inst{21} = 0b0; 6553 let Inst{20-16} = Rm; 6554 let Inst{15} = 0b1; 6555 let Inst{14-11} = op; 6556 let Inst{10} = 0b1; 6557 let Inst{9-5} = Rn; 6558 let Inst{4-0} = Rd; 6559} 6560 6561 6562// FCVTN (FP16 to FP8) 6563multiclass SIMD_FP8_CVTN_F16<string asm, SDPatternOperator Op> { 6564 let Uses = [FPMR, FPCR], mayLoad = 1 in { 6565 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b01, 0b1110, V64, V64, asm, ".8b",".4h">; 6566 def v16f8 : BaseSIMDThreeVectors<0b1, 0b0, 0b01, 0b1110, V128, V128, asm, ".16b", ".8h">; 6567 } 6568 def : Pat<(v8i8 (Op (v4f16 V64:$Rn), (v4f16 V64:$Rm))), 6569 (!cast<Instruction>(NAME # v8f8) V64:$Rn, V64:$Rm)>; 6570 def : Pat<(v16i8 (Op (v8f16 V128:$Rn), (v8f16 V128:$Rm))), 6571 (!cast<Instruction>(NAME # v16f8) V128:$Rn, V128:$Rm)>; 6572} 6573 6574// FCVTN, FCVTN2 (FP32 to FP8) 6575multiclass SIMD_FP8_CVTN_F32<string asm, SDPatternOperator Op> { 6576 let Uses = [FPMR, FPCR], mayLoad = 1 in { 6577 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b00, 0b1110, V64, V128, asm, ".8b", ".4s">; 6578 def 2v16f8 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1110, asm#2, ".16b", ".4s", 6579 V128, v16i8, v4f32, null_frag>; 6580 } 6581 6582 def : Pat<(v8i8 (Op (v4f32 V128:$Rn), (v4f32 V128:$Rm))), 6583 (!cast<Instruction>(NAME # v8f8) V128:$Rn, V128:$Rm)>; 6584 6585 def : Pat<(v16i8 (!cast<SDPatternOperator>(Op # 2) (v16i8 V128:$_Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm))), 6586 (!cast<Instruction>(NAME # 2v16f8) V128:$_Rd, V128:$Rn, V128:$Rm)>; 6587} 6588 6589multiclass SIMD_FP8_Dot2<string asm, SDPatternOperator op> { 6590 let Uses = [FPMR, FPCR], mayLoad = 1 in { 6591 def v4f16 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b01, 0b1111, asm, ".4h", ".8b", 6592 V64, v4f16, v8i8, op>; 6593 def v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1111, asm, ".8h", ".16b", 6594 V128, v8f16, v16i8, op>; 6595 } 6596} 6597 6598multiclass SIMD_FP8_Dot4<string asm, SDPatternOperator op> { 6599 let Uses = [FPMR, FPCR], mayLoad = 1 in { 6600 def v2f32 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b00, 0b1111, asm, ".2s", ".8b", 6601 V64, v2f32, v8i8, op>; 6602 def v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1111, asm, ".4s", ".16b", 6603 V128, v4f32, v16i8, op>; 6604 } 6605} 6606 6607let mayRaiseFPException = 1, Uses = [FPCR] in 6608multiclass SIMDThreeVectorFscale<bit U, bit S, bits<3> opc, 6609 string asm, SDPatternOperator OpNode> { 6610 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 6611 asm, ".4h", 6612 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6613 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 6614 asm, ".8h", 6615 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6616 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 6617 asm, ".2s", 6618 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6619 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 6620 asm, ".4s", 6621 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6622 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 6623 asm, ".2d", 6624 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6625} 6626 6627//---------------------------------------------------------------------------- 6628// AdvSIMD two register vector instructions. 6629//---------------------------------------------------------------------------- 6630 6631let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6632class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6633 bits<2> size2, RegisterOperand regtype, string asm, 6634 string dstkind, string srckind, list<dag> pattern> 6635 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6636 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6637 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 6638 Sched<[!if(Q, WriteVq, WriteVd)]> { 6639 bits<5> Rd; 6640 bits<5> Rn; 6641 let Inst{31} = 0; 6642 let Inst{30} = Q; 6643 let Inst{29} = U; 6644 let Inst{28-24} = 0b01110; 6645 let Inst{23-22} = size; 6646 let Inst{21} = 0b1; 6647 let Inst{20-19} = size2; 6648 let Inst{18-17} = 0b00; 6649 let Inst{16-12} = opcode; 6650 let Inst{11-10} = 0b10; 6651 let Inst{9-5} = Rn; 6652 let Inst{4-0} = Rd; 6653} 6654 6655let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6656class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6657 bits<2> size2, RegisterOperand regtype, 6658 string asm, string dstkind, string srckind, 6659 list<dag> pattern> 6660 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 6661 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6662 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6663 Sched<[!if(Q, WriteVq, WriteVd)]> { 6664 bits<5> Rd; 6665 bits<5> Rn; 6666 let Inst{31} = 0; 6667 let Inst{30} = Q; 6668 let Inst{29} = U; 6669 let Inst{28-24} = 0b01110; 6670 let Inst{23-22} = size; 6671 let Inst{21} = 0b1; 6672 let Inst{20-19} = size2; 6673 let Inst{18-17} = 0b00; 6674 let Inst{16-12} = opcode; 6675 let Inst{11-10} = 0b10; 6676 let Inst{9-5} = Rn; 6677 let Inst{4-0} = Rd; 6678} 6679 6680// Supports B, H, and S element sizes. 6681multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 6682 SDPatternOperator OpNode> { 6683 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6684 asm, ".8b", ".8b", 6685 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6686 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6687 asm, ".16b", ".16b", 6688 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6689 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6690 asm, ".4h", ".4h", 6691 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6692 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6693 asm, ".8h", ".8h", 6694 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6695 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6696 asm, ".2s", ".2s", 6697 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6698 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6699 asm, ".4s", ".4s", 6700 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6701} 6702 6703class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 6704 RegisterOperand regtype, string asm, string dstkind, 6705 string srckind, string amount> 6706 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 6707 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 6708 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 6709 Sched<[WriteVq]> { 6710 bits<5> Rd; 6711 bits<5> Rn; 6712 let Inst{31} = 0; 6713 let Inst{30} = Q; 6714 let Inst{29-24} = 0b101110; 6715 let Inst{23-22} = size; 6716 let Inst{21-10} = 0b100001001110; 6717 let Inst{9-5} = Rn; 6718 let Inst{4-0} = Rd; 6719} 6720 6721multiclass SIMDVectorLShiftLongBySizeBHS { 6722 let hasSideEffects = 0 in { 6723 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 6724 "shll", ".8h", ".8b", "8">; 6725 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 6726 "shll2", ".8h", ".16b", "8">; 6727 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 6728 "shll", ".4s", ".4h", "16">; 6729 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 6730 "shll2", ".4s", ".8h", "16">; 6731 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 6732 "shll", ".2d", ".2s", "32">; 6733 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 6734 "shll2", ".2d", ".4s", "32">; 6735 } 6736} 6737 6738// Supports all element sizes. 6739multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 6740 SDPatternOperator OpNode> { 6741 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6742 asm, ".4h", ".8b", 6743 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6744 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6745 asm, ".8h", ".16b", 6746 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6747 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6748 asm, ".2s", ".4h", 6749 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6750 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6751 asm, ".4s", ".8h", 6752 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6753 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6754 asm, ".1d", ".2s", 6755 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6756 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6757 asm, ".2d", ".4s", 6758 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6759} 6760 6761multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 6762 SDPatternOperator OpNode> { 6763 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6764 asm, ".4h", ".8b", 6765 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 6766 (v8i8 V64:$Rn)))]>; 6767 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6768 asm, ".8h", ".16b", 6769 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 6770 (v16i8 V128:$Rn)))]>; 6771 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6772 asm, ".2s", ".4h", 6773 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 6774 (v4i16 V64:$Rn)))]>; 6775 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6776 asm, ".4s", ".8h", 6777 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 6778 (v8i16 V128:$Rn)))]>; 6779 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6780 asm, ".1d", ".2s", 6781 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 6782 (v2i32 V64:$Rn)))]>; 6783 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6784 asm, ".2d", ".4s", 6785 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 6786 (v4i32 V128:$Rn)))]>; 6787} 6788 6789// Supports all element sizes, except 1xD. 6790multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 6791 SDPatternOperator OpNode> { 6792 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6793 asm, ".8b", ".8b", 6794 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 6795 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6796 asm, ".16b", ".16b", 6797 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 6798 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6799 asm, ".4h", ".4h", 6800 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 6801 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6802 asm, ".8h", ".8h", 6803 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 6804 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6805 asm, ".2s", ".2s", 6806 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 6807 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6808 asm, ".4s", ".4s", 6809 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 6810 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 6811 asm, ".2d", ".2d", 6812 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 6813} 6814 6815multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 6816 SDPatternOperator OpNode = null_frag> { 6817 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6818 asm, ".8b", ".8b", 6819 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6820 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6821 asm, ".16b", ".16b", 6822 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6823 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6824 asm, ".4h", ".4h", 6825 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6826 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6827 asm, ".8h", ".8h", 6828 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6829 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6830 asm, ".2s", ".2s", 6831 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6832 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6833 asm, ".4s", ".4s", 6834 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6835 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6836 asm, ".2d", ".2d", 6837 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6838} 6839 6840 6841// Supports only B element sizes. 6842multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6843 SDPatternOperator OpNode> { 6844 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6845 asm, ".8b", ".8b", 6846 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6847 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6848 asm, ".16b", ".16b", 6849 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6850 6851} 6852 6853// Supports only B and H element sizes. 6854multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6855 SDPatternOperator OpNode> { 6856 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6857 asm, ".8b", ".8b", 6858 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6859 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6860 asm, ".16b", ".16b", 6861 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6862 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6863 asm, ".4h", ".4h", 6864 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6865 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6866 asm, ".8h", ".8h", 6867 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6868} 6869 6870// Supports H, S and D element sizes, uses high bit of the size field 6871// as an extra opcode bit. 6872multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6873 SDPatternOperator OpNode, 6874 int fpexceptions = 1> { 6875 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 6876 let Predicates = [HasNEON, HasFullFP16] in { 6877 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6878 asm, ".4h", ".4h", 6879 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6880 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6881 asm, ".8h", ".8h", 6882 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6883 } // Predicates = [HasNEON, HasFullFP16] 6884 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6885 asm, ".2s", ".2s", 6886 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6887 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6888 asm, ".4s", ".4s", 6889 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6890 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6891 asm, ".2d", ".2d", 6892 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6893 } 6894} 6895 6896multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6897 SDPatternOperator OpNode> 6898 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6899 6900// Supports only S and D element sizes 6901let mayRaiseFPException = 1, Uses = [FPCR] in 6902multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6903 SDPatternOperator OpNode = null_frag> { 6904 6905 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6906 asm, ".2s", ".2s", 6907 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6908 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6909 asm, ".4s", ".4s", 6910 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6911 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6912 asm, ".2d", ".2d", 6913 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6914} 6915 6916multiclass FRIntNNTVector<bit U, bit op, string asm, 6917 SDPatternOperator OpNode = null_frag> : 6918 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6919 6920// Supports only S element size. 6921multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6922 SDPatternOperator OpNode> { 6923 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6924 asm, ".2s", ".2s", 6925 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6926 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6927 asm, ".4s", ".4s", 6928 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6929} 6930 6931let mayRaiseFPException = 1, Uses = [FPCR] in 6932multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6933 SDPatternOperator OpNode> { 6934 let Predicates = [HasNEON, HasFullFP16] in { 6935 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6936 asm, ".4h", ".4h", 6937 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6938 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6939 asm, ".8h", ".8h", 6940 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6941 } // Predicates = [HasNEON, HasFullFP16] 6942 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6943 asm, ".2s", ".2s", 6944 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6945 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6946 asm, ".4s", ".4s", 6947 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6948 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6949 asm, ".2d", ".2d", 6950 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6951} 6952 6953let mayRaiseFPException = 1, Uses = [FPCR] in 6954multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6955 SDPatternOperator OpNode> { 6956 let Predicates = [HasNEON, HasFullFP16] in { 6957 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6958 asm, ".4h", ".4h", 6959 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6960 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6961 asm, ".8h", ".8h", 6962 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6963 } // Predicates = [HasNEON, HasFullFP16] 6964 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6965 asm, ".2s", ".2s", 6966 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6967 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6968 asm, ".4s", ".4s", 6969 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6970 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6971 asm, ".2d", ".2d", 6972 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6973} 6974 6975let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6976class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6977 RegisterOperand inreg, RegisterOperand outreg, 6978 string asm, string outkind, string inkind, 6979 list<dag> pattern> 6980 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6981 "{\t$Rd" # outkind # ", $Rn" # inkind # 6982 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6983 Sched<[WriteVq]> { 6984 bits<5> Rd; 6985 bits<5> Rn; 6986 let Inst{31} = 0; 6987 let Inst{30} = Q; 6988 let Inst{29} = U; 6989 let Inst{28-24} = 0b01110; 6990 let Inst{23-22} = size; 6991 let Inst{21-17} = 0b10000; 6992 let Inst{16-12} = opcode; 6993 let Inst{11-10} = 0b10; 6994 let Inst{9-5} = Rn; 6995 let Inst{4-0} = Rd; 6996} 6997 6998let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6999class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 7000 RegisterOperand inreg, RegisterOperand outreg, 7001 string asm, string outkind, string inkind, 7002 list<dag> pattern> 7003 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 7004 "{\t$Rd" # outkind # ", $Rn" # inkind # 7005 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 7006 Sched<[WriteVq]> { 7007 bits<5> Rd; 7008 bits<5> Rn; 7009 let Inst{31} = 0; 7010 let Inst{30} = Q; 7011 let Inst{29} = U; 7012 let Inst{28-24} = 0b01110; 7013 let Inst{23-22} = size; 7014 let Inst{21-17} = 0b10000; 7015 let Inst{16-12} = opcode; 7016 let Inst{11-10} = 0b10; 7017 let Inst{9-5} = Rn; 7018 let Inst{4-0} = Rd; 7019} 7020 7021multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 7022 SDPatternOperator OpNode> { 7023 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 7024 asm, ".8b", ".8h", 7025 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 7026 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 7027 asm#"2", ".16b", ".8h", []>; 7028 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 7029 asm, ".4h", ".4s", 7030 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 7031 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 7032 asm#"2", ".8h", ".4s", []>; 7033 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 7034 asm, ".2s", ".2d", 7035 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 7036 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 7037 asm#"2", ".4s", ".2d", []>; 7038 7039 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 7040 (!cast<Instruction>(NAME # "v16i8") 7041 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 7042 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 7043 (!cast<Instruction>(NAME # "v8i16") 7044 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 7045 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 7046 (!cast<Instruction>(NAME # "v4i32") 7047 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 7048} 7049 7050//---------------------------------------------------------------------------- 7051// FP8 Advanced SIMD two-register miscellaneous 7052//---------------------------------------------------------------------------- 7053multiclass SIMD_FP8_CVTL<bits<2>sz, string asm, ValueType dty, SDPatternOperator Op> { 7054 let Uses=[FPMR, FPCR], mayLoad = 1 in { 7055 def NAME : BaseSIMDMixedTwoVector<0b0, 0b1, sz, 0b10111, V64, V128, 7056 asm, ".8h", ".8b", []>; 7057 def NAME#2 : BaseSIMDMixedTwoVector<0b1, 0b1, sz, 0b10111, V128, V128, 7058 asm#2, ".8h", ".16b", []>; 7059 } 7060 def : Pat<(dty (Op (v8i8 V64:$Rn))), 7061 (!cast<Instruction>(NAME) V64:$Rn)>; 7062 7063 def : Pat<(dty (Op (v16i8 V128:$Rn))), 7064 (!cast<Instruction>(NAME#2) V128:$Rn)>; 7065} 7066 7067class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 7068 bits<5> opcode, RegisterOperand regtype, string asm, 7069 string kind, string zero, ValueType dty, 7070 ValueType sty, SDNode OpNode> 7071 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7072 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 7073 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 7074 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 7075 Sched<[!if(Q, WriteVq, WriteVd)]> { 7076 bits<5> Rd; 7077 bits<5> Rn; 7078 let Inst{31} = 0; 7079 let Inst{30} = Q; 7080 let Inst{29} = U; 7081 let Inst{28-24} = 0b01110; 7082 let Inst{23-22} = size; 7083 let Inst{21} = 0b1; 7084 let Inst{20-19} = size2; 7085 let Inst{18-17} = 0b00; 7086 let Inst{16-12} = opcode; 7087 let Inst{11-10} = 0b10; 7088 let Inst{9-5} = Rn; 7089 let Inst{4-0} = Rd; 7090} 7091 7092// Comparisons support all element sizes, except 1xD. 7093multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 7094 SDNode OpNode> { 7095 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 7096 asm, ".8b", "0", 7097 v8i8, v8i8, OpNode>; 7098 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 7099 asm, ".16b", "0", 7100 v16i8, v16i8, OpNode>; 7101 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 7102 asm, ".4h", "0", 7103 v4i16, v4i16, OpNode>; 7104 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 7105 asm, ".8h", "0", 7106 v8i16, v8i16, OpNode>; 7107 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 7108 asm, ".2s", "0", 7109 v2i32, v2i32, OpNode>; 7110 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 7111 asm, ".4s", "0", 7112 v4i32, v4i32, OpNode>; 7113 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 7114 asm, ".2d", "0", 7115 v2i64, v2i64, OpNode>; 7116} 7117 7118// FP Comparisons support only S and D element sizes (and H for v8.2a). 7119multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 7120 string asm, SDNode OpNode> { 7121 7122 let mayRaiseFPException = 1, Uses = [FPCR] in { 7123 let Predicates = [HasNEON, HasFullFP16] in { 7124 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 7125 asm, ".4h", "0.0", 7126 v4i16, v4f16, OpNode>; 7127 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 7128 asm, ".8h", "0.0", 7129 v8i16, v8f16, OpNode>; 7130 } // Predicates = [HasNEON, HasFullFP16] 7131 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 7132 asm, ".2s", "0.0", 7133 v2i32, v2f32, OpNode>; 7134 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 7135 asm, ".4s", "0.0", 7136 v4i32, v4f32, OpNode>; 7137 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 7138 asm, ".2d", "0.0", 7139 v2i64, v2f64, OpNode>; 7140 } 7141 7142 let Predicates = [HasNEON, HasFullFP16] in { 7143 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 7144 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 7145 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 7146 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 7147 } 7148 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 7149 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 7150 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 7151 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 7152 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 7153 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 7154 let Predicates = [HasNEON, HasFullFP16] in { 7155 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 7156 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 7157 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 7158 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 7159 } 7160 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 7161 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 7162 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 7163 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 7164 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 7165 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 7166} 7167 7168let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 7169class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 7170 RegisterOperand outtype, RegisterOperand intype, 7171 string asm, string VdTy, string VnTy, 7172 list<dag> pattern> 7173 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 7174 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 7175 Sched<[WriteVq]> { 7176 bits<5> Rd; 7177 bits<5> Rn; 7178 let Inst{31} = 0; 7179 let Inst{30} = Q; 7180 let Inst{29} = U; 7181 let Inst{28-24} = 0b01110; 7182 let Inst{23-22} = size; 7183 let Inst{21-17} = 0b10000; 7184 let Inst{16-12} = opcode; 7185 let Inst{11-10} = 0b10; 7186 let Inst{9-5} = Rn; 7187 let Inst{4-0} = Rd; 7188} 7189 7190let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 7191class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 7192 RegisterOperand outtype, RegisterOperand intype, 7193 string asm, string VdTy, string VnTy, 7194 list<dag> pattern> 7195 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 7196 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 7197 Sched<[WriteVq]> { 7198 bits<5> Rd; 7199 bits<5> Rn; 7200 let Inst{31} = 0; 7201 let Inst{30} = Q; 7202 let Inst{29} = U; 7203 let Inst{28-24} = 0b01110; 7204 let Inst{23-22} = size; 7205 let Inst{21-17} = 0b10000; 7206 let Inst{16-12} = opcode; 7207 let Inst{11-10} = 0b10; 7208 let Inst{9-5} = Rn; 7209 let Inst{4-0} = Rd; 7210} 7211 7212multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 7213 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 7214 asm, ".4s", ".4h", []>; 7215 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 7216 asm#"2", ".4s", ".8h", []>; 7217 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 7218 asm, ".2d", ".2s", []>; 7219 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 7220 asm#"2", ".2d", ".4s", []>; 7221} 7222 7223multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 7224 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 7225 asm, ".4h", ".4s", []>; 7226 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 7227 asm#"2", ".8h", ".4s", []>; 7228 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 7229 asm, ".2s", ".2d", []>; 7230 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 7231 asm#"2", ".4s", ".2d", []>; 7232} 7233 7234multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 7235 SDPatternOperator OpNode> { 7236 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 7237 asm, ".2s", ".2d", 7238 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 7239 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 7240 asm#"2", ".4s", ".2d", []>; 7241 7242 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 7243 (!cast<Instruction>(NAME # "v4f32") 7244 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 7245} 7246 7247//---------------------------------------------------------------------------- 7248// AdvSIMD three register different-size vector instructions. 7249//---------------------------------------------------------------------------- 7250 7251let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7252class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 7253 RegisterOperand outtype, RegisterOperand intype1, 7254 RegisterOperand intype2, string asm, 7255 string outkind, string inkind1, string inkind2, 7256 list<dag> pattern> 7257 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 7258 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 7259 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 7260 Sched<[WriteVq]> { 7261 bits<5> Rd; 7262 bits<5> Rn; 7263 bits<5> Rm; 7264 let Inst{31} = 0; 7265 let Inst{30} = size{0}; 7266 let Inst{29} = U; 7267 let Inst{28-24} = 0b01110; 7268 let Inst{23-22} = size{2-1}; 7269 let Inst{21} = 1; 7270 let Inst{20-16} = Rm; 7271 let Inst{15-12} = opcode; 7272 let Inst{11-10} = 0b00; 7273 let Inst{9-5} = Rn; 7274 let Inst{4-0} = Rd; 7275} 7276 7277let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7278class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 7279 RegisterOperand outtype, RegisterOperand intype1, 7280 RegisterOperand intype2, string asm, 7281 string outkind, string inkind1, string inkind2, 7282 list<dag> pattern> 7283 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 7284 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 7285 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 7286 Sched<[WriteVq]> { 7287 bits<5> Rd; 7288 bits<5> Rn; 7289 bits<5> Rm; 7290 let Inst{31} = 0; 7291 let Inst{30} = size{0}; 7292 let Inst{29} = U; 7293 let Inst{28-24} = 0b01110; 7294 let Inst{23-22} = size{2-1}; 7295 let Inst{21} = 1; 7296 let Inst{20-16} = Rm; 7297 let Inst{15-12} = opcode; 7298 let Inst{11-10} = 0b00; 7299 let Inst{9-5} = Rn; 7300 let Inst{4-0} = Rd; 7301} 7302 7303// FIXME: TableGen doesn't know how to deal with expanded types that also 7304// change the element count (in this case, placing the results in 7305// the high elements of the result register rather than the low 7306// elements). Until that's fixed, we can't code-gen those. 7307multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 7308 Intrinsic IntOp> { 7309 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7310 V64, V128, V128, 7311 asm, ".8b", ".8h", ".8h", 7312 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 7313 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7314 V128, V128, V128, 7315 asm#"2", ".16b", ".8h", ".8h", 7316 []>; 7317 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7318 V64, V128, V128, 7319 asm, ".4h", ".4s", ".4s", 7320 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 7321 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7322 V128, V128, V128, 7323 asm#"2", ".8h", ".4s", ".4s", 7324 []>; 7325 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7326 V64, V128, V128, 7327 asm, ".2s", ".2d", ".2d", 7328 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 7329 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7330 V128, V128, V128, 7331 asm#"2", ".4s", ".2d", ".2d", 7332 []>; 7333 7334 7335 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 7336 // a version attached to an instruction. 7337 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 7338 (v8i16 V128:$Rm))), 7339 (!cast<Instruction>(NAME # "v8i16_v16i8") 7340 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7341 V128:$Rn, V128:$Rm)>; 7342 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 7343 (v4i32 V128:$Rm))), 7344 (!cast<Instruction>(NAME # "v4i32_v8i16") 7345 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7346 V128:$Rn, V128:$Rm)>; 7347 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 7348 (v2i64 V128:$Rm))), 7349 (!cast<Instruction>(NAME # "v2i64_v4i32") 7350 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7351 V128:$Rn, V128:$Rm)>; 7352} 7353 7354multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 7355 SDPatternOperator OpNode> { 7356 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7357 V128, V64, V64, 7358 asm, ".8h", ".8b", ".8b", 7359 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7360 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7361 V128, V128, V128, 7362 asm#"2", ".8h", ".16b", ".16b", []>; 7363 let Predicates = [HasAES] in { 7364 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 7365 V128, V64, V64, 7366 asm, ".1q", ".1d", ".1d", 7367 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>; 7368 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 7369 V128, V128, V128, 7370 asm#"2", ".1q", ".2d", ".2d", 7371 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)), 7372 (extract_high_v2i64 (v2i64 V128:$Rm))))]>; 7373 } 7374 7375 def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 7376 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 7377 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 7378} 7379 7380multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 7381 SDPatternOperator OpNode> { 7382 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7383 V128, V64, V64, 7384 asm, ".4s", ".4h", ".4h", 7385 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7386 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7387 V128, V128, V128, 7388 asm#"2", ".4s", ".8h", ".8h", 7389 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7390 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7391 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7392 V128, V64, V64, 7393 asm, ".2d", ".2s", ".2s", 7394 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7395 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7396 V128, V128, V128, 7397 asm#"2", ".2d", ".4s", ".4s", 7398 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7399 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7400} 7401 7402multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 7403 SDPatternOperator OpNode = null_frag> { 7404 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7405 V128, V64, V64, 7406 asm, ".8h", ".8b", ".8b", 7407 [(set (v8i16 V128:$Rd), 7408 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 7409 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7410 V128, V128, V128, 7411 asm#"2", ".8h", ".16b", ".16b", 7412 [(set (v8i16 V128:$Rd), 7413 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7414 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 7415 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7416 V128, V64, V64, 7417 asm, ".4s", ".4h", ".4h", 7418 [(set (v4i32 V128:$Rd), 7419 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 7420 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7421 V128, V128, V128, 7422 asm#"2", ".4s", ".8h", ".8h", 7423 [(set (v4i32 V128:$Rd), 7424 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7425 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7426 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7427 V128, V64, V64, 7428 asm, ".2d", ".2s", ".2s", 7429 [(set (v2i64 V128:$Rd), 7430 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 7431 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7432 V128, V128, V128, 7433 asm#"2", ".2d", ".4s", ".4s", 7434 [(set (v2i64 V128:$Rd), 7435 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7436 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7437} 7438 7439multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 7440 string asm, 7441 SDPatternOperator OpNode> { 7442 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7443 V128, V64, V64, 7444 asm, ".8h", ".8b", ".8b", 7445 [(set (v8i16 V128:$dst), 7446 (add (v8i16 V128:$Rd), 7447 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 7448 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7449 V128, V128, V128, 7450 asm#"2", ".8h", ".16b", ".16b", 7451 [(set (v8i16 V128:$dst), 7452 (add (v8i16 V128:$Rd), 7453 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7454 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 7455 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7456 V128, V64, V64, 7457 asm, ".4s", ".4h", ".4h", 7458 [(set (v4i32 V128:$dst), 7459 (add (v4i32 V128:$Rd), 7460 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 7461 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7462 V128, V128, V128, 7463 asm#"2", ".4s", ".8h", ".8h", 7464 [(set (v4i32 V128:$dst), 7465 (add (v4i32 V128:$Rd), 7466 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7467 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 7468 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7469 V128, V64, V64, 7470 asm, ".2d", ".2s", ".2s", 7471 [(set (v2i64 V128:$dst), 7472 (add (v2i64 V128:$Rd), 7473 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 7474 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7475 V128, V128, V128, 7476 asm#"2", ".2d", ".4s", ".4s", 7477 [(set (v2i64 V128:$dst), 7478 (add (v2i64 V128:$Rd), 7479 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7480 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 7481} 7482 7483multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 7484 SDPatternOperator OpNode = null_frag> { 7485 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7486 V128, V64, V64, 7487 asm, ".8h", ".8b", ".8b", 7488 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7489 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7490 V128, V128, V128, 7491 asm#"2", ".8h", ".16b", ".16b", 7492 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7493 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7494 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7495 V128, V64, V64, 7496 asm, ".4s", ".4h", ".4h", 7497 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7498 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7499 V128, V128, V128, 7500 asm#"2", ".4s", ".8h", ".8h", 7501 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7502 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7503 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7504 V128, V64, V64, 7505 asm, ".2d", ".2s", ".2s", 7506 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7507 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7508 V128, V128, V128, 7509 asm#"2", ".2d", ".4s", ".4s", 7510 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7511 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7512} 7513 7514multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 7515 string asm, 7516 SDPatternOperator OpNode> { 7517 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7518 V128, V64, V64, 7519 asm, ".8h", ".8b", ".8b", 7520 [(set (v8i16 V128:$dst), 7521 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7522 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7523 V128, V128, V128, 7524 asm#"2", ".8h", ".16b", ".16b", 7525 [(set (v8i16 V128:$dst), 7526 (OpNode (v8i16 V128:$Rd), 7527 (extract_high_v16i8 (v16i8 V128:$Rn)), 7528 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7529 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7530 V128, V64, V64, 7531 asm, ".4s", ".4h", ".4h", 7532 [(set (v4i32 V128:$dst), 7533 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7534 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7535 V128, V128, V128, 7536 asm#"2", ".4s", ".8h", ".8h", 7537 [(set (v4i32 V128:$dst), 7538 (OpNode (v4i32 V128:$Rd), 7539 (extract_high_v8i16 (v8i16 V128:$Rn)), 7540 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7541 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7542 V128, V64, V64, 7543 asm, ".2d", ".2s", ".2s", 7544 [(set (v2i64 V128:$dst), 7545 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7546 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7547 V128, V128, V128, 7548 asm#"2", ".2d", ".4s", ".4s", 7549 [(set (v2i64 V128:$dst), 7550 (OpNode (v2i64 V128:$Rd), 7551 (extract_high_v4i32 (v4i32 V128:$Rn)), 7552 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7553} 7554 7555multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 7556 SDPatternOperator Accum> { 7557 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7558 V128, V64, V64, 7559 asm, ".4s", ".4h", ".4h", 7560 [(set (v4i32 V128:$dst), 7561 (Accum (v4i32 V128:$Rd), 7562 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 7563 (v4i16 V64:$Rm)))))]>; 7564 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7565 V128, V128, V128, 7566 asm#"2", ".4s", ".8h", ".8h", 7567 [(set (v4i32 V128:$dst), 7568 (Accum (v4i32 V128:$Rd), 7569 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 7570 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7571 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7572 V128, V64, V64, 7573 asm, ".2d", ".2s", ".2s", 7574 [(set (v2i64 V128:$dst), 7575 (Accum (v2i64 V128:$Rd), 7576 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 7577 (v2i32 V64:$Rm)))))]>; 7578 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7579 V128, V128, V128, 7580 asm#"2", ".2d", ".4s", ".4s", 7581 [(set (v2i64 V128:$dst), 7582 (Accum (v2i64 V128:$Rd), 7583 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 7584 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7585} 7586 7587multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 7588 SDPatternOperator OpNode> { 7589 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7590 V128, V128, V64, 7591 asm, ".8h", ".8h", ".8b", 7592 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 7593 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7594 V128, V128, V128, 7595 asm#"2", ".8h", ".8h", ".16b", 7596 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7597 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7598 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7599 V128, V128, V64, 7600 asm, ".4s", ".4s", ".4h", 7601 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 7602 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7603 V128, V128, V128, 7604 asm#"2", ".4s", ".4s", ".8h", 7605 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7606 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7607 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7608 V128, V128, V64, 7609 asm, ".2d", ".2d", ".2s", 7610 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 7611 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7612 V128, V128, V128, 7613 asm#"2", ".2d", ".2d", ".4s", 7614 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7615 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7616} 7617 7618//---------------------------------------------------------------------------- 7619// AdvSIMD bitwise extract from vector 7620//---------------------------------------------------------------------------- 7621 7622class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 7623 string asm, string kind> 7624 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 7625 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 7626 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 7627 [(set (vty regtype:$Rd), 7628 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 7629 Sched<[!if(size, WriteVq, WriteVd)]> { 7630 bits<5> Rd; 7631 bits<5> Rn; 7632 bits<5> Rm; 7633 bits<4> imm; 7634 let Inst{31} = 0; 7635 let Inst{30} = size; 7636 let Inst{29-21} = 0b101110000; 7637 let Inst{20-16} = Rm; 7638 let Inst{15} = 0; 7639 let Inst{14-11} = imm; 7640 let Inst{10} = 0; 7641 let Inst{9-5} = Rn; 7642 let Inst{4-0} = Rd; 7643} 7644 7645 7646multiclass SIMDBitwiseExtract<string asm> { 7647 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 7648 let imm{3} = 0; 7649 } 7650 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 7651} 7652 7653//---------------------------------------------------------------------------- 7654// AdvSIMD zip vector 7655//---------------------------------------------------------------------------- 7656 7657class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 7658 string asm, string kind, SDNode OpNode, ValueType valty> 7659 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7660 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 7661 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 7662 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 7663 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 7664 bits<5> Rd; 7665 bits<5> Rn; 7666 bits<5> Rm; 7667 let Inst{31} = 0; 7668 let Inst{30} = size{0}; 7669 let Inst{29-24} = 0b001110; 7670 let Inst{23-22} = size{2-1}; 7671 let Inst{21} = 0; 7672 let Inst{20-16} = Rm; 7673 let Inst{15} = 0; 7674 let Inst{14-12} = opc; 7675 let Inst{11-10} = 0b10; 7676 let Inst{9-5} = Rn; 7677 let Inst{4-0} = Rd; 7678} 7679 7680multiclass SIMDZipVector<bits<3>opc, string asm, 7681 SDNode OpNode> { 7682 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 7683 asm, ".8b", OpNode, v8i8>; 7684 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 7685 asm, ".16b", OpNode, v16i8>; 7686 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 7687 asm, ".4h", OpNode, v4i16>; 7688 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 7689 asm, ".8h", OpNode, v8i16>; 7690 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 7691 asm, ".2s", OpNode, v2i32>; 7692 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 7693 asm, ".4s", OpNode, v4i32>; 7694 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 7695 asm, ".2d", OpNode, v2i64>; 7696 7697 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 7698 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7699 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)), 7700 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7701 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 7702 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7703 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)), 7704 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7705 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 7706 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 7707 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 7708 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 7709 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 7710 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 7711} 7712 7713//---------------------------------------------------------------------------- 7714// AdvSIMD three register scalar instructions 7715//---------------------------------------------------------------------------- 7716 7717let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7718class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 7719 RegisterClass regtype, string asm, 7720 list<dag> pattern> 7721 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7722 "\t$Rd, $Rn, $Rm", "", pattern>, 7723 Sched<[WriteVd]> { 7724 bits<5> Rd; 7725 bits<5> Rn; 7726 bits<5> Rm; 7727 let Inst{31-30} = 0b01; 7728 let Inst{29} = U; 7729 let Inst{28-24} = 0b11110; 7730 let Inst{23-21} = size; 7731 let Inst{20-16} = Rm; 7732 let Inst{15-11} = opcode; 7733 let Inst{10} = 1; 7734 let Inst{9-5} = Rn; 7735 let Inst{4-0} = Rd; 7736} 7737 7738let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7739class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 7740 dag oops, dag iops, string asm, 7741 list<dag> pattern> 7742 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 7743 Sched<[WriteVd]> { 7744 bits<5> Rd; 7745 bits<5> Rn; 7746 bits<5> Rm; 7747 let Inst{31-30} = 0b01; 7748 let Inst{29} = U; 7749 let Inst{28-24} = 0b11110; 7750 let Inst{23-22} = size; 7751 let Inst{21} = R; 7752 let Inst{20-16} = Rm; 7753 let Inst{15-11} = opcode; 7754 let Inst{10} = 1; 7755 let Inst{9-5} = Rn; 7756 let Inst{4-0} = Rd; 7757} 7758 7759multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 7760 SDPatternOperator OpNode> { 7761 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7762 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7763} 7764 7765multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 7766 SDPatternOperator OpNode> { 7767 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7768 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7769 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 7770 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7771 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 7772 7773 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 7774 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 7775 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 7776 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 7777} 7778 7779multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 7780 SDPatternOperator OpNode> { 7781 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 7782 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7783 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7784} 7785 7786multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 7787 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 7788 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 7789 asm, []>; 7790 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 7791 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 7792 asm, []>; 7793} 7794 7795multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 7796 SDPatternOperator OpNode = null_frag, 7797 Predicate pred = HasNEON> { 7798 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7799 let Predicates = [pred] in { 7800 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7801 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7802 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7803 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7804 } 7805 let Predicates = [pred, HasFullFP16] in { 7806 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7807 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 7808 } 7809 } 7810 7811 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7812 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7813} 7814 7815multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 7816 SDPatternOperator OpNode = null_frag> { 7817 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7818 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7819 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7820 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7821 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 7822 let Predicates = [HasNEON, HasFullFP16] in { 7823 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7824 []>; 7825 } // Predicates = [HasNEON, HasFullFP16] 7826 } 7827 7828 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7829 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7830} 7831 7832class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 7833 dag oops, dag iops, string asm, string cstr, list<dag> pat> 7834 : I<oops, iops, asm, 7835 "\t$Rd, $Rn, $Rm", cstr, pat>, 7836 Sched<[WriteVd]> { 7837 bits<5> Rd; 7838 bits<5> Rn; 7839 bits<5> Rm; 7840 let Inst{31-30} = 0b01; 7841 let Inst{29} = U; 7842 let Inst{28-24} = 0b11110; 7843 let Inst{23-22} = size; 7844 let Inst{21} = 1; 7845 let Inst{20-16} = Rm; 7846 let Inst{15-11} = opcode; 7847 let Inst{10} = 0; 7848 let Inst{9-5} = Rn; 7849 let Inst{4-0} = Rd; 7850} 7851 7852let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7853multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 7854 SDPatternOperator OpNode = null_frag> { 7855 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7856 (outs FPR32:$Rd), 7857 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7858 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7859 (outs FPR64:$Rd), 7860 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7861 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7862} 7863 7864let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7865multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7866 SDPatternOperator OpNode = null_frag> { 7867 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7868 (outs FPR32:$dst), 7869 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7870 asm, "$Rd = $dst", []>; 7871 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7872 (outs FPR64:$dst), 7873 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7874 asm, "$Rd = $dst", 7875 [(set (i64 FPR64:$dst), 7876 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7877} 7878 7879//---------------------------------------------------------------------------- 7880// AdvSIMD two register scalar instructions 7881//---------------------------------------------------------------------------- 7882 7883let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7884class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7885 RegisterClass regtype, RegisterClass regtype2, 7886 string asm, list<dag> pat> 7887 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7888 "\t$Rd, $Rn", "", pat>, 7889 Sched<[WriteVd]> { 7890 bits<5> Rd; 7891 bits<5> Rn; 7892 let Inst{31-30} = 0b01; 7893 let Inst{29} = U; 7894 let Inst{28-24} = 0b11110; 7895 let Inst{23-22} = size; 7896 let Inst{21} = 0b1; 7897 let Inst{20-19} = size2; 7898 let Inst{18-17} = 0b00; 7899 let Inst{16-12} = opcode; 7900 let Inst{11-10} = 0b10; 7901 let Inst{9-5} = Rn; 7902 let Inst{4-0} = Rd; 7903} 7904 7905let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7906class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7907 RegisterClass regtype, RegisterClass regtype2, 7908 string asm, list<dag> pat> 7909 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7910 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7911 Sched<[WriteVd]> { 7912 bits<5> Rd; 7913 bits<5> Rn; 7914 let Inst{31-30} = 0b01; 7915 let Inst{29} = U; 7916 let Inst{28-24} = 0b11110; 7917 let Inst{23-22} = size; 7918 let Inst{21-17} = 0b10000; 7919 let Inst{16-12} = opcode; 7920 let Inst{11-10} = 0b10; 7921 let Inst{9-5} = Rn; 7922 let Inst{4-0} = Rd; 7923} 7924 7925 7926let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7927class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7928 RegisterClass regtype, string asm, string zero> 7929 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7930 "\t$Rd, $Rn, #" # zero, "", []>, 7931 Sched<[WriteVd]> { 7932 bits<5> Rd; 7933 bits<5> Rn; 7934 let Inst{31-30} = 0b01; 7935 let Inst{29} = U; 7936 let Inst{28-24} = 0b11110; 7937 let Inst{23-22} = size; 7938 let Inst{21} = 0b1; 7939 let Inst{20-19} = size2; 7940 let Inst{18-17} = 0b00; 7941 let Inst{16-12} = opcode; 7942 let Inst{11-10} = 0b10; 7943 let Inst{9-5} = Rn; 7944 let Inst{4-0} = Rd; 7945} 7946 7947let mayRaiseFPException = 1, Uses = [FPCR] in 7948class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7949 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7950 [(set (f32 FPR32:$Rd), (AArch64fcvtxnsdr (f64 FPR64:$Rn)))]>, 7951 Sched<[WriteVd]> { 7952 bits<5> Rd; 7953 bits<5> Rn; 7954 let Inst{31-17} = 0b011111100110000; 7955 let Inst{16-12} = opcode; 7956 let Inst{11-10} = 0b10; 7957 let Inst{9-5} = Rn; 7958 let Inst{4-0} = Rd; 7959} 7960 7961multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7962 SDPatternOperator OpNode> { 7963 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7964 7965 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7966 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7967} 7968 7969multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7970 SDPatternOperator OpNode> { 7971 let mayRaiseFPException = 1, Uses = [FPCR] in { 7972 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7973 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7974 let Predicates = [HasNEON, HasFullFP16] in { 7975 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7976 } 7977 } 7978 7979 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7980 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7981 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7982 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7983 let Predicates = [HasNEON, HasFullFP16] in { 7984 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7985 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7986 } 7987 7988 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7989 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7990} 7991 7992multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7993 SDPatternOperator OpNode = null_frag, 7994 list<Predicate> preds = []> { 7995 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7996 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7997 7998 let Predicates = preds in { 7999 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 8000 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 8001 } 8002} 8003 8004let mayRaiseFPException = 1, Uses = [FPCR] in 8005multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 8006 let Predicates = [HasNEONandIsStreamingSafe] in { 8007 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 8008 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 8009 } 8010 let Predicates = [HasNEONandIsStreamingSafe, HasFullFP16] in { 8011 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 8012 } 8013} 8014 8015let mayRaiseFPException = 1, Uses = [FPCR] in 8016multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 8017 SDPatternOperator OpNode> { 8018 let Predicates = [HasNEONandIsStreamingSafe] in { 8019 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 8020 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 8021 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 8022 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 8023 } 8024 let Predicates = [HasNEONandIsStreamingSafe, HasFullFP16] in { 8025 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 8026 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 8027 } 8028} 8029 8030multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 8031 SDPatternOperator OpNode = null_frag> { 8032 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8033 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 8034 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 8035 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 8036 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 8037 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 8038 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 8039 } 8040 8041 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 8042 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 8043} 8044 8045multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 8046 Intrinsic OpNode> { 8047 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8048 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 8049 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 8050 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 8051 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 8052 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 8053 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 8054 } 8055 8056 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 8057 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 8058} 8059 8060 8061 8062let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8063multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 8064 SDPatternOperator OpNode = null_frag> { 8065 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 8066 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>; 8067 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 8068 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 8069} 8070 8071//---------------------------------------------------------------------------- 8072// AdvSIMD scalar pairwise instructions 8073//---------------------------------------------------------------------------- 8074 8075let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8076class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 8077 RegisterOperand regtype, RegisterOperand vectype, 8078 string asm, string kind> 8079 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 8080 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 8081 Sched<[WriteVd]> { 8082 bits<5> Rd; 8083 bits<5> Rn; 8084 let Inst{31-30} = 0b01; 8085 let Inst{29} = U; 8086 let Inst{28-24} = 0b11110; 8087 let Inst{23-22} = size; 8088 let Inst{21-17} = 0b11000; 8089 let Inst{16-12} = opcode; 8090 let Inst{11-10} = 0b10; 8091 let Inst{9-5} = Rn; 8092 let Inst{4-0} = Rd; 8093} 8094 8095multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 8096 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 8097 asm, ".2d">; 8098} 8099 8100let mayRaiseFPException = 1, Uses = [FPCR] in 8101multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 8102 let Predicates = [HasNEON, HasFullFP16] in { 8103 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 8104 asm, ".2h">; 8105 } 8106 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 8107 asm, ".2s">; 8108 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 8109 asm, ".2d">; 8110} 8111 8112//---------------------------------------------------------------------------- 8113// AdvSIMD across lanes instructions 8114//---------------------------------------------------------------------------- 8115 8116let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8117class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 8118 RegisterClass regtype, RegisterOperand vectype, 8119 string asm, string kind, list<dag> pattern> 8120 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 8121 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 8122 Sched<[!if(Q, WriteVq, WriteVd)]> { 8123 bits<5> Rd; 8124 bits<5> Rn; 8125 let Inst{31} = 0; 8126 let Inst{30} = Q; 8127 let Inst{29} = U; 8128 let Inst{28-24} = 0b01110; 8129 let Inst{23-22} = size; 8130 let Inst{21-17} = 0b11000; 8131 let Inst{16-12} = opcode; 8132 let Inst{11-10} = 0b10; 8133 let Inst{9-5} = Rn; 8134 let Inst{4-0} = Rd; 8135} 8136 8137multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 8138 string asm> { 8139 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 8140 asm, ".8b", []>; 8141 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 8142 asm, ".16b", []>; 8143 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 8144 asm, ".4h", []>; 8145 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 8146 asm, ".8h", []>; 8147 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 8148 asm, ".4s", []>; 8149} 8150 8151multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 8152 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 8153 asm, ".8b", []>; 8154 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 8155 asm, ".16b", []>; 8156 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 8157 asm, ".4h", []>; 8158 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 8159 asm, ".8h", []>; 8160 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 8161 asm, ".4s", []>; 8162} 8163 8164let mayRaiseFPException = 1, Uses = [FPCR] in 8165multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 8166 SDPatternOperator intOp> { 8167 let Predicates = [HasNEON, HasFullFP16] in { 8168 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 8169 asm, ".4h", 8170 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 8171 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 8172 asm, ".8h", 8173 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 8174 } // Predicates = [HasNEON, HasFullFP16] 8175 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 8176 asm, ".4s", 8177 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 8178} 8179 8180//---------------------------------------------------------------------------- 8181// AdvSIMD INS/DUP instructions 8182//---------------------------------------------------------------------------- 8183 8184// FIXME: There has got to be a better way to factor these. ugh. 8185 8186class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 8187 string operands, string constraints, list<dag> pattern> 8188 : I<outs, ins, asm, operands, constraints, pattern>, 8189 Sched<[!if(Q, WriteVq, WriteVd)]> { 8190 bits<5> Rd; 8191 bits<5> Rn; 8192 let Inst{31} = 0; 8193 let Inst{30} = Q; 8194 let Inst{29} = op; 8195 let Inst{28-21} = 0b01110000; 8196 let Inst{15} = 0; 8197 let Inst{10} = 1; 8198 let Inst{9-5} = Rn; 8199 let Inst{4-0} = Rd; 8200} 8201 8202class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 8203 RegisterOperand vecreg, RegisterClass regtype> 8204 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 8205 "{\t$Rd" # size # ", $Rn" # 8206 "|" # size # "\t$Rd, $Rn}", "", 8207 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 8208 let Inst{20-16} = imm5; 8209 let Inst{14-11} = 0b0001; 8210} 8211 8212class SIMDDupFromElement<bit Q, string dstkind, string srckind, 8213 ValueType vectype, ValueType insreg, 8214 RegisterOperand vecreg, Operand idxtype, 8215 SDNode OpNode> 8216 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 8217 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 8218 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 8219 [(set (vectype vecreg:$Rd), 8220 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 8221 let Inst{14-11} = 0b0000; 8222} 8223 8224class SIMDDup64FromElement 8225 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 8226 VectorIndexD, AArch64duplane64> { 8227 bits<1> idx; 8228 let Inst{20} = idx; 8229 let Inst{19-16} = 0b1000; 8230} 8231 8232class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 8233 RegisterOperand vecreg> 8234 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 8235 VectorIndexS, AArch64duplane32> { 8236 bits<2> idx; 8237 let Inst{20-19} = idx; 8238 let Inst{18-16} = 0b100; 8239} 8240 8241class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 8242 RegisterOperand vecreg> 8243 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 8244 VectorIndexH, AArch64duplane16> { 8245 bits<3> idx; 8246 let Inst{20-18} = idx; 8247 let Inst{17-16} = 0b10; 8248} 8249 8250class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 8251 RegisterOperand vecreg> 8252 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 8253 VectorIndexB, AArch64duplane8> { 8254 bits<4> idx; 8255 let Inst{20-17} = idx; 8256 let Inst{16} = 1; 8257} 8258 8259class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 8260 Operand idxtype, string asm, list<dag> pattern> 8261 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 8262 "{\t$Rd, $Rn" # size # "$idx" # 8263 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 8264 let Inst{14-11} = imm4; 8265} 8266 8267class SIMDSMov<bit Q, string size, RegisterClass regtype, 8268 Operand idxtype> 8269 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 8270class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 8271 Operand idxtype> 8272 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 8273 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 8274 8275class SIMDMovAlias<string asm, string size, Instruction inst, 8276 RegisterClass regtype, Operand idxtype> 8277 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 8278 "|" # size # "\t$dst, $src$idx}", 8279 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 8280 8281multiclass SMov { 8282 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 8283 // streaming mode. 8284 let Predicates = [HasNEONandIsStreamingSafe] in { 8285 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 8286 let Inst{20-16} = 0b00001; 8287 } 8288 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 8289 let Inst{20-16} = 0b00001; 8290 } 8291 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 8292 let Inst{20-16} = 0b00010; 8293 } 8294 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 8295 let Inst{20-16} = 0b00010; 8296 } 8297 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 8298 let Inst{20-16} = 0b00100; 8299 } 8300 } 8301 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 8302 bits<4> idx; 8303 let Inst{20-17} = idx; 8304 let Inst{16} = 1; 8305 } 8306 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 8307 bits<4> idx; 8308 let Inst{20-17} = idx; 8309 let Inst{16} = 1; 8310 } 8311 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 8312 bits<3> idx; 8313 let Inst{20-18} = idx; 8314 let Inst{17-16} = 0b10; 8315 } 8316 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 8317 bits<3> idx; 8318 let Inst{20-18} = idx; 8319 let Inst{17-16} = 0b10; 8320 } 8321 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 8322 bits<2> idx; 8323 let Inst{20-19} = idx; 8324 let Inst{18-16} = 0b100; 8325 } 8326} 8327 8328multiclass UMov { 8329 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 8330 // streaming mode. 8331 let Predicates = [HasNEONandIsStreamingSafe] in { 8332 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 8333 let Inst{20-16} = 0b00001; 8334 } 8335 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 8336 let Inst{20-16} = 0b00010; 8337 } 8338 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 8339 let Inst{20-16} = 0b00100; 8340 } 8341 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 8342 let Inst{20-16} = 0b01000; 8343 } 8344 def : SIMDMovAlias<"mov", ".s", 8345 !cast<Instruction>(NAME # vi32_idx0), 8346 GPR32, VectorIndex0>; 8347 def : SIMDMovAlias<"mov", ".d", 8348 !cast<Instruction>(NAME # vi64_idx0), 8349 GPR64, VectorIndex0>; 8350 } 8351 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 8352 bits<4> idx; 8353 let Inst{20-17} = idx; 8354 let Inst{16} = 1; 8355 } 8356 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 8357 bits<3> idx; 8358 let Inst{20-18} = idx; 8359 let Inst{17-16} = 0b10; 8360 } 8361 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 8362 bits<2> idx; 8363 let Inst{20-19} = idx; 8364 let Inst{18-16} = 0b100; 8365 } 8366 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 8367 bits<1> idx; 8368 let Inst{20} = idx; 8369 let Inst{19-16} = 0b1000; 8370 } 8371 def : SIMDMovAlias<"mov", ".s", 8372 !cast<Instruction>(NAME#"vi32"), 8373 GPR32, VectorIndexS>; 8374 def : SIMDMovAlias<"mov", ".d", 8375 !cast<Instruction>(NAME#"vi64"), 8376 GPR64, VectorIndexD>; 8377} 8378 8379class SIMDInsFromMain<string size, ValueType vectype, 8380 RegisterClass regtype, Operand idxtype> 8381 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 8382 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 8383 "{\t$Rd" # size # "$idx, $Rn" # 8384 "|" # size # "\t$Rd$idx, $Rn}", 8385 "$Rd = $dst", 8386 [(set V128:$dst, 8387 (vector_insert (vectype V128:$Rd), regtype:$Rn, (i64 idxtype:$idx)))]> { 8388 let Inst{14-11} = 0b0011; 8389} 8390 8391class SIMDInsFromElement<string size, ValueType vectype, 8392 ValueType elttype, Operand idxtype> 8393 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 8394 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 8395 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 8396 "|" # size # "\t$Rd$idx, $Rn$idx2}", 8397 "$Rd = $dst", 8398 [(set V128:$dst, 8399 (vector_insert 8400 (vectype V128:$Rd), 8401 (elttype (vector_extract (vectype V128:$Rn), (i64 idxtype:$idx2))), 8402 (i64 idxtype:$idx)))]>; 8403 8404class SIMDInsMainMovAlias<string size, Instruction inst, 8405 RegisterClass regtype, Operand idxtype> 8406 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 8407 "|" # size #"\t$dst$idx, $src}", 8408 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 8409class SIMDInsElementMovAlias<string size, Instruction inst, 8410 Operand idxtype> 8411 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 8412 # "|" # size #"\t$dst$idx, $src$idx2}", 8413 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 8414 8415 8416multiclass SIMDIns { 8417 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 8418 bits<4> idx; 8419 let Inst{20-17} = idx; 8420 let Inst{16} = 1; 8421 } 8422 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 8423 bits<3> idx; 8424 let Inst{20-18} = idx; 8425 let Inst{17-16} = 0b10; 8426 } 8427 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 8428 bits<2> idx; 8429 let Inst{20-19} = idx; 8430 let Inst{18-16} = 0b100; 8431 } 8432 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 8433 bits<1> idx; 8434 let Inst{20} = idx; 8435 let Inst{19-16} = 0b1000; 8436 } 8437 8438 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 8439 bits<4> idx; 8440 bits<4> idx2; 8441 let Inst{20-17} = idx; 8442 let Inst{16} = 1; 8443 let Inst{14-11} = idx2; 8444 } 8445 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 8446 bits<3> idx; 8447 bits<3> idx2; 8448 let Inst{20-18} = idx; 8449 let Inst{17-16} = 0b10; 8450 let Inst{14-12} = idx2; 8451 let Inst{11} = {?}; 8452 } 8453 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 8454 bits<2> idx; 8455 bits<2> idx2; 8456 let Inst{20-19} = idx; 8457 let Inst{18-16} = 0b100; 8458 let Inst{14-13} = idx2; 8459 let Inst{12-11} = {?,?}; 8460 } 8461 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 8462 bits<1> idx; 8463 bits<1> idx2; 8464 let Inst{20} = idx; 8465 let Inst{19-16} = 0b1000; 8466 let Inst{14} = idx2; 8467 let Inst{13-11} = {?,?,?}; 8468 } 8469 8470 // For all forms of the INS instruction, the "mov" mnemonic is the 8471 // preferred alias. Why they didn't just call the instruction "mov" in 8472 // the first place is a very good question indeed... 8473 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 8474 GPR32, VectorIndexB>; 8475 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 8476 GPR32, VectorIndexH>; 8477 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 8478 GPR32, VectorIndexS>; 8479 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 8480 GPR64, VectorIndexD>; 8481 8482 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 8483 VectorIndexB>; 8484 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 8485 VectorIndexH>; 8486 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 8487 VectorIndexS>; 8488 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 8489 VectorIndexD>; 8490} 8491 8492//---------------------------------------------------------------------------- 8493// AdvSIMD TBL/TBX 8494//---------------------------------------------------------------------------- 8495 8496let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8497class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8498 RegisterOperand listtype, string asm, string kind> 8499 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 8500 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 8501 Sched<[!if(Q, WriteVq, WriteVd)]> { 8502 bits<5> Vd; 8503 bits<5> Vn; 8504 bits<5> Vm; 8505 let Inst{31} = 0; 8506 let Inst{30} = Q; 8507 let Inst{29-21} = 0b001110000; 8508 let Inst{20-16} = Vm; 8509 let Inst{15} = 0; 8510 let Inst{14-13} = len; 8511 let Inst{12} = op; 8512 let Inst{11-10} = 0b00; 8513 let Inst{9-5} = Vn; 8514 let Inst{4-0} = Vd; 8515} 8516 8517let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8518class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8519 RegisterOperand listtype, string asm, string kind> 8520 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 8521 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 8522 Sched<[!if(Q, WriteVq, WriteVd)]> { 8523 bits<5> Vd; 8524 bits<5> Vn; 8525 bits<5> Vm; 8526 let Inst{31} = 0; 8527 let Inst{30} = Q; 8528 let Inst{29-21} = 0b001110000; 8529 let Inst{20-16} = Vm; 8530 let Inst{15} = 0; 8531 let Inst{14-13} = len; 8532 let Inst{12} = op; 8533 let Inst{11-10} = 0b00; 8534 let Inst{9-5} = Vn; 8535 let Inst{4-0} = Vd; 8536} 8537 8538class SIMDTableLookupAlias<string asm, Instruction inst, 8539 RegisterOperand vectype, RegisterOperand listtype> 8540 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 8541 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 8542 8543multiclass SIMDTableLookup<bit op, string asm> { 8544 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 8545 asm, ".8b">; 8546 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 8547 asm, ".8b">; 8548 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 8549 asm, ".8b">; 8550 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 8551 asm, ".8b">; 8552 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 8553 asm, ".16b">; 8554 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 8555 asm, ".16b">; 8556 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 8557 asm, ".16b">; 8558 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 8559 asm, ".16b">; 8560 8561 def : SIMDTableLookupAlias<asm # ".8b", 8562 !cast<Instruction>(NAME#"v8i8One"), 8563 V64, VecListOneConsecutive128>; 8564 def : SIMDTableLookupAlias<asm # ".8b", 8565 !cast<Instruction>(NAME#"v8i8Two"), 8566 V64, VecListTwoConsecutive128>; 8567 def : SIMDTableLookupAlias<asm # ".8b", 8568 !cast<Instruction>(NAME#"v8i8Three"), 8569 V64, VecListThreeConsecutive128>; 8570 def : SIMDTableLookupAlias<asm # ".8b", 8571 !cast<Instruction>(NAME#"v8i8Four"), 8572 V64, VecListFourConsecutive128>; 8573 def : SIMDTableLookupAlias<asm # ".16b", 8574 !cast<Instruction>(NAME#"v16i8One"), 8575 V128, VecListOneConsecutive128>; 8576 def : SIMDTableLookupAlias<asm # ".16b", 8577 !cast<Instruction>(NAME#"v16i8Two"), 8578 V128, VecListTwoConsecutive128>; 8579 def : SIMDTableLookupAlias<asm # ".16b", 8580 !cast<Instruction>(NAME#"v16i8Three"), 8581 V128, VecListThreeConsecutive128>; 8582 def : SIMDTableLookupAlias<asm # ".16b", 8583 !cast<Instruction>(NAME#"v16i8Four"), 8584 V128, VecListFourConsecutive128>; 8585} 8586 8587multiclass SIMDTableLookupTied<bit op, string asm> { 8588 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 8589 asm, ".8b">; 8590 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 8591 asm, ".8b">; 8592 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 8593 asm, ".8b">; 8594 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 8595 asm, ".8b">; 8596 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 8597 asm, ".16b">; 8598 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 8599 asm, ".16b">; 8600 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 8601 asm, ".16b">; 8602 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 8603 asm, ".16b">; 8604 8605 def : SIMDTableLookupAlias<asm # ".8b", 8606 !cast<Instruction>(NAME#"v8i8One"), 8607 V64, VecListOneConsecutive128>; 8608 def : SIMDTableLookupAlias<asm # ".8b", 8609 !cast<Instruction>(NAME#"v8i8Two"), 8610 V64, VecListTwoConsecutive128>; 8611 def : SIMDTableLookupAlias<asm # ".8b", 8612 !cast<Instruction>(NAME#"v8i8Three"), 8613 V64, VecListThreeConsecutive128>; 8614 def : SIMDTableLookupAlias<asm # ".8b", 8615 !cast<Instruction>(NAME#"v8i8Four"), 8616 V64, VecListFourConsecutive128>; 8617 def : SIMDTableLookupAlias<asm # ".16b", 8618 !cast<Instruction>(NAME#"v16i8One"), 8619 V128, VecListOneConsecutive128>; 8620 def : SIMDTableLookupAlias<asm # ".16b", 8621 !cast<Instruction>(NAME#"v16i8Two"), 8622 V128, VecListTwoConsecutive128>; 8623 def : SIMDTableLookupAlias<asm # ".16b", 8624 !cast<Instruction>(NAME#"v16i8Three"), 8625 V128, VecListThreeConsecutive128>; 8626 def : SIMDTableLookupAlias<asm # ".16b", 8627 !cast<Instruction>(NAME#"v16i8Four"), 8628 V128, VecListFourConsecutive128>; 8629} 8630 8631//---------------------------------------------------------------------------- 8632// AdvSIMD LUT 8633//---------------------------------------------------------------------------- 8634let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8635class BaseSIMDTableLookupIndexed<bit Q, bits<5> opc, 8636 RegisterOperand listtype, Operand idx_type, 8637 string asm, string kind> 8638 : I<(outs V128:$Rd), 8639 (ins listtype:$Rn, V128:$Rm, idx_type:$idx), 8640 asm, "\t$Rd" # kind # ", $Rn, $Rm$idx", "", []>, 8641 Sched<[]> { 8642 bits<5> Rd; 8643 bits<5> Rn; 8644 bits<5> Rm; 8645 let Inst{31} = 0; 8646 let Inst{30} = Q; 8647 let Inst{29-24} = 0b001110; 8648 let Inst{23-22} = opc{4-3}; 8649 let Inst{21} = 0; 8650 let Inst{20-16} = Rm; 8651 let Inst{15} = 0; 8652 let Inst{14-12} = opc{2-0}; 8653 let Inst{11-10} = 0b00; 8654 let Inst{9-5} = Rn; 8655 let Inst{4-0} = Rd; 8656} 8657 8658multiclass BaseSIMDTableLookupIndexed2<string asm> { 8659 def _B : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, VecListOne16b, VectorIndexS32b_timm, asm, ".16b"> { 8660 bits<2> idx; 8661 let Inst{14-13} = idx; 8662 } 8663 def _H : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, VecListOne8h, VectorIndexH32b_timm, asm, ".8h" > { 8664 bits<3> idx; 8665 let Inst{14-12} = idx; 8666 } 8667} 8668 8669multiclass BaseSIMDTableLookupIndexed4<string asm> { 8670 def _B : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, VecListOne16b, VectorIndexD32b_timm, asm, ".16b"> { 8671 bit idx; 8672 let Inst{14} = idx; 8673 } 8674 def _H : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, VecListTwo8h, VectorIndexS32b_timm, asm, ".8h" > { 8675 bits<2> idx; 8676 let Inst{14-13} = idx; 8677 } 8678} 8679 8680//---------------------------------------------------------------------------- 8681// AdvSIMD scalar DUP 8682//---------------------------------------------------------------------------- 8683let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8684class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 8685 string asm, string kind, Operand idxtype> 8686 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 8687 "{\t$dst, $src" # kind # "$idx" # 8688 "|\t$dst, $src$idx}", "", []>, 8689 Sched<[WriteVd]> { 8690 bits<5> dst; 8691 bits<5> src; 8692 let Inst{31-21} = 0b01011110000; 8693 let Inst{15-10} = 0b000001; 8694 let Inst{9-5} = src; 8695 let Inst{4-0} = dst; 8696} 8697 8698class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 8699 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 8700 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 8701 # "|\t$dst, $src$index}", 8702 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 8703 8704 8705multiclass SIMDScalarDUP<string asm> { 8706 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 8707 bits<4> idx; 8708 let Inst{20-17} = idx; 8709 let Inst{16} = 1; 8710 } 8711 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 8712 bits<3> idx; 8713 let Inst{20-18} = idx; 8714 let Inst{17-16} = 0b10; 8715 } 8716 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 8717 bits<2> idx; 8718 let Inst{20-19} = idx; 8719 let Inst{18-16} = 0b100; 8720 } 8721 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 8722 bits<1> idx; 8723 let Inst{20} = idx; 8724 let Inst{19-16} = 0b1000; 8725 } 8726 8727 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 8728 VectorIndexD:$idx)))), 8729 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 8730 8731 // 'DUP' mnemonic aliases. 8732 def : SIMDScalarDUPAlias<"dup", ".b", 8733 !cast<Instruction>(NAME#"i8"), 8734 FPR8, V128, VectorIndexB>; 8735 def : SIMDScalarDUPAlias<"dup", ".h", 8736 !cast<Instruction>(NAME#"i16"), 8737 FPR16, V128, VectorIndexH>; 8738 def : SIMDScalarDUPAlias<"dup", ".s", 8739 !cast<Instruction>(NAME#"i32"), 8740 FPR32, V128, VectorIndexS>; 8741 def : SIMDScalarDUPAlias<"dup", ".d", 8742 !cast<Instruction>(NAME#"i64"), 8743 FPR64, V128, VectorIndexD>; 8744} 8745 8746//---------------------------------------------------------------------------- 8747// AdvSIMD modified immediate instructions 8748//---------------------------------------------------------------------------- 8749 8750class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 8751 string asm, string op_string, 8752 string cstr, list<dag> pattern> 8753 : I<oops, iops, asm, op_string, cstr, pattern>, 8754 Sched<[!if(Q, WriteVq, WriteVd)]> { 8755 bits<5> Rd; 8756 bits<8> imm8; 8757 let Inst{31} = 0; 8758 let Inst{30} = Q; 8759 let Inst{29} = op; 8760 let Inst{28-19} = 0b0111100000; 8761 let Inst{18-16} = imm8{7-5}; 8762 let Inst{11} = op2; 8763 let Inst{10} = 1; 8764 let Inst{9-5} = imm8{4-0}; 8765 let Inst{4-0} = Rd; 8766} 8767 8768class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 8769 Operand immtype, dag opt_shift_iop, 8770 string opt_shift, string asm, string kind, 8771 list<dag> pattern> 8772 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 8773 !con((ins immtype:$imm8), opt_shift_iop), asm, 8774 "{\t$Rd" # kind # ", $imm8" # opt_shift # 8775 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8776 "", pattern> { 8777 let DecoderMethod = "DecodeModImmInstruction"; 8778} 8779 8780class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 8781 Operand immtype, dag opt_shift_iop, 8782 string opt_shift, string asm, string kind, 8783 list<dag> pattern> 8784 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 8785 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 8786 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 8787 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8788 "$Rd = $dst", pattern> { 8789 let DecoderMethod = "DecodeModImmTiedInstruction"; 8790} 8791 8792class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 8793 RegisterOperand vectype, string asm, 8794 string kind, list<dag> pattern> 8795 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8796 (ins logical_vec_shift:$shift), 8797 "$shift", asm, kind, pattern> { 8798 bits<2> shift; 8799 let Inst{15} = b15_b12{1}; 8800 let Inst{14-13} = shift; 8801 let Inst{12} = b15_b12{0}; 8802} 8803 8804class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 8805 RegisterOperand vectype, string asm, 8806 string kind, list<dag> pattern> 8807 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8808 (ins logical_vec_shift:$shift), 8809 "$shift", asm, kind, pattern> { 8810 bits<2> shift; 8811 let Inst{15} = b15_b12{1}; 8812 let Inst{14-13} = shift; 8813 let Inst{12} = b15_b12{0}; 8814} 8815 8816 8817class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 8818 RegisterOperand vectype, string asm, 8819 string kind, list<dag> pattern> 8820 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8821 (ins logical_vec_hw_shift:$shift), 8822 "$shift", asm, kind, pattern> { 8823 bits<2> shift; 8824 let Inst{15} = b15_b12{1}; 8825 let Inst{14} = 0; 8826 let Inst{13} = shift{0}; 8827 let Inst{12} = b15_b12{0}; 8828} 8829 8830class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 8831 RegisterOperand vectype, string asm, 8832 string kind, list<dag> pattern> 8833 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8834 (ins logical_vec_hw_shift:$shift), 8835 "$shift", asm, kind, pattern> { 8836 bits<2> shift; 8837 let Inst{15} = b15_b12{1}; 8838 let Inst{14} = 0; 8839 let Inst{13} = shift{0}; 8840 let Inst{12} = b15_b12{0}; 8841} 8842 8843multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 8844 string asm> { 8845 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 8846 asm, ".4h", []>; 8847 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 8848 asm, ".8h", []>; 8849 8850 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 8851 asm, ".2s", []>; 8852 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 8853 asm, ".4s", []>; 8854} 8855 8856multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 8857 bits<2> w_cmode, string asm, 8858 SDNode OpNode> { 8859 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 8860 asm, ".4h", 8861 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 8862 imm0_255:$imm8, 8863 (i32 imm:$shift)))]>; 8864 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 8865 asm, ".8h", 8866 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 8867 imm0_255:$imm8, 8868 (i32 imm:$shift)))]>; 8869 8870 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 8871 asm, ".2s", 8872 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 8873 imm0_255:$imm8, 8874 (i32 imm:$shift)))]>; 8875 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 8876 asm, ".4s", 8877 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 8878 imm0_255:$imm8, 8879 (i32 imm:$shift)))]>; 8880} 8881 8882class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 8883 RegisterOperand vectype, string asm, 8884 string kind, list<dag> pattern> 8885 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8886 (ins move_vec_shift:$shift), 8887 "$shift", asm, kind, pattern> { 8888 bits<1> shift; 8889 let Inst{15-13} = cmode{3-1}; 8890 let Inst{12} = shift; 8891} 8892 8893class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 8894 RegisterOperand vectype, 8895 Operand imm_type, string asm, 8896 string kind, list<dag> pattern> 8897 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 8898 asm, kind, pattern> { 8899 let Inst{15-12} = cmode; 8900} 8901 8902class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 8903 list<dag> pattern> 8904 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 8905 "\t$Rd, $imm8", "", pattern> { 8906 let Inst{15-12} = cmode; 8907 let DecoderMethod = "DecodeModImmInstruction"; 8908} 8909 8910//---------------------------------------------------------------------------- 8911// AdvSIMD indexed element 8912//---------------------------------------------------------------------------- 8913 8914let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8915class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8916 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8917 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8918 string apple_kind, string dst_kind, string lhs_kind, 8919 string rhs_kind, list<dag> pattern> 8920 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8921 asm, 8922 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8923 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8924 Sched<[WriteVd]> { 8925 bits<5> Rd; 8926 bits<5> Rn; 8927 bits<5> Rm; 8928 8929 let Inst{31} = 0; 8930 let Inst{30} = Q; 8931 let Inst{29} = U; 8932 let Inst{28} = Scalar; 8933 let Inst{27-24} = 0b1111; 8934 let Inst{23-22} = size; 8935 // Bit 21 must be set by the derived class. 8936 let Inst{20-16} = Rm; 8937 let Inst{15-12} = opc; 8938 // Bit 11 must be set by the derived class. 8939 let Inst{10} = 0; 8940 let Inst{9-5} = Rn; 8941 let Inst{4-0} = Rd; 8942} 8943 8944let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8945class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8946 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8947 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8948 string apple_kind, string dst_kind, string lhs_kind, 8949 string rhs_kind, list<dag> pattern> 8950 : I<(outs dst_reg:$dst), 8951 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8952 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8953 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8954 Sched<[WriteVd]> { 8955 bits<5> Rd; 8956 bits<5> Rn; 8957 bits<5> Rm; 8958 8959 let Inst{31} = 0; 8960 let Inst{30} = Q; 8961 let Inst{29} = U; 8962 let Inst{28} = Scalar; 8963 let Inst{27-24} = 0b1111; 8964 let Inst{23-22} = size; 8965 // Bit 21 must be set by the derived class. 8966 let Inst{20-16} = Rm; 8967 let Inst{15-12} = opc; 8968 // Bit 11 must be set by the derived class. 8969 let Inst{10} = 0; 8970 let Inst{9-5} = Rn; 8971 let Inst{4-0} = Rd; 8972} 8973 8974 8975//---------------------------------------------------------------------------- 8976// Armv8.6 BFloat16 Extension 8977//---------------------------------------------------------------------------- 8978let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8979 8980class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8981 string kind2, RegisterOperand RegType, 8982 ValueType AccumType, ValueType InputType> 8983 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8984 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8985 (InputType RegType:$Rn), 8986 (InputType RegType:$Rm)))]> { 8987 let AsmString = !strconcat(asm, 8988 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8989 ", $Rm" # kind2 # "}"); 8990} 8991 8992multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8993 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8994 v2f32, v4bf16>; 8995 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8996 v4f32, v8bf16>; 8997} 8998 8999class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 9000 string dst_kind, string lhs_kind, 9001 string rhs_kind, 9002 RegisterOperand RegType, 9003 ValueType AccumType, 9004 ValueType InputType> 9005 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 9006 RegType, RegType, V128, VectorIndexS, 9007 asm, "", dst_kind, lhs_kind, rhs_kind, 9008 [(set (AccumType RegType:$dst), 9009 (AccumType (int_aarch64_neon_bfdot 9010 (AccumType RegType:$Rd), 9011 (InputType RegType:$Rn), 9012 (InputType (bitconvert (AccumType 9013 (AArch64duplane32 (v4f32 V128:$Rm), 9014 VectorIndexS:$idx)))))))]> { 9015 9016 bits<2> idx; 9017 let Inst{21} = idx{0}; // L 9018 let Inst{11} = idx{1}; // H 9019} 9020 9021multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 9022 9023 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 9024 ".2h", V64, v2f32, v4bf16>; 9025 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 9026 ".2h", V128, v4f32, v8bf16>; 9027} 9028 9029let mayRaiseFPException = 1, Uses = [FPCR] in 9030class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 9031 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 9032 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 9033 (v8bf16 V128:$Rn), 9034 (v8bf16 V128:$Rm)))]> { 9035 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 9036} 9037 9038let mayRaiseFPException = 1, Uses = [FPCR] in 9039class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 9040 : I<(outs V128:$dst), 9041 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 9042 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 9043 [(set (v4f32 V128:$dst), 9044 (v4f32 (OpNode (v4f32 V128:$Rd), 9045 (v8bf16 V128:$Rn), 9046 (v8bf16 9047 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 9048 VectorIndexH:$idx)))))]>, 9049 Sched<[WriteVq]> { 9050 bits<5> Rd; 9051 bits<5> Rn; 9052 bits<4> Rm; 9053 bits<3> idx; 9054 9055 let Inst{31} = 0; 9056 let Inst{30} = Q; 9057 let Inst{29-22} = 0b00111111; 9058 let Inst{21-20} = idx{1-0}; 9059 let Inst{19-16} = Rm; 9060 let Inst{15-12} = 0b1111; 9061 let Inst{11} = idx{2}; // H 9062 let Inst{10} = 0; 9063 let Inst{9-5} = Rn; 9064 let Inst{4-0} = Rd; 9065} 9066 9067class SIMDThreeSameVectorBF16MatrixMul<string asm> 9068 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 9069 V128, asm, ".4s", 9070 [(set (v4f32 V128:$dst), 9071 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 9072 (v8bf16 V128:$Rn), 9073 (v8bf16 V128:$Rm)))]> { 9074 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 9075 ", $Rm", ".8h", "}"); 9076} 9077 9078let mayRaiseFPException = 1, Uses = [FPCR] in 9079class SIMD_BFCVTN 9080 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V64, 9081 "bfcvtn", ".4h", ".4s", 9082 [(set (v4bf16 V64:$Rd), (any_fpround (v4f32 V128:$Rn)))]>; 9083 9084let mayRaiseFPException = 1, Uses = [FPCR] in 9085class SIMD_BFCVTN2 9086 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 9087 "bfcvtn2", ".8h", ".4s", []>; 9088 9089let mayRaiseFPException = 1, Uses = [FPCR] in 9090class BF16ToSinglePrecision<string asm> 9091 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 9092 [(set (bf16 FPR16:$Rd), (any_fpround (f32 FPR32:$Rn)))]>, 9093 Sched<[WriteFCvt]> { 9094 bits<5> Rd; 9095 bits<5> Rn; 9096 let Inst{31-10} = 0b0001111001100011010000; 9097 let Inst{9-5} = Rn; 9098 let Inst{4-0} = Rd; 9099} 9100} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 9101 9102//---------------------------------------------------------------------------- 9103class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc, 9104 string asm, string dst_kind, 9105 RegisterOperand RegType, 9106 RegisterOperand RegType_lo> 9107 : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc, 9108 RegType, RegType, RegType_lo, VectorIndexB32b_timm, 9109 asm, "", dst_kind, ".16b", ".b", []> { 9110 9111 // idx = H:L:M 9112 bits<4> idx; 9113 let Inst{11} = idx{3}; 9114 let Inst{21-19} = idx{2-0}; 9115} 9116 9117multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm, SDPatternOperator op> { 9118 let Uses = [FPMR, FPCR], mayLoad = 1 in { 9119 def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h", 9120 V128, V128_0to7>; 9121 } 9122 9123 def : Pat<(v8f16 (op (v8f16 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128_0to7:$Rm), VectorIndexB32b_timm:$Idx)), 9124 (!cast<Instruction>(NAME # v8f16) $Rd, $Rn, $Rm, $Idx)>; 9125} 9126 9127multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm, SDPatternOperator op> { 9128 let Uses = [FPMR, FPCR], mayLoad = 1 in { 9129 def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s", 9130 V128, V128_0to7>; 9131 } 9132 9133 def : Pat<(v4f32 (op (v4f32 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128_0to7:$Rm), VectorIndexB32b_timm:$Idx)), 9134 (!cast<Instruction>(NAME # v4f32) $Rd, $Rn, $Rm, $Idx)>; 9135} 9136 9137//---------------------------------------------------------------------------- 9138// Armv8.6 Matrix Multiply Extension 9139//---------------------------------------------------------------------------- 9140 9141class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 9142 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 9143 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 9144 (v16i8 V128:$Rn), 9145 (v16i8 V128:$Rm)))]> { 9146 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 9147} 9148 9149//---------------------------------------------------------------------------- 9150// ARMv8.2-A Dot Product Instructions (Indexed) 9151class BaseSIMDThreeSameVectorIndexS<bit Q, bit U, bits<2> size, bits<4> opc, string asm, 9152 string dst_kind, string lhs_kind, string rhs_kind, 9153 RegisterOperand RegType, 9154 ValueType AccumType, ValueType InputType, 9155 AsmVectorIndexOpnd VIdx, 9156 SDPatternOperator OpNode> : 9157 BaseSIMDIndexedTied<Q, U, 0b0, size, opc, RegType, RegType, V128, 9158 VIdx, asm, "", dst_kind, lhs_kind, rhs_kind, 9159 [(set (AccumType RegType:$dst), 9160 (AccumType (OpNode (AccumType RegType:$Rd), 9161 (InputType RegType:$Rn), 9162 (InputType (bitconvert (AccumType 9163 (AArch64duplane32 (v4i32 V128:$Rm), 9164 VIdx:$idx)))))))]> { 9165 bits<2> idx; 9166 let Inst{21} = idx{0}; // L 9167 let Inst{11} = idx{1}; // H 9168} 9169 9170multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 9171 SDPatternOperator OpNode> { 9172 def v8i8 : BaseSIMDThreeSameVectorIndexS<0, U, size, {0b111, Mixed}, asm, ".2s", ".8b", ".4b", 9173 V64, v2i32, v8i8, VectorIndexS, OpNode>; 9174 def v16i8 : BaseSIMDThreeSameVectorIndexS<1, U, size, {0b111, Mixed}, asm, ".4s", ".16b", ".4b", 9175 V128, v4i32, v16i8, VectorIndexS, OpNode>; 9176} 9177 9178multiclass SIMD_FP8_Dot4_Index<string asm, SDPatternOperator op> { 9179 let Uses = [FPMR, FPCR], mayLoad = 1 in { 9180 def v2f32 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b00, 0b0000, asm, ".2s", ".8b", ".4b", 9181 V64, v2f32, v8i8, VectorIndexS32b_timm, null_frag>; 9182 def v4f32 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b00, 0b0000, asm, ".4s", ".16b",".4b", 9183 V128, v4f32, v16i8, VectorIndexS32b_timm, null_frag>; 9184 } 9185 9186 def : Pat<(v2f32 (op (v2f32 V64:$Rd), (v8i8 V64:$Rn), (v16i8 V128:$Rm), VectorIndexS32b_timm:$Idx)), 9187 (!cast<Instruction>(NAME # v2f32) $Rd, $Rn, $Rm, $Idx)>; 9188 9189 def : Pat<(v4f32 (op (v4f32 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm), VectorIndexS32b_timm:$Idx)), 9190 (!cast<Instruction>(NAME # v4f32) $Rd, $Rn, $Rm, $Idx)>; 9191} 9192 9193// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 9194let mayRaiseFPException = 1, Uses = [FPCR] in 9195class BaseSIMDThreeSameVectorIndexH<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 9196 string dst_kind, string lhs_kind, 9197 string rhs_kind, RegisterOperand RegType, 9198 RegisterOperand RegType_lo, ValueType AccumType, 9199 ValueType InputType, AsmVectorIndexOpnd VIdx, 9200 SDPatternOperator OpNode> : 9201 BaseSIMDIndexedTied<Q, U, 0, sz, opc, RegType, RegType, RegType_lo, 9202 VIdx, asm, "", dst_kind, lhs_kind, rhs_kind, 9203 [(set (AccumType RegType:$dst), 9204 (AccumType (OpNode (AccumType RegType:$Rd), 9205 (InputType RegType:$Rn), 9206 (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm), 9207 VIdx:$idx)))))]> { 9208 // idx = H:L:M 9209 bits<3> idx; 9210 let Inst{11} = idx{2}; // H 9211 let Inst{21} = idx{1}; // L 9212 let Inst{20} = idx{0}; // M 9213} 9214 9215multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 9216 SDPatternOperator OpNode> { 9217 def v4f16 : BaseSIMDThreeSameVectorIndexH<0, U, 0b10, opc, asm, ".2s", ".2h", ".h", 9218 V64, V128_lo, v2f32, v4f16, VectorIndexH, OpNode>; 9219 def v8f16 : BaseSIMDThreeSameVectorIndexH<1, U, 0b10, opc, asm, ".4s", ".4h", ".h", 9220 V128, V128_lo, v4f32, v8f16, VectorIndexH, OpNode>; 9221} 9222 9223//---------------------------------------------------------------------------- 9224// FP8 Advanced SIMD vector x indexed element 9225multiclass SIMD_FP8_Dot2_Index<string asm, SDPatternOperator op> { 9226 let Uses = [FPMR, FPCR], mayLoad = 1 in { 9227 def v4f16 : BaseSIMDThreeSameVectorIndexH<0b0, 0b0, 0b01, 0b0000, asm, ".4h", ".8b", ".2b", 9228 V64, V128_lo, v4f16, v8i8, VectorIndexH32b_timm, null_frag>; 9229 def v8f16 : BaseSIMDThreeSameVectorIndexH<0b1, 0b0, 0b01, 0b0000, asm, ".8h", ".16b", ".2b", 9230 V128, V128_lo, v8f16, v16i8, VectorIndexH32b_timm, null_frag>; 9231 } 9232 def : Pat<(v4f16 (op (v4f16 V64:$Rd), (v8i8 V64:$Rn), (v16i8 V128_lo:$Rm), VectorIndexH32b_timm:$Idx)), 9233 (!cast<Instruction>(NAME # v4f16) $Rd, $Rn, $Rm, $Idx)>; 9234 9235 def : Pat<(v8f16 (op (v8f16 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128_lo:$Rm), VectorIndexH32b_timm:$Idx)), 9236 (!cast<Instruction>(NAME # v8f16) $Rd, $Rn, $Rm, $Idx)>; 9237} 9238 9239multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 9240 SDPatternOperator OpNode> { 9241 let mayRaiseFPException = 1, Uses = [FPCR] in { 9242 let Predicates = [HasNEON, HasFullFP16] in { 9243 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 9244 V64, V64, 9245 V128_lo, VectorIndexH, 9246 asm, ".4h", ".4h", ".4h", ".h", 9247 [(set (v4f16 V64:$Rd), 9248 (OpNode (v4f16 V64:$Rn), 9249 (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9250 bits<3> idx; 9251 let Inst{11} = idx{2}; 9252 let Inst{21} = idx{1}; 9253 let Inst{20} = idx{0}; 9254 } 9255 9256 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 9257 V128, V128, 9258 V128_lo, VectorIndexH, 9259 asm, ".8h", ".8h", ".8h", ".h", 9260 [(set (v8f16 V128:$Rd), 9261 (OpNode (v8f16 V128:$Rn), 9262 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9263 bits<3> idx; 9264 let Inst{11} = idx{2}; 9265 let Inst{21} = idx{1}; 9266 let Inst{20} = idx{0}; 9267 } 9268 } // Predicates = [HasNEON, HasFullFP16] 9269 9270 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9271 V64, V64, 9272 V128, VectorIndexS, 9273 asm, ".2s", ".2s", ".2s", ".s", 9274 [(set (v2f32 V64:$Rd), 9275 (OpNode (v2f32 V64:$Rn), 9276 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> { 9277 bits<2> idx; 9278 let Inst{11} = idx{1}; 9279 let Inst{21} = idx{0}; 9280 } 9281 9282 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9283 V128, V128, 9284 V128, VectorIndexS, 9285 asm, ".4s", ".4s", ".4s", ".s", 9286 [(set (v4f32 V128:$Rd), 9287 (OpNode (v4f32 V128:$Rn), 9288 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 9289 bits<2> idx; 9290 let Inst{11} = idx{1}; 9291 let Inst{21} = idx{0}; 9292 } 9293 9294 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 9295 V128, V128, 9296 V128, VectorIndexD, 9297 asm, ".2d", ".2d", ".2d", ".d", 9298 [(set (v2f64 V128:$Rd), 9299 (OpNode (v2f64 V128:$Rn), 9300 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 9301 bits<1> idx; 9302 let Inst{11} = idx{0}; 9303 let Inst{21} = 0; 9304 } 9305 9306 let Predicates = [HasNEON, HasFullFP16] in { 9307 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 9308 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9309 asm, ".h", "", "", ".h", 9310 [(set (f16 FPR16Op:$Rd), 9311 (OpNode (f16 FPR16Op:$Rn), 9312 (f16 (vector_extract (v8f16 V128_lo:$Rm), 9313 VectorIndexH:$idx))))]> { 9314 bits<3> idx; 9315 let Inst{11} = idx{2}; 9316 let Inst{21} = idx{1}; 9317 let Inst{20} = idx{0}; 9318 } 9319 } // Predicates = [HasNEON, HasFullFP16] 9320 9321 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9322 FPR32Op, FPR32Op, V128, VectorIndexS, 9323 asm, ".s", "", "", ".s", 9324 [(set (f32 FPR32Op:$Rd), 9325 (OpNode (f32 FPR32Op:$Rn), 9326 (f32 (vector_extract (v4f32 V128:$Rm), 9327 VectorIndexS:$idx))))]> { 9328 bits<2> idx; 9329 let Inst{11} = idx{1}; 9330 let Inst{21} = idx{0}; 9331 } 9332 9333 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 9334 FPR64Op, FPR64Op, V128, VectorIndexD, 9335 asm, ".d", "", "", ".d", 9336 [(set (f64 FPR64Op:$Rd), 9337 (OpNode (f64 FPR64Op:$Rn), 9338 (f64 (vector_extract (v2f64 V128:$Rm), 9339 VectorIndexD:$idx))))]> { 9340 bits<1> idx; 9341 let Inst{11} = idx{0}; 9342 let Inst{21} = 0; 9343 } 9344 } // mayRaiseFPException = 1, Uses = [FPCR] 9345 9346 let Predicates = [HasNEON, HasFullFP16] in { 9347 def : Pat<(f16 (OpNode 9348 (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))), 9349 (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))), 9350 (!cast<Instruction>(NAME # v1i16_indexed) 9351 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128:$Rm, VectorIndexH:$idx)>; 9352 } 9353 9354 let Predicates = [HasNEON] in { 9355 def : Pat<(f32 (OpNode 9356 (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))), 9357 (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))), 9358 (!cast<Instruction>(NAME # v1i32_indexed) 9359 (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>; 9360 9361 def : Pat<(f64 (OpNode 9362 (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))), 9363 (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))), 9364 (!cast<Instruction>(NAME # v1i64_indexed) 9365 (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>; 9366 } 9367} 9368 9369multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 9370 let Predicates = [HasNEON, HasFullFP16] in { 9371 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 9372 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 9373 (AArch64duplane16 (v8f16 V128_lo:$Rm), 9374 VectorIndexH:$idx))), 9375 (!cast<Instruction>(INST # "v8i16_indexed") 9376 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 9377 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 9378 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 9379 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 9380 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 9381 9382 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 9383 (AArch64duplane16 (v8f16 V128_lo:$Rm), 9384 VectorIndexH:$idx))), 9385 (!cast<Instruction>(INST # "v4i16_indexed") 9386 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 9387 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 9388 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 9389 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 9390 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 9391 9392 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 9393 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 9394 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 9395 V128_lo:$Rm, VectorIndexH:$idx)>; 9396 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), 9397 (vector_extract (v8f16 V128:$Rn), (i64 0)), 9398 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 9399 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, 9400 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128_lo:$Rm, VectorIndexH:$idx)>; 9401 } // Predicates = [HasNEON, HasFullFP16] 9402 9403 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 9404 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 9405 (AArch64duplane32 (v4f32 V128:$Rm), 9406 VectorIndexS:$idx))), 9407 (!cast<Instruction>(INST # v2i32_indexed) 9408 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 9409 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 9410 (AArch64dup (f32 FPR32Op:$Rm)))), 9411 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 9412 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 9413 9414 9415 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 9416 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 9417 (AArch64duplane32 (v4f32 V128:$Rm), 9418 VectorIndexS:$idx))), 9419 (!cast<Instruction>(INST # "v4i32_indexed") 9420 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 9421 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 9422 (AArch64dup (f32 FPR32Op:$Rm)))), 9423 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 9424 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 9425 9426 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 9427 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 9428 (AArch64duplane64 (v2f64 V128:$Rm), 9429 VectorIndexD:$idx))), 9430 (!cast<Instruction>(INST # "v2i64_indexed") 9431 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 9432 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 9433 (AArch64dup (f64 FPR64Op:$Rm)))), 9434 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 9435 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 9436 9437 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 9438 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 9439 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 9440 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 9441 V128:$Rm, VectorIndexS:$idx)>; 9442 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), 9443 (vector_extract (v4f32 V128:$Rn), (i64 0)), 9444 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 9445 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, 9446 (f32 (EXTRACT_SUBREG V128:$Rn, ssub)), V128:$Rm, VectorIndexS:$idx)>; 9447 9448 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 9449 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 9450 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 9451 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 9452 V128:$Rm, VectorIndexD:$idx)>; 9453 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), 9454 (vector_extract (v2f64 V128:$Rn), (i64 0)), 9455 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 9456 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, 9457 (f64 (EXTRACT_SUBREG V128:$Rn, dsub)), V128:$Rm, VectorIndexD:$idx)>; 9458} 9459 9460let mayRaiseFPException = 1, Uses = [FPCR] in 9461multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 9462 let Predicates = [HasNEON, HasFullFP16] in { 9463 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 9464 V128_lo, VectorIndexH, 9465 asm, ".4h", ".4h", ".4h", ".h", []> { 9466 bits<3> idx; 9467 let Inst{11} = idx{2}; 9468 let Inst{21} = idx{1}; 9469 let Inst{20} = idx{0}; 9470 } 9471 9472 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 9473 V128, V128, 9474 V128_lo, VectorIndexH, 9475 asm, ".8h", ".8h", ".8h", ".h", []> { 9476 bits<3> idx; 9477 let Inst{11} = idx{2}; 9478 let Inst{21} = idx{1}; 9479 let Inst{20} = idx{0}; 9480 } 9481 } // Predicates = [HasNEON, HasFullFP16] 9482 9483 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 9484 V128, VectorIndexS, 9485 asm, ".2s", ".2s", ".2s", ".s", []> { 9486 bits<2> idx; 9487 let Inst{11} = idx{1}; 9488 let Inst{21} = idx{0}; 9489 } 9490 9491 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9492 V128, V128, 9493 V128, VectorIndexS, 9494 asm, ".4s", ".4s", ".4s", ".s", []> { 9495 bits<2> idx; 9496 let Inst{11} = idx{1}; 9497 let Inst{21} = idx{0}; 9498 } 9499 9500 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 9501 V128, V128, 9502 V128, VectorIndexD, 9503 asm, ".2d", ".2d", ".2d", ".d", []> { 9504 bits<1> idx; 9505 let Inst{11} = idx{0}; 9506 let Inst{21} = 0; 9507 } 9508 9509 let Predicates = [HasNEON, HasFullFP16] in { 9510 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 9511 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9512 asm, ".h", "", "", ".h", []> { 9513 bits<3> idx; 9514 let Inst{11} = idx{2}; 9515 let Inst{21} = idx{1}; 9516 let Inst{20} = idx{0}; 9517 } 9518 } // Predicates = [HasNEON, HasFullFP16] 9519 9520 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9521 FPR32Op, FPR32Op, V128, VectorIndexS, 9522 asm, ".s", "", "", ".s", []> { 9523 bits<2> idx; 9524 let Inst{11} = idx{1}; 9525 let Inst{21} = idx{0}; 9526 } 9527 9528 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 9529 FPR64Op, FPR64Op, V128, VectorIndexD, 9530 asm, ".d", "", "", ".d", []> { 9531 bits<1> idx; 9532 let Inst{11} = idx{0}; 9533 let Inst{21} = 0; 9534 } 9535} 9536 9537multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 9538 SDPatternOperator OpNodeLaneQ> { 9539 9540 def : Pat<(v4i16 (OpNodeLane 9541 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 9542 VectorIndexS32b:$idx)), 9543 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 9544 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 9545 (UImmS1XForm $idx))>; 9546 9547 def : Pat<(v4i16 (OpNodeLaneQ 9548 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 9549 VectorIndexH32b:$idx)), 9550 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 9551 (UImmS1XForm $idx))>; 9552 9553 def : Pat<(v8i16 (OpNodeLane 9554 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 9555 VectorIndexS32b:$idx)), 9556 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 9557 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9558 (UImmS1XForm $idx))>; 9559 9560 def : Pat<(v8i16 (OpNodeLaneQ 9561 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 9562 VectorIndexH32b:$idx)), 9563 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 9564 (UImmS1XForm $idx))>; 9565 9566 def : Pat<(v2i32 (OpNodeLane 9567 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 9568 VectorIndexD32b:$idx)), 9569 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 9570 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 9571 (UImmS1XForm $idx))>; 9572 9573 def : Pat<(v2i32 (OpNodeLaneQ 9574 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 9575 VectorIndexS32b:$idx)), 9576 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 9577 (UImmS1XForm $idx))>; 9578 9579 def : Pat<(v4i32 (OpNodeLane 9580 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 9581 VectorIndexD32b:$idx)), 9582 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 9583 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9584 (UImmS1XForm $idx))>; 9585 9586 def : Pat<(v4i32 (OpNodeLaneQ 9587 (v4i32 V128:$Rn), 9588 (v4i32 V128:$Rm), 9589 VectorIndexS32b:$idx)), 9590 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 9591 (UImmS1XForm $idx))>; 9592 9593} 9594 9595multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 9596 SDPatternOperator OpNode> { 9597 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 9598 V128_lo, VectorIndexH, 9599 asm, ".4h", ".4h", ".4h", ".h", 9600 [(set (v4i16 V64:$Rd), 9601 (OpNode (v4i16 V64:$Rn), 9602 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9603 bits<3> idx; 9604 let Inst{11} = idx{2}; 9605 let Inst{21} = idx{1}; 9606 let Inst{20} = idx{0}; 9607 } 9608 9609 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9610 V128, V128, 9611 V128_lo, VectorIndexH, 9612 asm, ".8h", ".8h", ".8h", ".h", 9613 [(set (v8i16 V128:$Rd), 9614 (OpNode (v8i16 V128:$Rn), 9615 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9616 bits<3> idx; 9617 let Inst{11} = idx{2}; 9618 let Inst{21} = idx{1}; 9619 let Inst{20} = idx{0}; 9620 } 9621 9622 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9623 V64, V64, 9624 V128, VectorIndexS, 9625 asm, ".2s", ".2s", ".2s", ".s", 9626 [(set (v2i32 V64:$Rd), 9627 (OpNode (v2i32 V64:$Rn), 9628 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9629 bits<2> idx; 9630 let Inst{11} = idx{1}; 9631 let Inst{21} = idx{0}; 9632 } 9633 9634 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9635 V128, V128, 9636 V128, VectorIndexS, 9637 asm, ".4s", ".4s", ".4s", ".s", 9638 [(set (v4i32 V128:$Rd), 9639 (OpNode (v4i32 V128:$Rn), 9640 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9641 bits<2> idx; 9642 let Inst{11} = idx{1}; 9643 let Inst{21} = idx{0}; 9644 } 9645 9646 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9647 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9648 asm, ".h", "", "", ".h", []> { 9649 bits<3> idx; 9650 let Inst{11} = idx{2}; 9651 let Inst{21} = idx{1}; 9652 let Inst{20} = idx{0}; 9653 } 9654 9655 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9656 FPR32Op, FPR32Op, V128, VectorIndexS, 9657 asm, ".s", "", "", ".s", 9658 [(set (i32 FPR32Op:$Rd), 9659 (OpNode FPR32Op:$Rn, 9660 (i32 (vector_extract (v4i32 V128:$Rm), 9661 VectorIndexS:$idx))))]> { 9662 bits<2> idx; 9663 let Inst{11} = idx{1}; 9664 let Inst{21} = idx{0}; 9665 } 9666} 9667 9668multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 9669 SDPatternOperator OpNode> { 9670 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9671 V64, V64, 9672 V128_lo, VectorIndexH, 9673 asm, ".4h", ".4h", ".4h", ".h", 9674 [(set (v4i16 V64:$Rd), 9675 (OpNode (v4i16 V64:$Rn), 9676 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9677 bits<3> idx; 9678 let Inst{11} = idx{2}; 9679 let Inst{21} = idx{1}; 9680 let Inst{20} = idx{0}; 9681 } 9682 9683 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9684 V128, V128, 9685 V128_lo, VectorIndexH, 9686 asm, ".8h", ".8h", ".8h", ".h", 9687 [(set (v8i16 V128:$Rd), 9688 (OpNode (v8i16 V128:$Rn), 9689 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9690 bits<3> idx; 9691 let Inst{11} = idx{2}; 9692 let Inst{21} = idx{1}; 9693 let Inst{20} = idx{0}; 9694 } 9695 9696 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9697 V64, V64, 9698 V128, VectorIndexS, 9699 asm, ".2s", ".2s", ".2s", ".s", 9700 [(set (v2i32 V64:$Rd), 9701 (OpNode (v2i32 V64:$Rn), 9702 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9703 bits<2> idx; 9704 let Inst{11} = idx{1}; 9705 let Inst{21} = idx{0}; 9706 } 9707 9708 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9709 V128, V128, 9710 V128, VectorIndexS, 9711 asm, ".4s", ".4s", ".4s", ".s", 9712 [(set (v4i32 V128:$Rd), 9713 (OpNode (v4i32 V128:$Rn), 9714 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9715 bits<2> idx; 9716 let Inst{11} = idx{1}; 9717 let Inst{21} = idx{0}; 9718 } 9719} 9720 9721multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 9722 SDPatternOperator OpNode> { 9723 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 9724 V128_lo, VectorIndexH, 9725 asm, ".4h", ".4h", ".4h", ".h", 9726 [(set (v4i16 V64:$dst), 9727 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 9728 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9729 bits<3> idx; 9730 let Inst{11} = idx{2}; 9731 let Inst{21} = idx{1}; 9732 let Inst{20} = idx{0}; 9733 } 9734 9735 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9736 V128, V128, 9737 V128_lo, VectorIndexH, 9738 asm, ".8h", ".8h", ".8h", ".h", 9739 [(set (v8i16 V128:$dst), 9740 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9741 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9742 bits<3> idx; 9743 let Inst{11} = idx{2}; 9744 let Inst{21} = idx{1}; 9745 let Inst{20} = idx{0}; 9746 } 9747 9748 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9749 V64, V64, 9750 V128, VectorIndexS, 9751 asm, ".2s", ".2s", ".2s", ".s", 9752 [(set (v2i32 V64:$dst), 9753 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9754 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9755 bits<2> idx; 9756 let Inst{11} = idx{1}; 9757 let Inst{21} = idx{0}; 9758 } 9759 9760 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9761 V128, V128, 9762 V128, VectorIndexS, 9763 asm, ".4s", ".4s", ".4s", ".s", 9764 [(set (v4i32 V128:$dst), 9765 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9766 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9767 bits<2> idx; 9768 let Inst{11} = idx{1}; 9769 let Inst{21} = idx{0}; 9770 } 9771} 9772 9773multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 9774 SDPatternOperator OpNode> { 9775 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9776 V128, V64, 9777 V128_lo, VectorIndexH, 9778 asm, ".4s", ".4s", ".4h", ".h", 9779 [(set (v4i32 V128:$Rd), 9780 (OpNode (v4i16 V64:$Rn), 9781 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9782 bits<3> idx; 9783 let Inst{11} = idx{2}; 9784 let Inst{21} = idx{1}; 9785 let Inst{20} = idx{0}; 9786 } 9787 9788 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9789 V128, V128, 9790 V128_lo, VectorIndexH, 9791 asm#"2", ".4s", ".4s", ".8h", ".h", 9792 [(set (v4i32 V128:$Rd), 9793 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9794 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9795 9796 bits<3> idx; 9797 let Inst{11} = idx{2}; 9798 let Inst{21} = idx{1}; 9799 let Inst{20} = idx{0}; 9800 } 9801 9802 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9803 V128, V64, 9804 V128, VectorIndexS, 9805 asm, ".2d", ".2d", ".2s", ".s", 9806 [(set (v2i64 V128:$Rd), 9807 (OpNode (v2i32 V64:$Rn), 9808 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9809 bits<2> idx; 9810 let Inst{11} = idx{1}; 9811 let Inst{21} = idx{0}; 9812 } 9813 9814 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9815 V128, V128, 9816 V128, VectorIndexS, 9817 asm#"2", ".2d", ".2d", ".4s", ".s", 9818 [(set (v2i64 V128:$Rd), 9819 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9820 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9821 bits<2> idx; 9822 let Inst{11} = idx{1}; 9823 let Inst{21} = idx{0}; 9824 } 9825 9826 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9827 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9828 asm, ".h", "", "", ".h", []> { 9829 bits<3> idx; 9830 let Inst{11} = idx{2}; 9831 let Inst{21} = idx{1}; 9832 let Inst{20} = idx{0}; 9833 } 9834 9835 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9836 FPR64Op, FPR32Op, V128, VectorIndexS, 9837 asm, ".s", "", "", ".s", []> { 9838 bits<2> idx; 9839 let Inst{11} = idx{1}; 9840 let Inst{21} = idx{0}; 9841 } 9842} 9843 9844multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 9845 SDPatternOperator Accum> { 9846 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9847 V128, V64, 9848 V128_lo, VectorIndexH, 9849 asm, ".4s", ".4s", ".4h", ".h", 9850 [(set (v4i32 V128:$dst), 9851 (Accum (v4i32 V128:$Rd), 9852 (v4i32 (int_aarch64_neon_sqdmull 9853 (v4i16 V64:$Rn), 9854 (dup_v8i16 (v8i16 V128_lo:$Rm), 9855 VectorIndexH:$idx)))))]> { 9856 bits<3> idx; 9857 let Inst{11} = idx{2}; 9858 let Inst{21} = idx{1}; 9859 let Inst{20} = idx{0}; 9860 } 9861 9862 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9863 V128, V128, 9864 V128_lo, VectorIndexH, 9865 asm#"2", ".4s", ".4s", ".8h", ".h", 9866 [(set (v4i32 V128:$dst), 9867 (Accum (v4i32 V128:$Rd), 9868 (v4i32 (int_aarch64_neon_sqdmull 9869 (extract_high_v8i16 (v8i16 V128:$Rn)), 9870 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 9871 bits<3> idx; 9872 let Inst{11} = idx{2}; 9873 let Inst{21} = idx{1}; 9874 let Inst{20} = idx{0}; 9875 } 9876 9877 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9878 V128, V64, 9879 V128, VectorIndexS, 9880 asm, ".2d", ".2d", ".2s", ".s", 9881 [(set (v2i64 V128:$dst), 9882 (Accum (v2i64 V128:$Rd), 9883 (v2i64 (int_aarch64_neon_sqdmull 9884 (v2i32 V64:$Rn), 9885 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9886 bits<2> idx; 9887 let Inst{11} = idx{1}; 9888 let Inst{21} = idx{0}; 9889 } 9890 9891 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9892 V128, V128, 9893 V128, VectorIndexS, 9894 asm#"2", ".2d", ".2d", ".4s", ".s", 9895 [(set (v2i64 V128:$dst), 9896 (Accum (v2i64 V128:$Rd), 9897 (v2i64 (int_aarch64_neon_sqdmull 9898 (extract_high_v4i32 (v4i32 V128:$Rn)), 9899 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9900 bits<2> idx; 9901 let Inst{11} = idx{1}; 9902 let Inst{21} = idx{0}; 9903 } 9904 9905 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9906 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9907 asm, ".h", "", "", ".h", []> { 9908 bits<3> idx; 9909 let Inst{11} = idx{2}; 9910 let Inst{21} = idx{1}; 9911 let Inst{20} = idx{0}; 9912 } 9913 9914 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9915 (i32 (vector_extract 9916 (v4i32 (int_aarch64_neon_sqdmull 9917 (v4i16 V64:$Rn), 9918 (v4i16 V64:$Rm))), 9919 (i64 0))))), 9920 (!cast<Instruction>(NAME # v1i32_indexed) 9921 FPR32Op:$Rd, 9922 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9923 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub), 9924 (i64 0))>; 9925 9926 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9927 (i32 (vector_extract 9928 (v4i32 (int_aarch64_neon_sqdmull 9929 (v4i16 V64:$Rn), 9930 (dup_v8i16 (v8i16 V128_lo:$Rm), 9931 VectorIndexH:$idx))), 9932 (i64 0))))), 9933 (!cast<Instruction>(NAME # v1i32_indexed) 9934 FPR32Op:$Rd, 9935 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9936 V128_lo:$Rm, 9937 VectorIndexH:$idx)>; 9938 9939 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9940 FPR64Op, FPR32Op, V128, VectorIndexS, 9941 asm, ".s", "", "", ".s", 9942 [(set (i64 FPR64Op:$dst), 9943 (Accum (i64 FPR64Op:$Rd), 9944 (i64 (int_aarch64_neon_sqdmulls_scalar 9945 (i32 FPR32Op:$Rn), 9946 (i32 (vector_extract (v4i32 V128:$Rm), 9947 VectorIndexS:$idx))))))]> { 9948 9949 bits<2> idx; 9950 let Inst{11} = idx{1}; 9951 let Inst{21} = idx{0}; 9952 } 9953} 9954 9955multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 9956 SDPatternOperator OpNode> { 9957 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9958 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9959 V128, V64, 9960 V128_lo, VectorIndexH, 9961 asm, ".4s", ".4s", ".4h", ".h", 9962 [(set (v4i32 V128:$Rd), 9963 (OpNode (v4i16 V64:$Rn), 9964 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9965 bits<3> idx; 9966 let Inst{11} = idx{2}; 9967 let Inst{21} = idx{1}; 9968 let Inst{20} = idx{0}; 9969 } 9970 9971 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9972 V128, V128, 9973 V128_lo, VectorIndexH, 9974 asm#"2", ".4s", ".4s", ".8h", ".h", 9975 [(set (v4i32 V128:$Rd), 9976 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9977 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9978 9979 bits<3> idx; 9980 let Inst{11} = idx{2}; 9981 let Inst{21} = idx{1}; 9982 let Inst{20} = idx{0}; 9983 } 9984 9985 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9986 V128, V64, 9987 V128, VectorIndexS, 9988 asm, ".2d", ".2d", ".2s", ".s", 9989 [(set (v2i64 V128:$Rd), 9990 (OpNode (v2i32 V64:$Rn), 9991 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9992 bits<2> idx; 9993 let Inst{11} = idx{1}; 9994 let Inst{21} = idx{0}; 9995 } 9996 9997 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9998 V128, V128, 9999 V128, VectorIndexS, 10000 asm#"2", ".2d", ".2d", ".4s", ".s", 10001 [(set (v2i64 V128:$Rd), 10002 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 10003 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 10004 bits<2> idx; 10005 let Inst{11} = idx{1}; 10006 let Inst{21} = idx{0}; 10007 } 10008 } 10009} 10010 10011multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 10012 SDPatternOperator OpNode> { 10013 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 10014 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10015 V128, V64, 10016 V128_lo, VectorIndexH, 10017 asm, ".4s", ".4s", ".4h", ".h", 10018 [(set (v4i32 V128:$dst), 10019 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 10020 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 10021 bits<3> idx; 10022 let Inst{11} = idx{2}; 10023 let Inst{21} = idx{1}; 10024 let Inst{20} = idx{0}; 10025 } 10026 10027 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10028 V128, V128, 10029 V128_lo, VectorIndexH, 10030 asm#"2", ".4s", ".4s", ".8h", ".h", 10031 [(set (v4i32 V128:$dst), 10032 (OpNode (v4i32 V128:$Rd), 10033 (extract_high_v8i16 (v8i16 V128:$Rn)), 10034 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 10035 bits<3> idx; 10036 let Inst{11} = idx{2}; 10037 let Inst{21} = idx{1}; 10038 let Inst{20} = idx{0}; 10039 } 10040 10041 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10042 V128, V64, 10043 V128, VectorIndexS, 10044 asm, ".2d", ".2d", ".2s", ".s", 10045 [(set (v2i64 V128:$dst), 10046 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 10047 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 10048 bits<2> idx; 10049 let Inst{11} = idx{1}; 10050 let Inst{21} = idx{0}; 10051 } 10052 10053 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10054 V128, V128, 10055 V128, VectorIndexS, 10056 asm#"2", ".2d", ".2d", ".4s", ".s", 10057 [(set (v2i64 V128:$dst), 10058 (OpNode (v2i64 V128:$Rd), 10059 (extract_high_v4i32 (v4i32 V128:$Rn)), 10060 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 10061 bits<2> idx; 10062 let Inst{11} = idx{1}; 10063 let Inst{21} = idx{0}; 10064 } 10065 } 10066} 10067 10068//---------------------------------------------------------------------------- 10069// AdvSIMD scalar shift by immediate 10070//---------------------------------------------------------------------------- 10071 10072let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 10073class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 10074 RegisterClass regtype1, RegisterClass regtype2, 10075 Operand immtype, string asm, list<dag> pattern> 10076 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 10077 asm, "\t$Rd, $Rn, $imm", "", pattern>, 10078 Sched<[WriteVd]> { 10079 bits<5> Rd; 10080 bits<5> Rn; 10081 bits<7> imm; 10082 let Inst{31-30} = 0b01; 10083 let Inst{29} = U; 10084 let Inst{28-23} = 0b111110; 10085 let Inst{22-16} = fixed_imm; 10086 let Inst{15-11} = opc; 10087 let Inst{10} = 1; 10088 let Inst{9-5} = Rn; 10089 let Inst{4-0} = Rd; 10090} 10091 10092let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 10093class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 10094 RegisterClass regtype1, RegisterClass regtype2, 10095 Operand immtype, string asm, list<dag> pattern> 10096 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 10097 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 10098 Sched<[WriteVd]> { 10099 bits<5> Rd; 10100 bits<5> Rn; 10101 bits<7> imm; 10102 let Inst{31-30} = 0b01; 10103 let Inst{29} = U; 10104 let Inst{28-23} = 0b111110; 10105 let Inst{22-16} = fixed_imm; 10106 let Inst{15-11} = opc; 10107 let Inst{10} = 1; 10108 let Inst{9-5} = Rn; 10109 let Inst{4-0} = Rd; 10110} 10111 10112 10113multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 10114 let Predicates = [HasNEON, HasFullFP16] in { 10115 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 10116 FPR16, FPR16, vecshiftR16, asm, []> { 10117 let Inst{19-16} = imm{3-0}; 10118 } 10119 } // Predicates = [HasNEON, HasFullFP16] 10120 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 10121 FPR32, FPR32, vecshiftR32, asm, []> { 10122 let Inst{20-16} = imm{4-0}; 10123 } 10124 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 10125 FPR64, FPR64, vecshiftR64, asm, []> { 10126 let Inst{21-16} = imm{5-0}; 10127 } 10128} 10129 10130multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 10131 SDPatternOperator OpNode> { 10132 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 10133 FPR64, FPR64, vecshiftR64, asm, 10134 [(set (i64 FPR64:$Rd), 10135 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 10136 let Inst{21-16} = imm{5-0}; 10137 } 10138 10139 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 10140 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 10141} 10142 10143multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 10144 SDPatternOperator OpNode = null_frag> { 10145 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 10146 FPR64, FPR64, vecshiftR64, asm, 10147 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 10148 (i32 vecshiftR64:$imm)))]> { 10149 let Inst{21-16} = imm{5-0}; 10150 } 10151 10152 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 10153 (i32 vecshiftR64:$imm))), 10154 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 10155 vecshiftR64:$imm)>; 10156} 10157 10158multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 10159 SDPatternOperator OpNode> { 10160 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 10161 FPR64, FPR64, vecshiftL64, asm, 10162 [(set (i64 FPR64:$Rd), 10163 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 10164 let Inst{21-16} = imm{5-0}; 10165 } 10166 10167 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 10168 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 10169} 10170 10171let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 10172multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 10173 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 10174 FPR64, FPR64, vecshiftL64, asm, []> { 10175 let Inst{21-16} = imm{5-0}; 10176 } 10177} 10178 10179let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 10180multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 10181 SDPatternOperator OpNode = null_frag> { 10182 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 10183 FPR8, FPR16, vecshiftR8, asm, []> { 10184 let Inst{18-16} = imm{2-0}; 10185 } 10186 10187 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 10188 FPR16, FPR32, vecshiftR16, asm, []> { 10189 let Inst{19-16} = imm{3-0}; 10190 } 10191 10192 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 10193 FPR32, FPR64, vecshiftR32, asm, 10194 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 10195 let Inst{20-16} = imm{4-0}; 10196 } 10197} 10198 10199multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 10200 SDPatternOperator OpNode> { 10201 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 10202 FPR8, FPR8, vecshiftL8, asm, []> { 10203 let Inst{18-16} = imm{2-0}; 10204 } 10205 10206 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 10207 FPR16, FPR16, vecshiftL16, asm, []> { 10208 let Inst{19-16} = imm{3-0}; 10209 } 10210 10211 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 10212 FPR32, FPR32, vecshiftL32, asm, 10213 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 10214 let Inst{20-16} = imm{4-0}; 10215 } 10216 10217 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 10218 FPR64, FPR64, vecshiftL64, asm, 10219 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 10220 let Inst{21-16} = imm{5-0}; 10221 } 10222 10223 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 10224 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 10225} 10226 10227multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 10228 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 10229 FPR8, FPR8, vecshiftR8, asm, []> { 10230 let Inst{18-16} = imm{2-0}; 10231 } 10232 10233 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 10234 FPR16, FPR16, vecshiftR16, asm, []> { 10235 let Inst{19-16} = imm{3-0}; 10236 } 10237 10238 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 10239 FPR32, FPR32, vecshiftR32, asm, []> { 10240 let Inst{20-16} = imm{4-0}; 10241 } 10242 10243 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 10244 FPR64, FPR64, vecshiftR64, asm, []> { 10245 let Inst{21-16} = imm{5-0}; 10246 } 10247} 10248 10249//---------------------------------------------------------------------------- 10250// AdvSIMD vector x indexed element 10251//---------------------------------------------------------------------------- 10252 10253let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 10254class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 10255 RegisterOperand dst_reg, RegisterOperand src_reg, 10256 Operand immtype, 10257 string asm, string dst_kind, string src_kind, 10258 list<dag> pattern> 10259 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 10260 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 10261 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 10262 Sched<[!if(Q, WriteVq, WriteVd)]> { 10263 bits<5> Rd; 10264 bits<5> Rn; 10265 let Inst{31} = 0; 10266 let Inst{30} = Q; 10267 let Inst{29} = U; 10268 let Inst{28-23} = 0b011110; 10269 let Inst{22-16} = fixed_imm; 10270 let Inst{15-11} = opc; 10271 let Inst{10} = 1; 10272 let Inst{9-5} = Rn; 10273 let Inst{4-0} = Rd; 10274} 10275 10276let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 10277class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 10278 RegisterOperand vectype1, RegisterOperand vectype2, 10279 Operand immtype, 10280 string asm, string dst_kind, string src_kind, 10281 list<dag> pattern> 10282 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 10283 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 10284 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 10285 Sched<[!if(Q, WriteVq, WriteVd)]> { 10286 bits<5> Rd; 10287 bits<5> Rn; 10288 let Inst{31} = 0; 10289 let Inst{30} = Q; 10290 let Inst{29} = U; 10291 let Inst{28-23} = 0b011110; 10292 let Inst{22-16} = fixed_imm; 10293 let Inst{15-11} = opc; 10294 let Inst{10} = 1; 10295 let Inst{9-5} = Rn; 10296 let Inst{4-0} = Rd; 10297} 10298 10299multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 10300 Intrinsic OpNode> { 10301 let Predicates = [HasNEON, HasFullFP16] in { 10302 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10303 V64, V64, vecshiftR16, 10304 asm, ".4h", ".4h", 10305 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 10306 bits<4> imm; 10307 let Inst{19-16} = imm; 10308 } 10309 10310 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10311 V128, V128, vecshiftR16, 10312 asm, ".8h", ".8h", 10313 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 10314 bits<4> imm; 10315 let Inst{19-16} = imm; 10316 } 10317 } // Predicates = [HasNEON, HasFullFP16] 10318 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10319 V64, V64, vecshiftR32, 10320 asm, ".2s", ".2s", 10321 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 10322 bits<5> imm; 10323 let Inst{20-16} = imm; 10324 } 10325 10326 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10327 V128, V128, vecshiftR32, 10328 asm, ".4s", ".4s", 10329 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 10330 bits<5> imm; 10331 let Inst{20-16} = imm; 10332 } 10333 10334 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10335 V128, V128, vecshiftR64, 10336 asm, ".2d", ".2d", 10337 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 10338 bits<6> imm; 10339 let Inst{21-16} = imm; 10340 } 10341} 10342 10343multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 10344 Intrinsic OpNode> { 10345 let Predicates = [HasNEON, HasFullFP16] in { 10346 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10347 V64, V64, vecshiftR16, 10348 asm, ".4h", ".4h", 10349 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 10350 bits<4> imm; 10351 let Inst{19-16} = imm; 10352 } 10353 10354 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10355 V128, V128, vecshiftR16, 10356 asm, ".8h", ".8h", 10357 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 10358 bits<4> imm; 10359 let Inst{19-16} = imm; 10360 } 10361 } // Predicates = [HasNEON, HasFullFP16] 10362 10363 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10364 V64, V64, vecshiftR32, 10365 asm, ".2s", ".2s", 10366 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 10367 bits<5> imm; 10368 let Inst{20-16} = imm; 10369 } 10370 10371 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10372 V128, V128, vecshiftR32, 10373 asm, ".4s", ".4s", 10374 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 10375 bits<5> imm; 10376 let Inst{20-16} = imm; 10377 } 10378 10379 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10380 V128, V128, vecshiftR64, 10381 asm, ".2d", ".2d", 10382 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 10383 bits<6> imm; 10384 let Inst{21-16} = imm; 10385 } 10386} 10387 10388multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 10389 SDPatternOperator OpNode> { 10390 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10391 V64, V128, vecshiftR16Narrow, 10392 asm, ".8b", ".8h", 10393 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 10394 bits<3> imm; 10395 let Inst{18-16} = imm; 10396 } 10397 10398 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10399 V128, V128, vecshiftR16Narrow, 10400 asm#"2", ".16b", ".8h", []> { 10401 bits<3> imm; 10402 let Inst{18-16} = imm; 10403 let hasSideEffects = 0; 10404 } 10405 10406 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10407 V64, V128, vecshiftR32Narrow, 10408 asm, ".4h", ".4s", 10409 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 10410 bits<4> imm; 10411 let Inst{19-16} = imm; 10412 } 10413 10414 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10415 V128, V128, vecshiftR32Narrow, 10416 asm#"2", ".8h", ".4s", []> { 10417 bits<4> imm; 10418 let Inst{19-16} = imm; 10419 let hasSideEffects = 0; 10420 } 10421 10422 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10423 V64, V128, vecshiftR64Narrow, 10424 asm, ".2s", ".2d", 10425 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 10426 bits<5> imm; 10427 let Inst{20-16} = imm; 10428 } 10429 10430 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10431 V128, V128, vecshiftR64Narrow, 10432 asm#"2", ".4s", ".2d", []> { 10433 bits<5> imm; 10434 let Inst{20-16} = imm; 10435 let hasSideEffects = 0; 10436 } 10437 10438 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 10439 // themselves, so put them here instead. 10440 10441 // Patterns involving what's effectively an insert high and a normal 10442 // intrinsic, represented by CONCAT_VECTORS. 10443 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 10444 vecshiftR16Narrow:$imm)), 10445 (!cast<Instruction>(NAME # "v16i8_shift") 10446 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10447 V128:$Rn, vecshiftR16Narrow:$imm)>; 10448 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 10449 vecshiftR32Narrow:$imm)), 10450 (!cast<Instruction>(NAME # "v8i16_shift") 10451 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10452 V128:$Rn, vecshiftR32Narrow:$imm)>; 10453 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 10454 vecshiftR64Narrow:$imm)), 10455 (!cast<Instruction>(NAME # "v4i32_shift") 10456 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10457 V128:$Rn, vecshiftR64Narrow:$imm)>; 10458} 10459 10460multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 10461 SDPatternOperator OpNode> { 10462 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10463 V64, V64, vecshiftL8, 10464 asm, ".8b", ".8b", 10465 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10466 (i32 vecshiftL8:$imm)))]> { 10467 bits<3> imm; 10468 let Inst{18-16} = imm; 10469 } 10470 10471 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10472 V128, V128, vecshiftL8, 10473 asm, ".16b", ".16b", 10474 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10475 (i32 vecshiftL8:$imm)))]> { 10476 bits<3> imm; 10477 let Inst{18-16} = imm; 10478 } 10479 10480 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10481 V64, V64, vecshiftL16, 10482 asm, ".4h", ".4h", 10483 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10484 (i32 vecshiftL16:$imm)))]> { 10485 bits<4> imm; 10486 let Inst{19-16} = imm; 10487 } 10488 10489 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10490 V128, V128, vecshiftL16, 10491 asm, ".8h", ".8h", 10492 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10493 (i32 vecshiftL16:$imm)))]> { 10494 bits<4> imm; 10495 let Inst{19-16} = imm; 10496 } 10497 10498 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10499 V64, V64, vecshiftL32, 10500 asm, ".2s", ".2s", 10501 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10502 (i32 vecshiftL32:$imm)))]> { 10503 bits<5> imm; 10504 let Inst{20-16} = imm; 10505 } 10506 10507 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10508 V128, V128, vecshiftL32, 10509 asm, ".4s", ".4s", 10510 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10511 (i32 vecshiftL32:$imm)))]> { 10512 bits<5> imm; 10513 let Inst{20-16} = imm; 10514 } 10515 10516 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10517 V128, V128, vecshiftL64, 10518 asm, ".2d", ".2d", 10519 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10520 (i32 vecshiftL64:$imm)))]> { 10521 bits<6> imm; 10522 let Inst{21-16} = imm; 10523 } 10524} 10525 10526multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 10527 SDPatternOperator OpNode> { 10528 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10529 V64, V64, vecshiftR8, 10530 asm, ".8b", ".8b", 10531 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10532 (i32 vecshiftR8:$imm)))]> { 10533 bits<3> imm; 10534 let Inst{18-16} = imm; 10535 } 10536 10537 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10538 V128, V128, vecshiftR8, 10539 asm, ".16b", ".16b", 10540 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10541 (i32 vecshiftR8:$imm)))]> { 10542 bits<3> imm; 10543 let Inst{18-16} = imm; 10544 } 10545 10546 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10547 V64, V64, vecshiftR16, 10548 asm, ".4h", ".4h", 10549 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10550 (i32 vecshiftR16:$imm)))]> { 10551 bits<4> imm; 10552 let Inst{19-16} = imm; 10553 } 10554 10555 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10556 V128, V128, vecshiftR16, 10557 asm, ".8h", ".8h", 10558 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10559 (i32 vecshiftR16:$imm)))]> { 10560 bits<4> imm; 10561 let Inst{19-16} = imm; 10562 } 10563 10564 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10565 V64, V64, vecshiftR32, 10566 asm, ".2s", ".2s", 10567 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10568 (i32 vecshiftR32:$imm)))]> { 10569 bits<5> imm; 10570 let Inst{20-16} = imm; 10571 } 10572 10573 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10574 V128, V128, vecshiftR32, 10575 asm, ".4s", ".4s", 10576 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10577 (i32 vecshiftR32:$imm)))]> { 10578 bits<5> imm; 10579 let Inst{20-16} = imm; 10580 } 10581 10582 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10583 V128, V128, vecshiftR64, 10584 asm, ".2d", ".2d", 10585 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10586 (i32 vecshiftR64:$imm)))]> { 10587 bits<6> imm; 10588 let Inst{21-16} = imm; 10589 } 10590} 10591 10592let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10593multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 10594 SDPatternOperator OpNode = null_frag> { 10595 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10596 V64, V64, vecshiftR8, asm, ".8b", ".8b", 10597 [(set (v8i8 V64:$dst), 10598 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10599 (i32 vecshiftR8:$imm)))]> { 10600 bits<3> imm; 10601 let Inst{18-16} = imm; 10602 } 10603 10604 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10605 V128, V128, vecshiftR8, asm, ".16b", ".16b", 10606 [(set (v16i8 V128:$dst), 10607 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10608 (i32 vecshiftR8:$imm)))]> { 10609 bits<3> imm; 10610 let Inst{18-16} = imm; 10611 } 10612 10613 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10614 V64, V64, vecshiftR16, asm, ".4h", ".4h", 10615 [(set (v4i16 V64:$dst), 10616 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10617 (i32 vecshiftR16:$imm)))]> { 10618 bits<4> imm; 10619 let Inst{19-16} = imm; 10620 } 10621 10622 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10623 V128, V128, vecshiftR16, asm, ".8h", ".8h", 10624 [(set (v8i16 V128:$dst), 10625 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10626 (i32 vecshiftR16:$imm)))]> { 10627 bits<4> imm; 10628 let Inst{19-16} = imm; 10629 } 10630 10631 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10632 V64, V64, vecshiftR32, asm, ".2s", ".2s", 10633 [(set (v2i32 V64:$dst), 10634 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10635 (i32 vecshiftR32:$imm)))]> { 10636 bits<5> imm; 10637 let Inst{20-16} = imm; 10638 } 10639 10640 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10641 V128, V128, vecshiftR32, asm, ".4s", ".4s", 10642 [(set (v4i32 V128:$dst), 10643 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10644 (i32 vecshiftR32:$imm)))]> { 10645 bits<5> imm; 10646 let Inst{20-16} = imm; 10647 } 10648 10649 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10650 V128, V128, vecshiftR64, 10651 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 10652 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10653 (i32 vecshiftR64:$imm)))]> { 10654 bits<6> imm; 10655 let Inst{21-16} = imm; 10656 } 10657} 10658 10659multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 10660 SDPatternOperator OpNode = null_frag> { 10661 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10662 V64, V64, vecshiftL8, 10663 asm, ".8b", ".8b", 10664 [(set (v8i8 V64:$dst), 10665 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10666 (i32 vecshiftL8:$imm)))]> { 10667 bits<3> imm; 10668 let Inst{18-16} = imm; 10669 } 10670 10671 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10672 V128, V128, vecshiftL8, 10673 asm, ".16b", ".16b", 10674 [(set (v16i8 V128:$dst), 10675 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10676 (i32 vecshiftL8:$imm)))]> { 10677 bits<3> imm; 10678 let Inst{18-16} = imm; 10679 } 10680 10681 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10682 V64, V64, vecshiftL16, 10683 asm, ".4h", ".4h", 10684 [(set (v4i16 V64:$dst), 10685 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10686 (i32 vecshiftL16:$imm)))]> { 10687 bits<4> imm; 10688 let Inst{19-16} = imm; 10689 } 10690 10691 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10692 V128, V128, vecshiftL16, 10693 asm, ".8h", ".8h", 10694 [(set (v8i16 V128:$dst), 10695 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10696 (i32 vecshiftL16:$imm)))]> { 10697 bits<4> imm; 10698 let Inst{19-16} = imm; 10699 } 10700 10701 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10702 V64, V64, vecshiftL32, 10703 asm, ".2s", ".2s", 10704 [(set (v2i32 V64:$dst), 10705 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10706 (i32 vecshiftL32:$imm)))]> { 10707 bits<5> imm; 10708 let Inst{20-16} = imm; 10709 } 10710 10711 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10712 V128, V128, vecshiftL32, 10713 asm, ".4s", ".4s", 10714 [(set (v4i32 V128:$dst), 10715 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10716 (i32 vecshiftL32:$imm)))]> { 10717 bits<5> imm; 10718 let Inst{20-16} = imm; 10719 } 10720 10721 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10722 V128, V128, vecshiftL64, 10723 asm, ".2d", ".2d", 10724 [(set (v2i64 V128:$dst), 10725 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10726 (i32 vecshiftL64:$imm)))]> { 10727 bits<6> imm; 10728 let Inst{21-16} = imm; 10729 } 10730} 10731 10732multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 10733 SDPatternOperator OpNode> { 10734 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10735 V128, V64, vecshiftL8, asm, ".8h", ".8b", 10736 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 10737 bits<3> imm; 10738 let Inst{18-16} = imm; 10739 } 10740 10741 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10742 V128, V128, vecshiftL8, 10743 asm#"2", ".8h", ".16b", 10744 [(set (v8i16 V128:$Rd), 10745 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 10746 bits<3> imm; 10747 let Inst{18-16} = imm; 10748 } 10749 10750 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10751 V128, V64, vecshiftL16, asm, ".4s", ".4h", 10752 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 10753 bits<4> imm; 10754 let Inst{19-16} = imm; 10755 } 10756 10757 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10758 V128, V128, vecshiftL16, 10759 asm#"2", ".4s", ".8h", 10760 [(set (v4i32 V128:$Rd), 10761 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 10762 10763 bits<4> imm; 10764 let Inst{19-16} = imm; 10765 } 10766 10767 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10768 V128, V64, vecshiftL32, asm, ".2d", ".2s", 10769 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 10770 bits<5> imm; 10771 let Inst{20-16} = imm; 10772 } 10773 10774 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10775 V128, V128, vecshiftL32, 10776 asm#"2", ".2d", ".4s", 10777 [(set (v2i64 V128:$Rd), 10778 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 10779 bits<5> imm; 10780 let Inst{20-16} = imm; 10781 } 10782} 10783 10784 10785//--- 10786// Vector load/store 10787//--- 10788// SIMD ldX/stX no-index memory references don't allow the optional 10789// ", #0" constant and handle post-indexing explicitly, so we use 10790// a more specialized parse method for them. Otherwise, it's the same as 10791// the general GPR64sp handling. 10792 10793class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 10794 string asm, dag oops, dag iops, list<dag> pattern> 10795 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 10796 bits<5> Vt; 10797 bits<5> Rn; 10798 let Inst{31} = 0; 10799 let Inst{30} = Q; 10800 let Inst{29-23} = 0b0011000; 10801 let Inst{22} = L; 10802 let Inst{21-16} = 0b000000; 10803 let Inst{15-12} = opcode; 10804 let Inst{11-10} = size; 10805 let Inst{9-5} = Rn; 10806 let Inst{4-0} = Vt; 10807} 10808 10809class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 10810 string asm, dag oops, dag iops> 10811 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 10812 bits<5> Vt; 10813 bits<5> Rn; 10814 bits<5> Xm; 10815 let Inst{31} = 0; 10816 let Inst{30} = Q; 10817 let Inst{29-23} = 0b0011001; 10818 let Inst{22} = L; 10819 let Inst{21} = 0; 10820 let Inst{20-16} = Xm; 10821 let Inst{15-12} = opcode; 10822 let Inst{11-10} = size; 10823 let Inst{9-5} = Rn; 10824 let Inst{4-0} = Vt; 10825} 10826 10827// The immediate form of AdvSIMD post-indexed addressing is encoded with 10828// register post-index addressing from the zero register. 10829multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 10830 int Offset, int Size> { 10831 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 10832 // "ld1\t$Vt, [$Rn], #16" 10833 // may get mapped to 10834 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 10835 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10836 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10837 GPR64sp:$Rn, 10838 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10839 XZR), 1>; 10840 10841 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 10842 // "ld1.8b\t$Vt, [$Rn], #16" 10843 // may get mapped to 10844 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 10845 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10846 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10847 GPR64sp:$Rn, 10848 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10849 XZR), 0>; 10850 10851 // E.g. "ld1.8b { v0, v1 }, [x1]" 10852 // "ld1\t$Vt, [$Rn]" 10853 // may get mapped to 10854 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 10855 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10856 (!cast<Instruction>(BaseName # Count # "v" # layout) 10857 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10858 GPR64sp:$Rn), 0>; 10859 10860 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 10861 // "ld1\t$Vt, [$Rn], $Xm" 10862 // may get mapped to 10863 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 10864 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10865 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10866 GPR64sp:$Rn, 10867 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10868 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10869} 10870 10871multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 10872 int Offset128, int Offset64, bits<4> opcode> { 10873 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10874 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 10875 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 10876 (ins GPR64sp:$Rn), []>; 10877 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 10878 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 10879 (ins GPR64sp:$Rn), []>; 10880 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 10881 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 10882 (ins GPR64sp:$Rn), []>; 10883 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 10884 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 10885 (ins GPR64sp:$Rn), []>; 10886 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 10887 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 10888 (ins GPR64sp:$Rn), []>; 10889 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 10890 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 10891 (ins GPR64sp:$Rn), []>; 10892 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 10893 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 10894 (ins GPR64sp:$Rn), []>; 10895 10896 10897 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 10898 (outs GPR64sp:$wback, 10899 !cast<RegisterOperand>(veclist # "16b"):$Vt), 10900 (ins GPR64sp:$Rn, 10901 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10902 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 10903 (outs GPR64sp:$wback, 10904 !cast<RegisterOperand>(veclist # "8h"):$Vt), 10905 (ins GPR64sp:$Rn, 10906 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10907 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 10908 (outs GPR64sp:$wback, 10909 !cast<RegisterOperand>(veclist # "4s"):$Vt), 10910 (ins GPR64sp:$Rn, 10911 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10912 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 10913 (outs GPR64sp:$wback, 10914 !cast<RegisterOperand>(veclist # "2d"):$Vt), 10915 (ins GPR64sp:$Rn, 10916 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10917 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 10918 (outs GPR64sp:$wback, 10919 !cast<RegisterOperand>(veclist # "8b"):$Vt), 10920 (ins GPR64sp:$Rn, 10921 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10922 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 10923 (outs GPR64sp:$wback, 10924 !cast<RegisterOperand>(veclist # "4h"):$Vt), 10925 (ins GPR64sp:$Rn, 10926 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10927 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 10928 (outs GPR64sp:$wback, 10929 !cast<RegisterOperand>(veclist # "2s"):$Vt), 10930 (ins GPR64sp:$Rn, 10931 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10932 } 10933 10934 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10935 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10936 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10937 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10938 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10939 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10940 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10941} 10942 10943// Only ld1/st1 has a v1d version. 10944multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 10945 int Offset128, int Offset64, bits<4> opcode> { 10946 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 10947 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 10948 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10949 GPR64sp:$Rn), []>; 10950 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 10951 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10952 GPR64sp:$Rn), []>; 10953 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 10954 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10955 GPR64sp:$Rn), []>; 10956 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 10957 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10958 GPR64sp:$Rn), []>; 10959 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 10960 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10961 GPR64sp:$Rn), []>; 10962 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 10963 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10964 GPR64sp:$Rn), []>; 10965 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 10966 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10967 GPR64sp:$Rn), []>; 10968 10969 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 10970 (outs GPR64sp:$wback), 10971 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10972 GPR64sp:$Rn, 10973 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10974 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 10975 (outs GPR64sp:$wback), 10976 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10977 GPR64sp:$Rn, 10978 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10979 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 10980 (outs GPR64sp:$wback), 10981 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10982 GPR64sp:$Rn, 10983 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10984 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 10985 (outs GPR64sp:$wback), 10986 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10987 GPR64sp:$Rn, 10988 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10989 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 10990 (outs GPR64sp:$wback), 10991 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10992 GPR64sp:$Rn, 10993 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10994 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 10995 (outs GPR64sp:$wback), 10996 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10997 GPR64sp:$Rn, 10998 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10999 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 11000 (outs GPR64sp:$wback), 11001 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 11002 GPR64sp:$Rn, 11003 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 11004 } 11005 11006 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 11007 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 11008 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 11009 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 11010 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 11011 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 11012 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 11013} 11014 11015multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 11016 int Offset128, int Offset64, bits<4> opcode> 11017 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 11018 11019 // LD1 instructions have extra "1d" variants. 11020 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 11021 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 11022 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 11023 (ins GPR64sp:$Rn), []>; 11024 11025 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 11026 (outs GPR64sp:$wback, 11027 !cast<RegisterOperand>(veclist # "1d"):$Vt), 11028 (ins GPR64sp:$Rn, 11029 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 11030 } 11031 11032 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 11033} 11034 11035multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 11036 int Offset128, int Offset64, bits<4> opcode> 11037 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 11038 11039 // ST1 instructions have extra "1d" variants. 11040 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 11041 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 11042 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 11043 GPR64sp:$Rn), []>; 11044 11045 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 11046 (outs GPR64sp:$wback), 11047 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 11048 GPR64sp:$Rn, 11049 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 11050 } 11051 11052 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 11053} 11054 11055multiclass SIMDLd1Multiple<string asm> { 11056 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 11057 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 11058 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 11059 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 11060} 11061 11062multiclass SIMDSt1Multiple<string asm> { 11063 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 11064 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 11065 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 11066 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 11067} 11068 11069multiclass SIMDLd2Multiple<string asm> { 11070 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 11071} 11072 11073multiclass SIMDSt2Multiple<string asm> { 11074 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 11075} 11076 11077multiclass SIMDLd3Multiple<string asm> { 11078 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 11079} 11080 11081multiclass SIMDSt3Multiple<string asm> { 11082 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 11083} 11084 11085multiclass SIMDLd4Multiple<string asm> { 11086 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 11087} 11088 11089multiclass SIMDSt4Multiple<string asm> { 11090 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 11091} 11092 11093//--- 11094// AdvSIMD Load/store single-element 11095//--- 11096 11097class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 11098 string asm, string operands, string cst, 11099 dag oops, dag iops, list<dag> pattern> 11100 : I<oops, iops, asm, operands, cst, pattern> { 11101 bits<5> Vt; 11102 bits<5> Rn; 11103 let Inst{31} = 0; 11104 let Inst{29-24} = 0b001101; 11105 let Inst{22} = L; 11106 let Inst{21} = R; 11107 let Inst{15-13} = opcode; 11108 let Inst{9-5} = Rn; 11109 let Inst{4-0} = Vt; 11110} 11111 11112class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 11113 string asm, string operands, string cst, 11114 dag oops, dag iops, list<dag> pattern> 11115 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 11116 bits<5> Vt; 11117 bits<5> Rn; 11118 let Inst{31} = 0; 11119 let Inst{29-24} = 0b001101; 11120 let Inst{22} = L; 11121 let Inst{21} = R; 11122 let Inst{15-13} = opcode; 11123 let Inst{9-5} = Rn; 11124 let Inst{4-0} = Vt; 11125} 11126 11127 11128let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11129class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 11130 DAGOperand listtype> 11131 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 11132 (outs listtype:$Vt), (ins GPR64sp:$Rn), 11133 []> { 11134 let Inst{30} = Q; 11135 let Inst{23} = 0; 11136 let Inst{20-16} = 0b00000; 11137 let Inst{12} = S; 11138 let Inst{11-10} = size; 11139} 11140let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11141class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 11142 string asm, DAGOperand listtype, DAGOperand GPR64pi> 11143 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 11144 "$Rn = $wback", 11145 (outs GPR64sp:$wback, listtype:$Vt), 11146 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 11147 bits<5> Xm; 11148 let Inst{30} = Q; 11149 let Inst{23} = 1; 11150 let Inst{20-16} = Xm; 11151 let Inst{12} = S; 11152 let Inst{11-10} = size; 11153} 11154 11155multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 11156 int Offset, int Size> { 11157 // E.g. "ld1r { v0.8b }, [x1], #1" 11158 // "ld1r.8b\t$Vt, [$Rn], #1" 11159 // may get mapped to 11160 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 11161 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 11162 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 11163 GPR64sp:$Rn, 11164 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 11165 XZR), 1>; 11166 11167 // E.g. "ld1r.8b { v0 }, [x1], #1" 11168 // "ld1r.8b\t$Vt, [$Rn], #1" 11169 // may get mapped to 11170 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 11171 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 11172 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 11173 GPR64sp:$Rn, 11174 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 11175 XZR), 0>; 11176 11177 // E.g. "ld1r.8b { v0 }, [x1]" 11178 // "ld1r.8b\t$Vt, [$Rn]" 11179 // may get mapped to 11180 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 11181 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 11182 (!cast<Instruction>(BaseName # "v" # layout) 11183 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 11184 GPR64sp:$Rn), 0>; 11185 11186 // E.g. "ld1r.8b { v0 }, [x1], x2" 11187 // "ld1r.8b\t$Vt, [$Rn], $Xm" 11188 // may get mapped to 11189 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 11190 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 11191 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 11192 GPR64sp:$Rn, 11193 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 11194 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 11195} 11196 11197multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 11198 int Offset1, int Offset2, int Offset4, int Offset8> { 11199 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 11200 !cast<DAGOperand>("VecList" # Count # "8b")>; 11201 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 11202 !cast<DAGOperand>("VecList" # Count #"16b")>; 11203 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 11204 !cast<DAGOperand>("VecList" # Count #"4h")>; 11205 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 11206 !cast<DAGOperand>("VecList" # Count #"8h")>; 11207 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 11208 !cast<DAGOperand>("VecList" # Count #"2s")>; 11209 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 11210 !cast<DAGOperand>("VecList" # Count #"4s")>; 11211 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 11212 !cast<DAGOperand>("VecList" # Count #"1d")>; 11213 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 11214 !cast<DAGOperand>("VecList" # Count #"2d")>; 11215 11216 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 11217 !cast<DAGOperand>("VecList" # Count # "8b"), 11218 !cast<DAGOperand>("GPR64pi" # Offset1)>; 11219 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 11220 !cast<DAGOperand>("VecList" # Count # "16b"), 11221 !cast<DAGOperand>("GPR64pi" # Offset1)>; 11222 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 11223 !cast<DAGOperand>("VecList" # Count # "4h"), 11224 !cast<DAGOperand>("GPR64pi" # Offset2)>; 11225 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 11226 !cast<DAGOperand>("VecList" # Count # "8h"), 11227 !cast<DAGOperand>("GPR64pi" # Offset2)>; 11228 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 11229 !cast<DAGOperand>("VecList" # Count # "2s"), 11230 !cast<DAGOperand>("GPR64pi" # Offset4)>; 11231 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 11232 !cast<DAGOperand>("VecList" # Count # "4s"), 11233 !cast<DAGOperand>("GPR64pi" # Offset4)>; 11234 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 11235 !cast<DAGOperand>("VecList" # Count # "1d"), 11236 !cast<DAGOperand>("GPR64pi" # Offset8)>; 11237 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 11238 !cast<DAGOperand>("VecList" # Count # "2d"), 11239 !cast<DAGOperand>("GPR64pi" # Offset8)>; 11240 11241 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 11242 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 11243 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 11244 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 11245 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 11246 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 11247 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 11248 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 11249} 11250 11251class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 11252 dag oops, dag iops, list<dag> pattern> 11253 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 11254 pattern> { 11255 // idx encoded in Q:S:size fields. 11256 bits<4> idx; 11257 let Inst{30} = idx{3}; 11258 let Inst{23} = 0; 11259 let Inst{20-16} = 0b00000; 11260 let Inst{12} = idx{2}; 11261 let Inst{11-10} = idx{1-0}; 11262} 11263class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 11264 dag oops, dag iops, list<dag> pattern> 11265 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 11266 oops, iops, pattern> { 11267 // idx encoded in Q:S:size fields. 11268 bits<4> idx; 11269 let Inst{30} = idx{3}; 11270 let Inst{23} = 0; 11271 let Inst{20-16} = 0b00000; 11272 let Inst{12} = idx{2}; 11273 let Inst{11-10} = idx{1-0}; 11274} 11275class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 11276 dag oops, dag iops> 11277 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11278 "$Rn = $wback", oops, iops, []> { 11279 // idx encoded in Q:S:size fields. 11280 bits<4> idx; 11281 bits<5> Xm; 11282 let Inst{30} = idx{3}; 11283 let Inst{23} = 1; 11284 let Inst{20-16} = Xm; 11285 let Inst{12} = idx{2}; 11286 let Inst{11-10} = idx{1-0}; 11287} 11288class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 11289 dag oops, dag iops> 11290 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11291 "$Rn = $wback", oops, iops, []> { 11292 // idx encoded in Q:S:size fields. 11293 bits<4> idx; 11294 bits<5> Xm; 11295 let Inst{30} = idx{3}; 11296 let Inst{23} = 1; 11297 let Inst{20-16} = Xm; 11298 let Inst{12} = idx{2}; 11299 let Inst{11-10} = idx{1-0}; 11300} 11301 11302class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 11303 dag oops, dag iops, list<dag> pattern> 11304 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 11305 pattern> { 11306 // idx encoded in Q:S:size<1> fields. 11307 bits<3> idx; 11308 let Inst{30} = idx{2}; 11309 let Inst{23} = 0; 11310 let Inst{20-16} = 0b00000; 11311 let Inst{12} = idx{1}; 11312 let Inst{11} = idx{0}; 11313 let Inst{10} = size; 11314} 11315class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 11316 dag oops, dag iops, list<dag> pattern> 11317 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 11318 oops, iops, pattern> { 11319 // idx encoded in Q:S:size<1> fields. 11320 bits<3> idx; 11321 let Inst{30} = idx{2}; 11322 let Inst{23} = 0; 11323 let Inst{20-16} = 0b00000; 11324 let Inst{12} = idx{1}; 11325 let Inst{11} = idx{0}; 11326 let Inst{10} = size; 11327} 11328 11329class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 11330 dag oops, dag iops> 11331 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11332 "$Rn = $wback", oops, iops, []> { 11333 // idx encoded in Q:S:size<1> fields. 11334 bits<3> idx; 11335 bits<5> Xm; 11336 let Inst{30} = idx{2}; 11337 let Inst{23} = 1; 11338 let Inst{20-16} = Xm; 11339 let Inst{12} = idx{1}; 11340 let Inst{11} = idx{0}; 11341 let Inst{10} = size; 11342} 11343class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 11344 dag oops, dag iops> 11345 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11346 "$Rn = $wback", oops, iops, []> { 11347 // idx encoded in Q:S:size<1> fields. 11348 bits<3> idx; 11349 bits<5> Xm; 11350 let Inst{30} = idx{2}; 11351 let Inst{23} = 1; 11352 let Inst{20-16} = Xm; 11353 let Inst{12} = idx{1}; 11354 let Inst{11} = idx{0}; 11355 let Inst{10} = size; 11356} 11357class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 11358 dag oops, dag iops, list<dag> pattern> 11359 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 11360 pattern> { 11361 // idx encoded in Q:S fields. 11362 bits<2> idx; 11363 let Inst{30} = idx{1}; 11364 let Inst{23} = 0; 11365 let Inst{20-16} = 0b00000; 11366 let Inst{12} = idx{0}; 11367 let Inst{11-10} = size; 11368} 11369class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 11370 dag oops, dag iops, list<dag> pattern> 11371 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 11372 oops, iops, pattern> { 11373 // idx encoded in Q:S fields. 11374 bits<2> idx; 11375 let Inst{30} = idx{1}; 11376 let Inst{23} = 0; 11377 let Inst{20-16} = 0b00000; 11378 let Inst{12} = idx{0}; 11379 let Inst{11-10} = size; 11380} 11381class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 11382 string asm, dag oops, dag iops> 11383 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11384 "$Rn = $wback", oops, iops, []> { 11385 // idx encoded in Q:S fields. 11386 bits<2> idx; 11387 bits<5> Xm; 11388 let Inst{30} = idx{1}; 11389 let Inst{23} = 1; 11390 let Inst{20-16} = Xm; 11391 let Inst{12} = idx{0}; 11392 let Inst{11-10} = size; 11393} 11394class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 11395 string asm, dag oops, dag iops> 11396 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11397 "$Rn = $wback", oops, iops, []> { 11398 // idx encoded in Q:S fields. 11399 bits<2> idx; 11400 bits<5> Xm; 11401 let Inst{30} = idx{1}; 11402 let Inst{23} = 1; 11403 let Inst{20-16} = Xm; 11404 let Inst{12} = idx{0}; 11405 let Inst{11-10} = size; 11406} 11407class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 11408 dag oops, dag iops, list<dag> pattern> 11409 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 11410 pattern> { 11411 // idx encoded in Q field. 11412 bits<1> idx; 11413 let Inst{30} = idx; 11414 let Inst{23} = 0; 11415 let Inst{20-16} = 0b00000; 11416 let Inst{12} = 0; 11417 let Inst{11-10} = size; 11418} 11419class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 11420 dag oops, dag iops, list<dag> pattern> 11421 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 11422 oops, iops, pattern> { 11423 // idx encoded in Q field. 11424 bits<1> idx; 11425 let Inst{30} = idx; 11426 let Inst{23} = 0; 11427 let Inst{20-16} = 0b00000; 11428 let Inst{12} = 0; 11429 let Inst{11-10} = size; 11430} 11431class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 11432 string asm, dag oops, dag iops> 11433 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11434 "$Rn = $wback", oops, iops, []> { 11435 // idx encoded in Q field. 11436 bits<1> idx; 11437 bits<5> Xm; 11438 let Inst{30} = idx; 11439 let Inst{23} = 1; 11440 let Inst{20-16} = Xm; 11441 let Inst{12} = 0; 11442 let Inst{11-10} = size; 11443} 11444class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 11445 string asm, dag oops, dag iops> 11446 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11447 "$Rn = $wback", oops, iops, []> { 11448 // idx encoded in Q field. 11449 bits<1> idx; 11450 bits<5> Xm; 11451 let Inst{30} = idx; 11452 let Inst{23} = 1; 11453 let Inst{20-16} = Xm; 11454 let Inst{12} = 0; 11455 let Inst{11-10} = size; 11456} 11457 11458let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11459multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 11460 RegisterOperand listtype, 11461 RegisterOperand GPR64pi> { 11462 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 11463 (outs listtype:$dst), 11464 (ins listtype:$Vt, VectorIndexB:$idx, 11465 GPR64sp:$Rn), []>; 11466 11467 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 11468 (outs GPR64sp:$wback, listtype:$dst), 11469 (ins listtype:$Vt, VectorIndexB:$idx, 11470 GPR64sp:$Rn, GPR64pi:$Xm)>; 11471} 11472let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11473multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 11474 RegisterOperand listtype, 11475 RegisterOperand GPR64pi> { 11476 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 11477 (outs listtype:$dst), 11478 (ins listtype:$Vt, VectorIndexH:$idx, 11479 GPR64sp:$Rn), []>; 11480 11481 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 11482 (outs GPR64sp:$wback, listtype:$dst), 11483 (ins listtype:$Vt, VectorIndexH:$idx, 11484 GPR64sp:$Rn, GPR64pi:$Xm)>; 11485} 11486let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11487multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 11488 RegisterOperand listtype, 11489 RegisterOperand GPR64pi> { 11490 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 11491 (outs listtype:$dst), 11492 (ins listtype:$Vt, VectorIndexS:$idx, 11493 GPR64sp:$Rn), []>; 11494 11495 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 11496 (outs GPR64sp:$wback, listtype:$dst), 11497 (ins listtype:$Vt, VectorIndexS:$idx, 11498 GPR64sp:$Rn, GPR64pi:$Xm)>; 11499} 11500let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11501multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 11502 RegisterOperand listtype, RegisterOperand GPR64pi> { 11503 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 11504 (outs listtype:$dst), 11505 (ins listtype:$Vt, VectorIndexD:$idx, 11506 GPR64sp:$Rn), []>; 11507 11508 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 11509 (outs GPR64sp:$wback, listtype:$dst), 11510 (ins listtype:$Vt, VectorIndexD:$idx, 11511 GPR64sp:$Rn, GPR64pi:$Xm)>; 11512} 11513let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11514multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 11515 RegisterOperand listtype, RegisterOperand GPR64pi> { 11516 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 11517 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 11518 GPR64sp:$Rn), []>; 11519 11520 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 11521 (outs GPR64sp:$wback), 11522 (ins listtype:$Vt, VectorIndexB:$idx, 11523 GPR64sp:$Rn, GPR64pi:$Xm)>; 11524} 11525let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11526multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 11527 RegisterOperand listtype, RegisterOperand GPR64pi> { 11528 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 11529 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 11530 GPR64sp:$Rn), []>; 11531 11532 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 11533 (outs GPR64sp:$wback), 11534 (ins listtype:$Vt, VectorIndexH:$idx, 11535 GPR64sp:$Rn, GPR64pi:$Xm)>; 11536} 11537let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11538multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 11539 RegisterOperand listtype, RegisterOperand GPR64pi> { 11540 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 11541 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 11542 GPR64sp:$Rn), []>; 11543 11544 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 11545 (outs GPR64sp:$wback), 11546 (ins listtype:$Vt, VectorIndexS:$idx, 11547 GPR64sp:$Rn, GPR64pi:$Xm)>; 11548} 11549let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11550multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 11551 RegisterOperand listtype, RegisterOperand GPR64pi> { 11552 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 11553 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 11554 GPR64sp:$Rn), []>; 11555 11556 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 11557 (outs GPR64sp:$wback), 11558 (ins listtype:$Vt, VectorIndexD:$idx, 11559 GPR64sp:$Rn, GPR64pi:$Xm)>; 11560} 11561 11562multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 11563 string Count, int Offset, Operand idxtype> { 11564 // E.g. "ld1 { v0.8b }[0], [x1], #1" 11565 // "ld1\t$Vt, [$Rn], #1" 11566 // may get mapped to 11567 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 11568 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 11569 (!cast<Instruction>(NAME # Type # "_POST") 11570 GPR64sp:$Rn, 11571 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 11572 idxtype:$idx, XZR), 1>; 11573 11574 // E.g. "ld1.8b { v0 }[0], [x1], #1" 11575 // "ld1.8b\t$Vt, [$Rn], #1" 11576 // may get mapped to 11577 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 11578 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 11579 (!cast<Instruction>(NAME # Type # "_POST") 11580 GPR64sp:$Rn, 11581 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11582 idxtype:$idx, XZR), 0>; 11583 11584 // E.g. "ld1.8b { v0 }[0], [x1]" 11585 // "ld1.8b\t$Vt, [$Rn]" 11586 // may get mapped to 11587 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 11588 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 11589 (!cast<Instruction>(NAME # Type) 11590 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11591 idxtype:$idx, GPR64sp:$Rn), 0>; 11592 11593 // E.g. "ld1.8b { v0 }[0], [x1], x2" 11594 // "ld1.8b\t$Vt, [$Rn], $Xm" 11595 // may get mapped to 11596 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 11597 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 11598 (!cast<Instruction>(NAME # Type # "_POST") 11599 GPR64sp:$Rn, 11600 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11601 idxtype:$idx, 11602 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 11603} 11604 11605multiclass SIMDLdSt1SingleAliases<string asm> { 11606 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 11607 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 11608 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 11609 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 11610} 11611 11612multiclass SIMDLdSt2SingleAliases<string asm> { 11613 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 11614 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 11615 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 11616 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 11617} 11618 11619multiclass SIMDLdSt3SingleAliases<string asm> { 11620 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 11621 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 11622 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 11623 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 11624} 11625 11626multiclass SIMDLdSt4SingleAliases<string asm> { 11627 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 11628 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 11629 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 11630 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 11631} 11632} // end of 'let Predicates = [HasNEON]' 11633 11634//---------------------------------------------------------------------------- 11635// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 11636//---------------------------------------------------------------------------- 11637 11638let Predicates = [HasNEON, HasRDM] in { 11639 11640class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 11641 RegisterOperand regtype, string asm, 11642 string kind, list<dag> pattern> 11643 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 11644 pattern> { 11645} 11646multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 11647 SDPatternOperator op> { 11648 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 11649 [(set (v4i16 V64:$dst), 11650 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 11651 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 11652 [(set (v8i16 V128:$dst), 11653 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 11654 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 11655 [(set (v2i32 V64:$dst), 11656 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 11657 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 11658 [(set (v4i32 V128:$dst), 11659 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 11660} 11661 11662multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 11663 SDPatternOperator op> { 11664 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 11665 V64, V64, V128_lo, VectorIndexH, 11666 asm, ".4h", ".4h", ".4h", ".h", 11667 [(set (v4i16 V64:$dst), 11668 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 11669 (dup_v8i16 (v8i16 V128_lo:$Rm), 11670 VectorIndexH:$idx))))]> { 11671 bits<3> idx; 11672 let Inst{11} = idx{2}; 11673 let Inst{21} = idx{1}; 11674 let Inst{20} = idx{0}; 11675 } 11676 11677 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 11678 V128, V128, V128_lo, VectorIndexH, 11679 asm, ".8h", ".8h", ".8h", ".h", 11680 [(set (v8i16 V128:$dst), 11681 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 11682 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 11683 VectorIndexH:$idx)))))]> { 11684 bits<3> idx; 11685 let Inst{11} = idx{2}; 11686 let Inst{21} = idx{1}; 11687 let Inst{20} = idx{0}; 11688 } 11689 11690 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 11691 V64, V64, V128, VectorIndexS, 11692 asm, ".2s", ".2s", ".2s", ".s", 11693 [(set (v2i32 V64:$dst), 11694 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 11695 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 11696 bits<2> idx; 11697 let Inst{11} = idx{1}; 11698 let Inst{21} = idx{0}; 11699 } 11700 11701 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 11702 V128, V128, V128, VectorIndexS, 11703 asm, ".4s", ".4s", ".4s", ".s", 11704 [(set (v4i32 V128:$dst), 11705 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11706 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 11707 VectorIndexS:$idx)))))]> { 11708 bits<2> idx; 11709 let Inst{11} = idx{1}; 11710 let Inst{21} = idx{0}; 11711 } 11712 11713 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 11714 FPR16Op, FPR16Op, V128_lo, 11715 VectorIndexH, asm, ".h", "", "", ".h", 11716 []> { 11717 bits<3> idx; 11718 let Inst{11} = idx{2}; 11719 let Inst{21} = idx{1}; 11720 let Inst{20} = idx{0}; 11721 } 11722 11723 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 11724 FPR32Op, FPR32Op, V128, VectorIndexS, 11725 asm, ".s", "", "", ".s", 11726 [(set (i32 FPR32Op:$dst), 11727 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 11728 (i32 (vector_extract (v4i32 V128:$Rm), 11729 VectorIndexS:$idx)))))]> { 11730 bits<2> idx; 11731 let Inst{11} = idx{1}; 11732 let Inst{21} = idx{0}; 11733 } 11734} 11735} // let Predicates = [HasNeon, HasRDM] 11736 11737//---------------------------------------------------------------------------- 11738// ARMv8.3 Complex ADD/MLA instructions 11739//---------------------------------------------------------------------------- 11740 11741class ComplexRotationOperand<int Angle, int Remainder, string Type> 11742 : AsmOperandClass { 11743 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 11744 let DiagnosticType = "InvalidComplexRotation" # Type; 11745 let Name = "ComplexRotation" # Type; 11746} 11747def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11748 SDNodeXForm<imm, [{ 11749 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 11750}]>> { 11751 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 11752 let PrintMethod = "printComplexRotationOp<90, 0>"; 11753} 11754def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11755 SDNodeXForm<imm, [{ 11756 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 11757}]>> { 11758 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 11759 let PrintMethod = "printComplexRotationOp<180, 90>"; 11760} 11761let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11762class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 11763 RegisterOperand regtype, Operand rottype, 11764 string asm, string kind, list<dag> pattern> 11765 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11766 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11767 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 11768 Sched<[!if(Q, WriteVq, WriteVd)]> { 11769 bits<5> Rd; 11770 bits<5> Rn; 11771 bits<5> Rm; 11772 bits<1> rot; 11773 let Inst{31} = 0; 11774 let Inst{30} = Q; 11775 let Inst{29} = U; 11776 let Inst{28-24} = 0b01110; 11777 let Inst{23-22} = size; 11778 let Inst{21} = 0; 11779 let Inst{20-16} = Rm; 11780 let Inst{15-13} = opcode; 11781 // Non-tied version (FCADD) only has one rotation bit 11782 let Inst{12} = rot; 11783 let Inst{11} = 0; 11784 let Inst{10} = 1; 11785 let Inst{9-5} = Rn; 11786 let Inst{4-0} = Rd; 11787} 11788 11789//8.3 CompNum - Floating-point complex number support 11790multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 11791 string asm, SDPatternOperator OpNode>{ 11792 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11793 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 11794 asm, ".4h", 11795 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11796 (v4f16 V64:$Rn), 11797 (v4f16 V64:$Rm), 11798 (i32 rottype:$rot)))]>; 11799 11800 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 11801 asm, ".8h", 11802 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11803 (v8f16 V128:$Rn), 11804 (v8f16 V128:$Rm), 11805 (i32 rottype:$rot)))]>; 11806 } 11807 11808 let Predicates = [HasComplxNum, HasNEON] in { 11809 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 11810 asm, ".2s", 11811 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11812 (v2f32 V64:$Rn), 11813 (v2f32 V64:$Rm), 11814 (i32 rottype:$rot)))]>; 11815 11816 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 11817 asm, ".4s", 11818 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11819 (v4f32 V128:$Rn), 11820 (v4f32 V128:$Rm), 11821 (i32 rottype:$rot)))]>; 11822 11823 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 11824 asm, ".2d", 11825 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11826 (v2f64 V128:$Rn), 11827 (v2f64 V128:$Rm), 11828 (i32 rottype:$rot)))]>; 11829 } 11830} 11831 11832let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11833class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 11834 bits<3> opcode, 11835 RegisterOperand regtype, 11836 Operand rottype, string asm, 11837 string kind, list<dag> pattern> 11838 : I<(outs regtype:$dst), 11839 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11840 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11841 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 11842 Sched<[!if(Q, WriteVq, WriteVd)]> { 11843 bits<5> Rd; 11844 bits<5> Rn; 11845 bits<5> Rm; 11846 bits<2> rot; 11847 let Inst{31} = 0; 11848 let Inst{30} = Q; 11849 let Inst{29} = U; 11850 let Inst{28-24} = 0b01110; 11851 let Inst{23-22} = size; 11852 let Inst{21} = 0; 11853 let Inst{20-16} = Rm; 11854 let Inst{15-13} = opcode; 11855 let Inst{12-11} = rot; 11856 let Inst{10} = 1; 11857 let Inst{9-5} = Rn; 11858 let Inst{4-0} = Rd; 11859} 11860 11861multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 11862 Operand rottype, string asm, 11863 SDPatternOperator OpNode> { 11864 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11865 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 11866 rottype, asm, ".4h", 11867 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11868 (v4f16 V64:$Rn), 11869 (v4f16 V64:$Rm), 11870 (i32 rottype:$rot)))]>; 11871 11872 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 11873 rottype, asm, ".8h", 11874 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11875 (v8f16 V128:$Rn), 11876 (v8f16 V128:$Rm), 11877 (i32 rottype:$rot)))]>; 11878 } 11879 11880 let Predicates = [HasComplxNum, HasNEON] in { 11881 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 11882 rottype, asm, ".2s", 11883 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11884 (v2f32 V64:$Rn), 11885 (v2f32 V64:$Rm), 11886 (i32 rottype:$rot)))]>; 11887 11888 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 11889 rottype, asm, ".4s", 11890 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11891 (v4f32 V128:$Rn), 11892 (v4f32 V128:$Rm), 11893 (i32 rottype:$rot)))]>; 11894 11895 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 11896 rottype, asm, ".2d", 11897 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11898 (v2f64 V128:$Rn), 11899 (v2f64 V128:$Rm), 11900 (i32 rottype:$rot)))]>; 11901 } 11902} 11903 11904let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11905class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 11906 bit opc1, bit opc2, RegisterOperand dst_reg, 11907 RegisterOperand lhs_reg, 11908 RegisterOperand rhs_reg, Operand vec_idx, 11909 Operand rottype, string asm, string apple_kind, 11910 string dst_kind, string lhs_kind, 11911 string rhs_kind, list<dag> pattern> 11912 : I<(outs dst_reg:$dst), 11913 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 11914 asm, 11915 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 11916 "$idx, $rot" # "|" # apple_kind # 11917 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 11918 Sched<[!if(Q, WriteVq, WriteVd)]> { 11919 bits<5> Rd; 11920 bits<5> Rn; 11921 bits<5> Rm; 11922 bits<2> rot; 11923 11924 let Inst{31} = 0; 11925 let Inst{30} = Q; 11926 let Inst{29} = U; 11927 let Inst{28} = Scalar; 11928 let Inst{27-24} = 0b1111; 11929 let Inst{23-22} = size; 11930 // Bit 21 must be set by the derived class. 11931 let Inst{20-16} = Rm; 11932 let Inst{15} = opc1; 11933 let Inst{14-13} = rot; 11934 let Inst{12} = opc2; 11935 // Bit 11 must be set by the derived class. 11936 let Inst{10} = 0; 11937 let Inst{9-5} = Rn; 11938 let Inst{4-0} = Rd; 11939} 11940 11941// The complex instructions index by pairs of elements, so the VectorIndexes 11942// don't match the lane types, and the index bits are different to the other 11943// classes. 11944multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 11945 string asm> { 11946 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11947 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 11948 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 11949 ".4h", ".h", []> { 11950 bits<1> idx; 11951 let Inst{11} = 0; 11952 let Inst{21} = idx{0}; 11953 } 11954 11955 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 11956 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 11957 ".8h", ".8h", ".h", []> { 11958 bits<2> idx; 11959 let Inst{11} = idx{1}; 11960 let Inst{21} = idx{0}; 11961 } 11962 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 11963 11964 let Predicates = [HasComplxNum, HasNEON] in { 11965 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 11966 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 11967 ".4s", ".4s", ".s", []> { 11968 bits<1> idx; 11969 let Inst{11} = idx{0}; 11970 let Inst{21} = 0; 11971 } 11972 } // Predicates = [HasComplxNum, HasNEON] 11973} 11974 11975//---------------------------------------------------------------------------- 11976// Crypto extensions 11977//---------------------------------------------------------------------------- 11978 11979let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11980class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 11981 list<dag> pat> 11982 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 11983 Sched<[WriteVq]>{ 11984 bits<5> Rd; 11985 bits<5> Rn; 11986 let Inst{31-16} = 0b0100111000101000; 11987 let Inst{15-12} = opc; 11988 let Inst{11-10} = 0b10; 11989 let Inst{9-5} = Rn; 11990 let Inst{4-0} = Rd; 11991} 11992 11993class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 11994 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 11995 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 11996 11997class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 11998 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 11999 "$Rd = $dst", 12000 [(set (v16i8 V128:$dst), 12001 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 12002 12003let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 12004class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 12005 dag oops, dag iops, list<dag> pat> 12006 : I<oops, iops, asm, 12007 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 12008 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 12009 Sched<[WriteVq]>{ 12010 bits<5> Rd; 12011 bits<5> Rn; 12012 bits<5> Rm; 12013 let Inst{31-21} = 0b01011110000; 12014 let Inst{20-16} = Rm; 12015 let Inst{15} = 0; 12016 let Inst{14-12} = opc; 12017 let Inst{11-10} = 0b00; 12018 let Inst{9-5} = Rn; 12019 let Inst{4-0} = Rd; 12020} 12021 12022class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 12023 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 12024 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 12025 [(set (v4i32 FPR128:$dst), 12026 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 12027 (v4i32 V128:$Rm)))]>; 12028 12029class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 12030 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 12031 (ins V128:$Rd, V128:$Rn, V128:$Rm), 12032 [(set (v4i32 V128:$dst), 12033 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 12034 (v4i32 V128:$Rm)))]>; 12035 12036class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 12037 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 12038 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 12039 [(set (v4i32 FPR128:$dst), 12040 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 12041 (v4i32 V128:$Rm)))]>; 12042 12043let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 12044class SHA2OpInst<bits<4> opc, string asm, string kind, 12045 string cstr, dag oops, dag iops, 12046 list<dag> pat> 12047 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 12048 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 12049 Sched<[WriteVq]>{ 12050 bits<5> Rd; 12051 bits<5> Rn; 12052 let Inst{31-16} = 0b0101111000101000; 12053 let Inst{15-12} = opc; 12054 let Inst{11-10} = 0b10; 12055 let Inst{9-5} = Rn; 12056 let Inst{4-0} = Rd; 12057} 12058 12059class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 12060 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 12061 (ins V128:$Rd, V128:$Rn), 12062 [(set (v4i32 V128:$dst), 12063 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 12064 12065class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 12066 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 12067 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 12068 12069// Armv8.2-A Crypto extensions 12070class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 12071 list<dag> pattern> 12072 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 12073 bits<5> Vd; 12074 bits<5> Vn; 12075 let Inst{31-25} = 0b1100111; 12076 let Inst{9-5} = Vn; 12077 let Inst{4-0} = Vd; 12078} 12079 12080class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 12081 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 12082 "$Vd = $Vdst", []> { 12083 let Inst{31-25} = 0b1100111; 12084 let Inst{24-21} = 0b0110; 12085 let Inst{20-15} = 0b000001; 12086 let Inst{14} = op0; 12087 let Inst{13-12} = 0b00; 12088 let Inst{11-10} = op1; 12089} 12090class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 12091 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 12092class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 12093 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 12094 12095class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 12096 string asmops, string cst> 12097 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 12098 bits<5> Vm; 12099 let Inst{24-21} = 0b0011; 12100 let Inst{20-16} = Vm; 12101 let Inst{15} = 0b1; 12102 let Inst{14} = op0; 12103 let Inst{13-12} = 0b00; 12104 let Inst{11-10} = op1; 12105} 12106class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 12107 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 12108 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 12109class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 12110 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 12111 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 12112class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 12113 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 12114 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 12115class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 12116 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 12117 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 12118class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 12119 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 12120 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 12121 12122class CryptoRRRR<bits<2>op0, string asm, string asmops> 12123 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 12124 asmops, "", []> { 12125 bits<5> Vm; 12126 bits<5> Va; 12127 let Inst{24-23} = 0b00; 12128 let Inst{22-21} = op0; 12129 let Inst{20-16} = Vm; 12130 let Inst{15} = 0b0; 12131 let Inst{14-10} = Va; 12132} 12133class CryptoRRRR_16B<bits<2>op0, string asm> 12134 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 12135 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 12136} 12137class CryptoRRRR_4S<bits<2>op0, string asm> 12138 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 12139 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 12140} 12141 12142class CryptoRRRi6<string asm> 12143 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 12144 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 12145 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 12146 bits<6> imm; 12147 bits<5> Vm; 12148 let Inst{24-21} = 0b0100; 12149 let Inst{20-16} = Vm; 12150 let Inst{15-10} = imm; 12151 let Inst{9-5} = Vn; 12152 let Inst{4-0} = Vd; 12153} 12154 12155class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 12156 : BaseCryptoV82<(outs V128:$Vdst), 12157 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 12158 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 12159 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 12160 bits<2> imm; 12161 bits<5> Vm; 12162 let Inst{24-21} = 0b0010; 12163 let Inst{20-16} = Vm; 12164 let Inst{15} = 0b1; 12165 let Inst{14} = op0; 12166 let Inst{13-12} = imm; 12167 let Inst{11-10} = op1; 12168} 12169 12170//---------------------------------------------------------------------------- 12171// v8.1 atomic instructions extension: 12172// * CAS 12173// * CASP 12174// * SWP 12175// * LDOPregister<OP>, and aliases STOPregister<OP> 12176 12177// Instruction encodings: 12178// 12179// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 12180// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 12181// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 12182// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 12183// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 12184// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 12185 12186// Instruction syntax: 12187// 12188// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 12189// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 12190// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 12191// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 12192// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 12193// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 12194// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 12195// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 12196// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 12197// ST<OP>{<order>} <Xs>, [<Xn|SP>] 12198 12199let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 12200class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 12201 string cstr, list<dag> pattern> 12202 : I<oops, iops, asm, operands, cstr, pattern> { 12203 bits<2> Sz; 12204 bit NP; 12205 bit Acq; 12206 bit Rel; 12207 bits<5> Rs; 12208 bits<5> Rn; 12209 bits<5> Rt; 12210 let Inst{31-30} = Sz; 12211 let Inst{29-24} = 0b001000; 12212 let Inst{23} = NP; 12213 let Inst{22} = Acq; 12214 let Inst{21} = 0b1; 12215 let Inst{20-16} = Rs; 12216 let Inst{15} = Rel; 12217 let Inst{14-10} = 0b11111; 12218 let Inst{9-5} = Rn; 12219 let Inst{4-0} = Rt; 12220 let Predicates = [HasLSE]; 12221} 12222 12223class BaseCAS<string order, string size, RegisterClass RC> 12224 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 12225 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 12226 "$out = $Rs",[]>, 12227 Sched<[WriteAtomic]> { 12228 let NP = 1; 12229} 12230 12231multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 12232 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 12233 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 12234 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 12235 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 12236} 12237 12238class BaseCASP<string order, string size, RegisterOperand RC> 12239 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 12240 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 12241 "$out = $Rs",[]>, 12242 Sched<[WriteAtomic]> { 12243 let NP = 0; 12244} 12245 12246multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 12247 let Sz = 0b00, Acq = Acq, Rel = Rel in 12248 def W : BaseCASP<order, "", WSeqPairClassOperand>; 12249 let Sz = 0b01, Acq = Acq, Rel = Rel in 12250 def X : BaseCASP<order, "", XSeqPairClassOperand>; 12251} 12252 12253// v9.6-a CAST unprivileged instructions 12254let mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 12255class BaseCASTEncoding<dag oops, dag iops, string asm, 12256 string cstr, list<dag> pattern> 12257 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", cstr, pattern> { 12258 bits<5> Rs; 12259 bits<5> Rn; 12260 bits<5> Rt; 12261 bit L; 12262 bit o0; 12263 bits<2> Sz; 12264 let Inst{31-30} = Sz; 12265 let Inst{29-23} = 0b0010011; 12266 let Inst{22} = L; 12267 let Inst{21} = 0b0; 12268 let Inst{20-16} = Rs; 12269 let Inst{15} = o0; 12270 let Inst{14-10} = 0b11111; 12271 let Unpredictable{14-10} = 0b11111; 12272 let Inst{9-5} = Rn; 12273 let Inst{4-0} = Rt; 12274} 12275 12276multiclass CompareAndSwapUnprivileged<bits<2> Sz, bit L, bit o0, string order> { 12277 let Sz = Sz, L = L, o0 = o0 in 12278 def X : BaseCASTEncoding < 12279 (outs GPR64:$out), 12280 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp0:$Rn), 12281 "cas" # order # "t", 12282 "$out = $Rs",[]>, Sched<[WriteAtomic]>; 12283 12284} 12285 12286multiclass CompareAndSwapPairUnprivileged<bits<2> Sz, bit L, bit o0, string order> { 12287 let Sz = Sz, L = L, o0 = o0 in 12288 def X : BaseCASTEncoding<(outs XSeqPairClassOperand:$out), 12289 (ins XSeqPairClassOperand:$Rs, XSeqPairClassOperand:$Rt, GPR64sp0:$Rn), 12290 "casp" # order # "t", 12291 "$out = $Rs",[]>, 12292 Sched<[WriteAtomic]>; 12293} 12294 12295let Predicates = [HasLSE] in 12296class BaseSWP<string order, string size, RegisterClass RC> 12297 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 12298 "\t$Rs, $Rt, [$Rn]","",[]>, 12299 Sched<[WriteAtomic]> { 12300 bits<2> Sz; 12301 bit Acq; 12302 bit Rel; 12303 bits<5> Rs; 12304 bits<3> opc = 0b000; 12305 bits<5> Rn; 12306 bits<5> Rt; 12307 let Inst{31-30} = Sz; 12308 let Inst{29-24} = 0b111000; 12309 let Inst{23} = Acq; 12310 let Inst{22} = Rel; 12311 let Inst{21} = 0b1; 12312 let Inst{20-16} = Rs; 12313 let Inst{15} = 0b1; 12314 let Inst{14-12} = opc; 12315 let Inst{11-10} = 0b00; 12316 let Inst{9-5} = Rn; 12317 let Inst{4-0} = Rt; 12318 let Predicates = [HasLSE]; 12319} 12320 12321multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 12322 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 12323 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 12324 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 12325 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 12326} 12327 12328// v9.6a swap operations 12329class BaseSWPLSUI<string order, RegisterClass RC> 12330 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swpt" # order, 12331 "\t$Rs, $Rt, [$Rn]","",[]>, 12332 Sched<[WriteAtomic]> { 12333 bits<2> Sz; 12334 bit Acq; 12335 bit Rel; 12336 bits<5> Rs; 12337 bits<5> Rn; 12338 bits<5> Rt; 12339 let Inst{31-30} = Sz; 12340 let Inst{29-24} = 0b011001; 12341 let Inst{23} = Acq; 12342 let Inst{22} = Rel; 12343 let Inst{21} = 0b1; 12344 let Inst{20-16} = Rs; 12345 let Inst{15} = 0b1; 12346 let Inst{14-12} = 0b000; 12347 let Inst{11-10} = 0b01; 12348 let Inst{9-5} = Rn; 12349 let Inst{4-0} = Rt; 12350} 12351 12352multiclass SwapLSUI<bits<1> Acq, bits<1> Rel, string order> { 12353 let Sz = 0b00, Acq = Acq, Rel = Rel in def W : BaseSWPLSUI<order, GPR32>; 12354 let Sz = 0b01, Acq = Acq, Rel = Rel in def X : BaseSWPLSUI<order, GPR64>; 12355} 12356 12357let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 12358class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 12359 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 12360 "\t$Rs, $Rt, [$Rn]","",[]>, 12361 Sched<[WriteAtomic]> { 12362 bits<2> Sz; 12363 bit Acq; 12364 bit Rel; 12365 bits<5> Rs; 12366 bits<3> opc; 12367 bits<5> Rn; 12368 bits<5> Rt; 12369 let Inst{31-30} = Sz; 12370 let Inst{29-24} = 0b111000; 12371 let Inst{23} = Acq; 12372 let Inst{22} = Rel; 12373 let Inst{21} = 0b1; 12374 let Inst{20-16} = Rs; 12375 let Inst{15} = 0b0; 12376 let Inst{14-12} = opc; 12377 let Inst{11-10} = 0b00; 12378 let Inst{9-5} = Rn; 12379 let Inst{4-0} = Rt; 12380 let Predicates = [HasLSE]; 12381} 12382 12383multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 12384 string order> { 12385 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 12386 def B : BaseLDOPregister<op, order, "b", GPR32>; 12387 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 12388 def H : BaseLDOPregister<op, order, "h", GPR32>; 12389 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 12390 def W : BaseLDOPregister<op, order, "", GPR32>; 12391 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 12392 def X : BaseLDOPregister<op, order, "", GPR64>; 12393} 12394 12395class BaseLDOPregisterLSUI<string op, string order, RegisterClass RC> 12396 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ldt" # op # order, 12397 "\t$Rs, $Rt, [$Rn]","",[]>, 12398 Sched<[WriteAtomic]> { 12399 bits<2> Sz; 12400 bit Acq; 12401 bit Rel; 12402 bits<5> Rs; 12403 bits<3> opc; 12404 bits<5> Rn; 12405 bits<5> Rt; 12406 let Inst{31-30} = Sz; 12407 let Inst{29-24} = 0b011001; 12408 let Inst{23} = Acq; 12409 let Inst{22} = Rel; 12410 let Inst{21} = 0b1; 12411 let Inst{20-16} = Rs; 12412 let Inst{15} = 0b0; 12413 let Inst{14-12} = opc; 12414 let Inst{11-10} = 0b01; 12415 let Inst{9-5} = Rn; 12416 let Inst{4-0} = Rt; 12417} 12418 12419 12420multiclass LDOPregisterLSUI<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 12421 string order> { 12422 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 12423 def W : BaseLDOPregisterLSUI<op, order, GPR32>; 12424 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 12425 def X : BaseLDOPregisterLSUI<op, order, GPR64>; 12426} 12427 12428// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 12429// complex DAG for DstRHS. 12430let Predicates = [HasLSE] in 12431multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 12432 ValueType vt, dag SrcRHS, dag DstRHS> { 12433 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, SrcRHS), 12434 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 12435 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, SrcRHS), 12436 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 12437 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, SrcRHS), 12438 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 12439 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, SrcRHS), 12440 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 12441 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, SrcRHS), 12442 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 12443} 12444 12445multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 12446 ValueType vt, dag RHS> { 12447 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS, RHS>; 12448} 12449 12450multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 12451 ValueType vt, dag LHS, dag RHS> { 12452 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, LHS, RHS>; 12453} 12454 12455multiclass LDOPregister_patterns<string inst, string op> { 12456 defm : LDOPregister_patterns_ord<inst, "X", op, i64, (i64 GPR64:$Rm)>; 12457 defm : LDOPregister_patterns_ord<inst, "W", op, i32, (i32 GPR32:$Rm)>; 12458 defm : LDOPregister_patterns_ord<inst, "H", op, i16, (i32 GPR32:$Rm)>; 12459 defm : LDOPregister_patterns_ord<inst, "B", op, i8, (i32 GPR32:$Rm)>; 12460} 12461 12462multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 12463 defm : LDOPregister_patterns_ord_mod<inst, "X", op, i64, 12464 (i64 GPR64:$Rm), 12465 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 12466 defm : LDOPregister_patterns_ord_mod<inst, "W", op, i32, 12467 (i32 GPR32:$Rm), 12468 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 12469 defm : LDOPregister_patterns_ord_mod<inst, "H", op, i16, 12470 (i32 GPR32:$Rm), 12471 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 12472 defm : LDOPregister_patterns_ord_mod<inst, "B", op, i8, 12473 (i32 GPR32:$Rm), 12474 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 12475} 12476 12477let Predicates = [HasLSE] in 12478multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 12479 ValueType vt, dag OLD, dag NEW> { 12480 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, OLD, NEW), 12481 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 12482 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, OLD, NEW), 12483 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 12484 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, OLD, NEW), 12485 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 12486 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 12487 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 12488 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 12489 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 12490} 12491 12492multiclass CASregister_patterns_ord<string inst, string suffix, string op, 12493 ValueType vt, dag OLD, dag NEW> { 12494 defm : CASregister_patterns_ord_dag<inst, suffix, op, vt, OLD, NEW>; 12495} 12496 12497multiclass CASregister_patterns<string inst, string op> { 12498 defm : CASregister_patterns_ord<inst, "X", op, i64, 12499 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 12500 defm : CASregister_patterns_ord<inst, "W", op, i32, 12501 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 12502 defm : CASregister_patterns_ord<inst, "H", op, i16, 12503 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 12504 defm : CASregister_patterns_ord<inst, "B", op, i8, 12505 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 12506} 12507 12508let Predicates = [HasLSE] in 12509class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 12510 Instruction inst> : 12511 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 12512 12513multiclass STOPregister<string asm, string instr> { 12514 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 12515 !cast<Instruction>(instr # "LB")>; 12516 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 12517 !cast<Instruction>(instr # "LH")>; 12518 def : BaseSTOPregister<asm # "l", GPR32, WZR, 12519 !cast<Instruction>(instr # "LW")>; 12520 def : BaseSTOPregister<asm # "l", GPR64, XZR, 12521 !cast<Instruction>(instr # "LX")>; 12522 def : BaseSTOPregister<asm # "b", GPR32, WZR, 12523 !cast<Instruction>(instr # "B")>; 12524 def : BaseSTOPregister<asm # "h", GPR32, WZR, 12525 !cast<Instruction>(instr # "H")>; 12526 def : BaseSTOPregister<asm, GPR32, WZR, 12527 !cast<Instruction>(instr # "W")>; 12528 def : BaseSTOPregister<asm, GPR64, XZR, 12529 !cast<Instruction>(instr # "X")>; 12530} 12531 12532class BaseSTOPregisterLSUI<string asm, RegisterClass OP, Register Reg, 12533 Instruction inst> : 12534 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 12535 12536multiclass STOPregisterLSUI<string asm, string instr> { 12537 def : BaseSTOPregisterLSUI<asm # "a", GPR32, WZR, 12538 !cast<Instruction>(instr # "W")>; 12539 def : BaseSTOPregisterLSUI<asm # "a", GPR64, XZR, 12540 !cast<Instruction>(instr # "X")>; 12541 def : BaseSTOPregisterLSUI<asm # "l", GPR32, WZR, 12542 !cast<Instruction>(instr # "W")>; 12543 def : BaseSTOPregisterLSUI<asm # "l", GPR64, XZR, 12544 !cast<Instruction>(instr # "X")>; 12545 def : BaseSTOPregisterLSUI<asm # "al", GPR32, WZR, 12546 !cast<Instruction>(instr # "W")>; 12547 def : BaseSTOPregisterLSUI<asm # "al", GPR64, XZR, 12548 !cast<Instruction>(instr # "X")>; 12549 def : BaseSTOPregisterLSUI<asm, GPR32, WZR, 12550 !cast<Instruction>(instr # "W")>; 12551 def : BaseSTOPregisterLSUI<asm, GPR64, XZR, 12552 !cast<Instruction>(instr # "X")>; 12553} 12554 12555class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 12556 dag iops, dag oops, list<dag> pat> 12557 : I<oops, iops, asm_inst, asm_ops, "", pat>, 12558 Sched<[]> /* FIXME: fill in scheduling details once known */ { 12559 bits<5> Rt; 12560 bits<5> Rn; 12561 let Inst{31-21} = 0b11111000001; 12562 let Inst{15} = 1; 12563 let Inst{14-12} = opc; 12564 let Inst{11-10} = 0b00; 12565 let Inst{9-5} = Rn; 12566 let Inst{4-0} = Rt; 12567 12568 let Predicates = [HasV8_7a]; 12569} 12570 12571class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 12572 list<dag> pat = []> 12573 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 12574 let Inst{20-16} = 0b11111; 12575} 12576 12577class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 12578 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 12579 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 12580 bits<5> Rs; 12581 let Inst{20-16} = Rs; 12582 let mayStore = 1; 12583} 12584 12585class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 12586 bits<2> op2, string asm> 12587 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 12588 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 12589 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 12590 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 12591 Sched<[]> { 12592 bits<5> Rd; 12593 bits<5> Rs; 12594 bits<5> Rn; 12595 let Inst{31-27} = 0b00011; 12596 let Inst{26} = isMove; 12597 let Inst{25-24} = 0b01; 12598 let Inst{23-22} = opcode; 12599 let Inst{21} = 0b0; 12600 let Inst{20-16} = Rs; 12601 let Inst{15-14} = op2; 12602 let Inst{13-12} = op1; 12603 let Inst{11-10} = 0b01; 12604 let Inst{9-5} = Rn; 12605 let Inst{4-0} = Rd; 12606 12607 let DecoderMethod = "DecodeCPYMemOpInstruction"; 12608 let mayLoad = 1; 12609 let mayStore = 1; 12610} 12611 12612class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 12613 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 12614 12615class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 12616 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 12617 12618class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 12619 string asm> 12620 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 12621 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 12622 asm, "\t[$Rd]!, $Rn!, $Rm", 12623 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 12624 Sched<[]> { 12625 bits<5> Rd; 12626 bits<5> Rn; 12627 bits<5> Rm; 12628 let Inst{31-27} = 0b00011; 12629 let Inst{26} = isTagging; 12630 let Inst{25-21} = 0b01110; 12631 let Inst{20-16} = Rm; 12632 let Inst{15-14} = opcode; 12633 let Inst{13} = op2; 12634 let Inst{12} = op1; 12635 let Inst{11-10} = 0b01; 12636 let Inst{9-5} = Rn; 12637 let Inst{4-0} = Rd; 12638 12639 let DecoderMethod = "DecodeSETMemOpInstruction"; 12640 let mayLoad = 0; 12641 let mayStore = 1; 12642} 12643 12644class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 12645 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 12646 12647class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 12648 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 12649 12650multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 12651 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 12652 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 12653 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 12654 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 12655 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 12656 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 12657 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 12658 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 12659 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 12660 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 12661 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 12662 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 12663 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 12664 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 12665 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 12666 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 12667} 12668 12669multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 12670 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 12671 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 12672 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 12673 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 12674 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 12675 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 12676 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 12677 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 12678 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 12679 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 12680 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 12681 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 12682 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 12683 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 12684 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 12685 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 12686} 12687 12688multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 12689 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 12690 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 12691 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 12692 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 12693} 12694 12695multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 12696 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 12697 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 12698 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 12699 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 12700} 12701 12702//---------------------------------------------------------------------------- 12703// 2022 Armv8.9/Armv9.4 Extensions 12704//---------------------------------------------------------------------------- 12705 12706//--- 12707// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC) 12708//--- 12709 12710class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc, 12711 RegisterClass regtype, ImmLeaf immtype, string asm, 12712 SDPatternOperator OpNode> 12713 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm), 12714 asm, "\t$Rd, $Rn, $imm", "", 12715 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> { 12716 bits<5> Rd; 12717 bits<5> Rn; 12718 bits<8> imm; 12719 12720 let Inst{31} = sf; 12721 let Inst{30} = Op; 12722 let Inst{29} = S; 12723 let Inst{28-22} = 0b1000111; 12724 let Inst{21-18} = opc; 12725 let Inst{17-10} = imm; 12726 let Inst{9-5} = Rn; 12727 let Inst{4-0} = Rd; 12728} 12729 12730class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin, 12731 RegisterClass regtype, string asm, 12732 SDPatternOperator OpNode> 12733 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>, 12734 Sched<[WriteI]> { 12735 let Inst{11} = isMin; 12736 let Inst{10} = isUnsigned; 12737 let mayLoad = 0; 12738 let mayStore = 0; 12739 let hasSideEffects = 0; 12740} 12741 12742class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin, 12743 RegisterClass regtype, ImmLeaf immtype, string asm, 12744 SDPatternOperator OpNode> 12745 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm, 12746 OpNode>, 12747 Sched<[]> { 12748 let Inst{19} = isMin; 12749 let Inst{18} = isUnsigned; 12750 let mayLoad = 0; 12751 let mayStore = 0; 12752 let hasSideEffects = 0; 12753} 12754 12755multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm, 12756 SDPatternOperator OpNode = null_frag> { 12757 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>; 12758 12759 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32, 12760 !cond(isUnsigned : uimm8_32b, 12761 !not(isUnsigned) : simm8_32b), asm, OpNode>; 12762 12763 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>; 12764 12765 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64, 12766 !cond(isUnsigned : uimm8_64b, 12767 !not(isUnsigned) : simm8_64b), asm, OpNode>; 12768} 12769 12770//--- 12771// RCPC instructions (FEAT_LRCPC3) 12772//--- 12773 12774class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops, 12775 string asm, string operands, string cstr = ""> 12776 : I<oops, iops, asm, operands, cstr, []>, 12777 Sched<[WriteAtomic]> { 12778 bits<5> Rt; 12779 bits<5> Rn; 12780 let Inst{31-30} = size; 12781 let Inst{29-24} = {0,1,1,V,0,1}; 12782 let Inst{23-22} = opc; 12783 let Inst{21} = 0b0; 12784 // Inst{20-12} 12785 let Inst{11-10} = 0b10; 12786 let Inst{9-5} = Rn; 12787 let Inst{4-0} = Rt; 12788 12789 let mayLoad = Inst{22}; 12790 let mayStore = !not(Inst{22}); 12791 let hasSideEffects = 0; 12792} 12793 12794class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2, 12795 dag oops, dag iops, string asm, 12796 string operands, string cstr> 12797 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12798 bits<5> Rt2; 12799 let Inst{20-16} = Rt2; 12800 let Inst{15-12} = opc2; 12801} 12802 12803class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops, 12804 string asm, string operands, string cstr> 12805 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12806 let Inst{20-12} = 0b000000000; // imm9 12807} 12808 12809multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype, 12810 dag oops, dag iops, string asm> { 12811 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> { 12812 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 12813 let Inst{20-12} = simm; 12814 } 12815 12816 def a : InstAlias<asm # "\t$Rt, [$Rn]", 12817 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 12818} 12819 12820class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst> 12821 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm, 12822 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>, 12823 Sched<[]> { 12824 bit Q; 12825 let Inst{31} = 0; 12826 let Inst{30} = Q; 12827 let Inst{23} = 0; 12828 let Inst{20-16} = 0b00001; 12829 let Inst{12} = 0; // S 12830 let Inst{11-10} = 0b01; // size 12831 12832 let mayLoad = L; 12833 let mayStore = !not(L); 12834 let hasSideEffects = 1; 12835} 12836 12837//--- 12838// Instrumentation Extension (FEAT_ITE) 12839//--- 12840 12841let Predicates = [HasITE] in 12842def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> { 12843 let Inst{20-19} = 0b01; 12844 let Inst{18-16} = 0b011; 12845 let Inst{15-12} = 0b0111; 12846 let Inst{11-8} = 0b0010; 12847 let Inst{7-5} = 0b111; 12848} 12849 12850// * RCWCAS family 12851// * RCW<OP> family 12852 12853//-------------------------------------------------------------------- 12854// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?) 12855 12856// Instruction encoding: 12857// 12858// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0 12859// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12860// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12861// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12862// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12863 12864// Instruction syntax: 12865// 12866// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 12867// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>] 12868 12869class BaseRCWCASEncoding<dag oops, dag iops, string asm> 12870 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>, 12871 Sched<[]> { 12872 bit Acq; 12873 bit Rel; 12874 bit SC; 12875 bit Pair; 12876 bits<5> Rs; 12877 bits<5> Rn; 12878 bits<5> Rt; 12879 let Inst{31} = 0b0; 12880 let Inst{30} = SC; 12881 let Inst{29-24} = 0b011001; 12882 let Inst{23} = Acq; 12883 let Inst{22} = Rel; 12884 let Inst{21} = 0b1; 12885 let Inst{20-16} = Rs; 12886 let Inst{15-13} = 0b000; 12887 let Inst{12-11} = 0b01; 12888 let Inst{10} = Pair; 12889 let Inst{9-5} = Rn; 12890 let Inst{4-0} = Rt; 12891 let mayLoad = 1; 12892 let mayStore = 1; 12893 let hasSideEffects = 1; 12894 let Defs = [NZCV]; 12895} 12896 12897multiclass BaseRCWCAS<dag oops, dag iops, string prefix> { 12898 let Acq = 0b0, Rel = 0b0 in 12899 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">; 12900 let Acq = 0b1, Rel = 0b0 in 12901 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">; 12902 let Acq = 0b0, Rel = 0b1 in 12903 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">; 12904 let Acq = 0b1, Rel = 0b1 in 12905 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">; 12906} 12907 12908multiclass ReadCheckWriteCompareAndSwap { 12909 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in 12910 defm CAS : BaseRCWCAS<(outs GPR64:$out), 12911 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >; 12912 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in 12913 defm SCAS : BaseRCWCAS<(outs GPR64:$out), 12914 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">; 12915 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12916 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12917 (ins XSeqPairClassOperand:$Rs, 12918 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12919 "rcwcasp">; 12920 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12921 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12922 (ins XSeqPairClassOperand:$Rs, 12923 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12924 "rcwscasp">; 12925} 12926 12927//------------------------------------------------------------------ 12928// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?) 12929 12930// Instruction encoding: 12931// 12932// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12933// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12934// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12935// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12936// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12937// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12938// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12939 12940// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12941// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12942// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12943// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12944// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12945// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12946// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12947 12948// Instruction syntax: 12949// 12950// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 12951// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>] 12952 12953class BaseRCWOPEncoding<string asm> 12954 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm, 12955 "\t$Rs, $Rt, [$Rn]", "", []>, 12956 Sched<[]> { 12957 bit Acq; 12958 bit Rel; 12959 bit SC; 12960 bits<3> opc; 12961 bits<5> Rs; 12962 bits<5> Rn; 12963 bits<5> Rt; 12964 let Inst{31} = 0b0; 12965 let Inst{30} = SC; 12966 let Inst{29-24} = 0b111000; 12967 let Inst{23} = Acq; 12968 let Inst{22} = Rel; 12969 let Inst{21} = 0b1; 12970 let Inst{20-16} = Rs; 12971 let Inst{15} = 0b1; 12972 let Inst{14-12} = opc; 12973 let Inst{11-10} = 0b00; 12974 let Inst{9-5} = Rn; 12975 let Inst{4-0} = Rt; 12976 let mayLoad = 1; 12977 let mayStore = 1; 12978 let hasSideEffects = 1; 12979 let Defs = [NZCV]; 12980 let Predicates = [HasTHE]; 12981} 12982 12983class BaseRCWOPPEncoding<string asm> 12984 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12985 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm, 12986 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12987 Sched<[]> { 12988 bit Acq; 12989 bit Rel; 12990 bit SC; 12991 bits<3> opc; 12992 bits<5> Rt2; 12993 bits<5> Rn; 12994 bits<5> Rt; 12995 let Inst{31} = 0b0; 12996 let Inst{30} = SC; 12997 let Inst{29-24} = 0b011001; 12998 let Inst{23} = Acq; 12999 let Inst{22} = Rel; 13000 let Inst{21} = 0b1; 13001 let Inst{20-16} = Rt2; 13002 let Inst{15} = 0b1; 13003 let Inst{14-12} = opc; 13004 let Inst{11-10} = 0b00; 13005 let Inst{9-5} = Rn; 13006 let Inst{4-0} = Rt; 13007 let mayLoad = 1; 13008 let mayStore = 1; 13009 let hasSideEffects = 1; 13010 let Defs = [NZCV]; 13011 let Predicates = [HasTHE, HasD128]; 13012} 13013 13014multiclass BaseRCWOP<string prefix> { 13015 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">; 13016 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">; 13017 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">; 13018 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">; 13019 13020 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">; 13021 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">; 13022 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">; 13023 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">; 13024} 13025 13026multiclass ReadCheckWriteOperation<bits<3> opc, string op> { 13027 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>; 13028 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >; 13029} 13030 13031//--- 13032// 128-bit atomic instructions (FEAT_LSE128) 13033//--- 13034 13035let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in 13036class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm> 13037: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 13038 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), 13039 asm, "\t$Rt, $Rt2, [$Rn]", 13040 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 13041 Sched<[]> { 13042 bits<5> Rt; 13043 bits<5> Rt2; 13044 bits<5> Rn; 13045 let Inst{31-24} = 0b00011001; 13046 let Inst{23-22} = AR; 13047 let Inst{21} = 0b1; 13048 let Inst{20-16} = Rt2; 13049 let Inst{15} = o3; 13050 let Inst{14-12} = op0; 13051 let Inst{11-10} = 0b00; 13052 let Inst{9-5} = Rn; 13053 let Inst{4-0} = Rt; 13054} 13055 13056//--- 13057// 128-bit System Instructions (FEAT_SYSINSTR128) 13058//--- 13059 13060// Instruction encoding: 13061// 13062// 31 19|18 16|15 12|11 8|7 5|4 0 13063// SYSP 1101010101001| op1| Cn| Cm|op2| Rt 13064 13065// Instruction syntax: 13066// 13067// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>} 13068 13069class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> : 13070 RtSystemI<L, oops, iops, asm, operands, pattern> { 13071 let Inst{22} = 0b1; // override BaseSystemI 13072} 13073 13074class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs> 13075 : RtSystemI128<L, outputs, inputs, asm, operands> { 13076 bits<3> op1; 13077 bits<4> Cn; 13078 bits<4> Cm; 13079 bits<3> op2; 13080 let Inst{20-19} = 0b01; 13081 let Inst{18-16} = op1; 13082 let Inst{15-12} = Cn; 13083 let Inst{11-8} = Cm; 13084 let Inst{7-5} = op2; 13085} 13086class SystemPXtI<bit L, string asm> : 13087 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs), 13088 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>; 13089 13090//---------------------------------------------------------------------------- 13091// 2023 Armv9.5 Extensions 13092//---------------------------------------------------------------------------- 13093 13094//--- 13095// Checked Pointer Arithmetic (FEAT_CPA) 13096//--- 13097 13098def LSLImm3ShiftOperand : AsmOperandClass { 13099 let SuperClasses = [ExtendOperandLSL64]; 13100 let Name = "LSLImm3Shift"; 13101 let RenderMethod = "addLSLImm3ShifterOperands"; 13102 let DiagnosticType = "AddSubLSLImm3ShiftLarge"; 13103} 13104 13105def lsl_imm3_shift_operand : Operand<i32> { 13106 let PrintMethod = "printShifter"; 13107 let ParserMatchClass = LSLImm3ShiftOperand; 13108} 13109 13110// Base CPA scalar add/subtract with lsl #imm3 shift 13111class BaseAddSubCPA<bit isSub, string asm> : I<(outs GPR64sp:$Rd), 13112 (ins GPR64sp:$Rn, GPR64:$Rm, lsl_imm3_shift_operand:$shift_imm), 13113 asm, "\t$Rd, $Rn, $Rm$shift_imm", "", []>, Sched<[]> { 13114 bits<5> Rd; 13115 bits<5> Rn; 13116 bits<5> Rm; 13117 bits<3> shift_imm; 13118 let Inst{31} = 0b1; 13119 let Inst{30} = isSub; 13120 let Inst{29-21} = 0b011010000; 13121 let Inst{20-16} = Rm; 13122 let Inst{15-13} = 0b001; 13123 let Inst{12-10} = shift_imm; 13124 let Inst{9-5} = Rn; 13125 let Inst{4-0} = Rd; 13126} 13127 13128// Alias for CPA scalar add/subtract with no shift 13129class AddSubCPAAlias<string asm, Instruction inst> 13130 : InstAlias<asm#"\t$Rd, $Rn, $Rm", 13131 (inst GPR64sp:$Rd, GPR64sp:$Rn, GPR64:$Rm, 0)>; 13132 13133multiclass AddSubCPA<bit isSub, string asm> { 13134 def _shift : BaseAddSubCPA<isSub, asm>; 13135 def _noshift : AddSubCPAAlias<asm, !cast<Instruction>(NAME#"_shift")>; 13136} 13137 13138class MulAccumCPA<bit isSub, string asm> 13139 : BaseMulAccum<isSub, 0b011, GPR64, GPR64, asm, []>, Sched<[]> { 13140 let Inst{31} = 0b1; 13141} 13142 13143 13144//---------------------------------------------------------------------------- 13145// 2024 Armv9.6 Extensions 13146//---------------------------------------------------------------------------- 13147 13148//--- 13149// Compare-and-branch instructions. 13150//--- 13151 13152class BaseCmpBranchRegister<RegisterClass regtype, bit sf, bits<3> cc, 13153 bits<2>sz, string asm> 13154 : I<(outs), (ins regtype:$Rt, regtype:$Rm, am_brcmpcond:$target), 13155 asm, "\t$Rt, $Rm, $target", "", 13156 []>, 13157 Sched<[WriteBr]> { 13158 let isBranch = 1; 13159 let isTerminator = 1; 13160 13161 bits<5> Rm; 13162 bits<5> Rt; 13163 bits<9> target; 13164 let Inst{31} = sf; 13165 let Inst{30-24} = 0b1110100; 13166 let Inst{23-21} = cc; 13167 let Inst{20-16} = Rm; 13168 let Inst{15-14} = sz; 13169 let Inst{13-5} = target; 13170 let Inst{4-0} = Rt; 13171} 13172 13173multiclass CmpBranchRegister<bits<3> cc, string asm> { 13174 def Wrr : BaseCmpBranchRegister<GPR32, 0b0, cc, 0b00, asm>; 13175 def Xrr : BaseCmpBranchRegister<GPR64, 0b1, cc, 0b00, asm>; 13176} 13177 13178class BaseCmpBranchImmediate<RegisterClass regtype, bit sf, bits<3> cc, 13179 Operand imm_ty, string asm> 13180 : I<(outs), (ins regtype:$Rt, imm_ty:$imm, am_brcmpcond:$target), 13181 asm, "\t$Rt, $imm, $target", "", 13182 []>, 13183 Sched<[WriteBr]> { 13184 let isBranch = 1; 13185 let isTerminator = 1; 13186 13187 bits<5> Rt; 13188 bits<6> imm; 13189 bits<9> target; 13190 let Inst{31} = sf; 13191 let Inst{30-24} = 0b1110101; 13192 let Inst{23-21} = cc; 13193 let Inst{20-15} = imm; 13194 let Inst{14} = 0b0; 13195 let Inst{13-5} = target; 13196 let Inst{4-0} = Rt; 13197} 13198 13199multiclass CmpBranchImmediate<bits<3> cc, string imm_ty, string asm> { 13200 def Wri : BaseCmpBranchImmediate<GPR32, 0b0, cc, !cast<Operand>(imm_ty # "_32b"), asm>; 13201 def Xri : BaseCmpBranchImmediate<GPR64, 0b1, cc, !cast<Operand>(imm_ty # "_64b"), asm>; 13202} 13203 13204multiclass CmpBranchImmediateAlias<string mnemonic, string insn, string imm_ty> { 13205 def : InstAlias<mnemonic # "\t$Rt, $imm, $target", 13206 (!cast<Instruction>(insn # "Wri") GPR32:$Rt, 13207 !cast<Operand>(imm_ty # "_32b"):$imm, 13208 am_brcmpcond:$target), 0>; 13209 def : InstAlias<mnemonic # "\t$Rt, $imm, $target", 13210 (!cast<Instruction>(insn # "Xri") GPR64:$Rt, 13211 !cast<Operand>(imm_ty # "_64b"):$imm, 13212 am_brcmpcond:$target), 0>; 13213} 13214 13215multiclass CmpBranchWRegisterAlias<string mnemonic, string insn> { 13216 def : InstAlias<mnemonic # "\t$Rt, $Rm, $target", 13217 (!cast<Instruction>(insn # "Wrr") GPR32:$Rm, GPR32:$Rt, am_brcmpcond:$target), 0>; 13218} 13219 13220multiclass CmpBranchRegisterAlias<string mnemonic, string insn> { 13221 defm : CmpBranchWRegisterAlias<mnemonic, insn>; 13222 13223 def : InstAlias<mnemonic # "\t$Rt, $Rm, $target", 13224 (!cast<Instruction>(insn # "Xrr") GPR64:$Rm, GPR64:$Rt, am_brcmpcond:$target), 0>; 13225} 13226//---------------------------------------------------------------------------- 13227// Allow the size specifier tokens to be upper case, not just lower. 13228def : TokenAlias<".4B", ".4b">; // Add dot product 13229def : TokenAlias<".8B", ".8b">; 13230def : TokenAlias<".4H", ".4h">; 13231def : TokenAlias<".2S", ".2s">; 13232def : TokenAlias<".1D", ".1d">; 13233def : TokenAlias<".16B", ".16b">; 13234def : TokenAlias<".8H", ".8h">; 13235def : TokenAlias<".4S", ".4s">; 13236def : TokenAlias<".2D", ".2d">; 13237def : TokenAlias<".1Q", ".1q">; 13238def : TokenAlias<".2H", ".2h">; 13239def : TokenAlias<".2B", ".2b">; 13240def : TokenAlias<".B", ".b">; 13241def : TokenAlias<".H", ".h">; 13242def : TokenAlias<".S", ".s">; 13243def : TokenAlias<".D", ".d">; 13244def : TokenAlias<".Q", ".q">; 13245 13246//---------------------------------------------------------------------------- 13247// 2024 Armv9.6 Extensions 13248//---------------------------------------------------------------------------- 13249 13250let mayLoad = 1, mayStore = 1 in 13251class BaseAtomicFPLoad<RegisterClass regtype, bits<2> sz, bits<2> AR, 13252 bits<3> op0, string asm> 13253: I<(outs regtype:$Rt), 13254 (ins regtype:$Rs, GPR64sp:$Rn), 13255 asm, "\t$Rs, $Rt, [$Rn]","", []>, 13256 Sched<[]> { 13257 bits<5> Rt; 13258 bits<5> Rs; 13259 bits<5> Rn; 13260 let Inst{31-30} = sz; 13261 let Inst{29-24} = 0b111100; 13262 let Inst{23-22} = AR; 13263 let Inst{21} = 0b1; 13264 let Inst{20-16} = Rs; 13265 let Inst{15} = 0b0; 13266 let Inst{14-12} = op0; 13267 let Inst{11-10} = 0b00; 13268 let Inst{9-5} = Rn; 13269 let Inst{4-0} = Rt; 13270} 13271 13272multiclass AtomicFPLoad<bits<2> AR, bits<3> op0, string asm> { 13273 def D : BaseAtomicFPLoad<FPR64, 0b11, AR, op0, asm>; 13274 def S : BaseAtomicFPLoad<FPR32, 0b10, AR, op0, asm>; 13275 def H : BaseAtomicFPLoad<FPR16, 0b01, AR, op0, asm>; 13276} 13277 13278let mayLoad = 1, mayStore = 1 in 13279class BaseAtomicFPStore<RegisterClass regtype, bits<2> sz, bit R, 13280 bits<3> op0, string asm> 13281: I<(outs), 13282 (ins regtype:$Rs, GPR64sp:$Rn), 13283 asm, "\t$Rs, [$Rn]", 13284 "", []>, 13285 Sched<[]> { 13286 bits<5> Rt; 13287 bits<5> Rs; 13288 bits<5> Rn; 13289 let Inst{31-30} = sz; 13290 let Inst{29-23} = 0b1111000; 13291 let Inst{22} = R; 13292 let Inst{21} = 0b1; 13293 let Inst{20-16} = Rs; 13294 let Inst{15} = 0b1; 13295 let Inst{14-12} = op0; 13296 let Inst{11-10} = 0b00; 13297 let Inst{9-5} = Rn; 13298 let Inst{4-0} = 0b11111; 13299} 13300 13301multiclass AtomicFPStore<bit R, bits<3> op0, string asm> { 13302 def D : BaseAtomicFPStore<FPR64, 0b11, R, op0, asm>; 13303 def S : BaseAtomicFPStore<FPR32, 0b10, R, op0, asm>; 13304 def H : BaseAtomicFPStore<FPR16, 0b01, R, op0, asm>; 13305} 13306 13307class BaseSIMDThreeSameVectorFP8MatrixMul<string asm, bits<2> size, string kind> 13308 : BaseSIMDThreeSameVectorTied<1, 1, {size, 0}, 0b11101, 13309 V128, asm, ".16b", []> { 13310 let AsmString = !strconcat(asm, "{\t$Rd", kind, ", $Rn", ".16b", 13311 ", $Rm", ".16b", "}"); 13312} 13313 13314multiclass SIMDThreeSameVectorFP8MatrixMul<string asm>{ 13315 def v8f16: BaseSIMDThreeSameVectorFP8MatrixMul<asm, 0b00, ".8h">{ 13316 let Predicates = [HasNEON, HasF8F16MM]; 13317 } 13318 def v4f32: BaseSIMDThreeSameVectorFP8MatrixMul<asm, 0b10, ".4s">{ 13319 let Predicates = [HasNEON, HasF8F32MM]; 13320 } 13321} 13322 13323