1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// Describe AArch64 instructions format here 11// 12 13// Format specifies the encoding used by the instruction. This is part of the 14// ad-hoc solution used to emit machine instruction encodings by our machine 15// code emitter. 16class Format<bits<2> val> { 17 bits<2> Value = val; 18} 19 20def PseudoFrm : Format<0>; 21def NormalFrm : Format<1>; // Do we need any others? 22 23// Enum describing whether an instruction is 24// destructive in its first source operand. 25class DestructiveInstTypeEnum<bits<4> val> { 26 bits<4> Value = val; 27} 28def NotDestructive : DestructiveInstTypeEnum<0>; 29// Destructive in its first operand and can be MOVPRFX'd, but has no other 30// special properties. 31def DestructiveOther : DestructiveInstTypeEnum<1>; 32def DestructiveUnary : DestructiveInstTypeEnum<2>; 33def DestructiveBinaryImm : DestructiveInstTypeEnum<3>; 34def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>; 35def DestructiveBinary : DestructiveInstTypeEnum<5>; 36def DestructiveBinaryComm : DestructiveInstTypeEnum<6>; 37def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>; 38def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>; 39def DestructiveUnaryPassthru : DestructiveInstTypeEnum<9>; 40 41class FalseLanesEnum<bits<2> val> { 42 bits<2> Value = val; 43} 44def FalseLanesNone : FalseLanesEnum<0>; 45def FalseLanesZero : FalseLanesEnum<1>; 46def FalseLanesUndef : FalseLanesEnum<2>; 47 48class SMEMatrixTypeEnum<bits<3> val> { 49 bits<3> Value = val; 50} 51def SMEMatrixNone : SMEMatrixTypeEnum<0>; 52def SMEMatrixTileB : SMEMatrixTypeEnum<1>; 53def SMEMatrixTileH : SMEMatrixTypeEnum<2>; 54def SMEMatrixTileS : SMEMatrixTypeEnum<3>; 55def SMEMatrixTileD : SMEMatrixTypeEnum<4>; 56def SMEMatrixTileQ : SMEMatrixTypeEnum<5>; 57def SMEMatrixArray : SMEMatrixTypeEnum<6>; 58 59// AArch64 Instruction Format 60class AArch64Inst<Format f, string cstr> : Instruction { 61 field bits<32> Inst; // Instruction encoding. 62 // Mask of bits that cause an encoding to be UNPREDICTABLE. 63 // If a bit is set, then if the corresponding bit in the 64 // target encoding differs from its value in the "Inst" field, 65 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 66 field bits<32> Unpredictable = 0; 67 // SoftFail is the generic name for this field, but we alias it so 68 // as to make it more obvious what it means in ARM-land. 69 field bits<32> SoftFail = Unpredictable; 70 let Namespace = "AArch64"; 71 Format F = f; 72 bits<2> Form = F.Value; 73 74 // Defaults 75 bit isWhile = 0; 76 bit isPTestLike = 0; 77 FalseLanesEnum FalseLanes = FalseLanesNone; 78 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 79 SMEMatrixTypeEnum SMEMatrixType = SMEMatrixNone; 80 ElementSizeEnum ElementSize = ElementSizeNone; 81 82 let TSFlags{13-11} = SMEMatrixType.Value; 83 let TSFlags{10} = isPTestLike; 84 let TSFlags{9} = isWhile; 85 let TSFlags{8-7} = FalseLanes.Value; 86 let TSFlags{6-3} = DestructiveInstType.Value; 87 let TSFlags{2-0} = ElementSize.Value; 88 89 let Pattern = []; 90 let Constraints = cstr; 91} 92 93class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 94 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 95 96// Pseudo instructions (don't have encoding information) 97class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 98 : AArch64Inst<PseudoFrm, cstr> { 99 dag OutOperandList = oops; 100 dag InOperandList = iops; 101 let Pattern = pattern; 102 let isCodeGenOnly = 1; 103 let isPseudo = 1; 104} 105 106// Real instructions (have encoding information) 107class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 108 let Pattern = pattern; 109 let Size = 4; 110} 111 112// Normal instructions 113class I<dag oops, dag iops, string asm, string operands, string cstr, 114 list<dag> pattern> 115 : EncodedI<cstr, pattern> { 116 dag OutOperandList = oops; 117 dag InOperandList = iops; 118 let AsmString = !strconcat(asm, operands); 119} 120 121class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 122class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 123class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 124 125// Helper fragment for an extract of the high portion of a 128-bit vector. The 126// ComplexPattern match both extract_subvector and bitcast(extract_subvector(..)). 127def extract_high_v16i8 : 128 ComplexPattern<v8i8, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 129def extract_high_v8i16 : 130 ComplexPattern<v4i16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 131def extract_high_v4i32 : 132 ComplexPattern<v2i32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 133def extract_high_v2i64 : 134 ComplexPattern<v1i64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 135 136def extract_high_v8f16 : 137 ComplexPattern<v4f16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 138def extract_high_v4f32 : 139 ComplexPattern<v2f32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 140 141def gi_extract_high_v8f16 : 142 GIComplexOperandMatcher<v4s16, "selectExtractHigh">, 143 GIComplexPatternEquiv<extract_high_v8f16>; 144def gi_extract_high_v4f32 : 145 GIComplexOperandMatcher<v2s32, "selectExtractHigh">, 146 GIComplexPatternEquiv<extract_high_v4f32>; 147 148def extract_high_dup_v8i16 : 149 BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>; 150def extract_high_dup_v4i32 : 151 BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>; 152 153def dup_v8i16 : 154 PatFrags<(ops node:$LHS, node:$RHS), 155 [(v4i16 (extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 0))), 156 (v4i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS))]>; 157def dup_v4i32 : 158 PatFrags<(ops node:$LHS, node:$RHS), 159 [(v2i32 (extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 0))), 160 (v2i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS))]>; 161def dup_v8f16 : 162 PatFrags<(ops node:$LHS, node:$RHS), 163 [(v4f16 (extract_subvector (v8f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS)), (i64 0))), 164 (v4f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS))]>; 165def dup_v4f32 : 166 PatFrags<(ops node:$LHS, node:$RHS), 167 [(v2f32 (extract_subvector (v4f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS)), (i64 0))), 168 (v2f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS))]>; 169 170//===----------------------------------------------------------------------===// 171// Asm Operand Classes. 172// 173 174// Shifter operand for arithmetic shifted encodings. 175def ShifterOperand : AsmOperandClass { 176 let Name = "Shifter"; 177} 178 179// Shifter operand for mov immediate encodings. 180def MovImm32ShifterOperand : AsmOperandClass { 181 let SuperClasses = [ShifterOperand]; 182 let Name = "MovImm32Shifter"; 183 let RenderMethod = "addShifterOperands"; 184 let DiagnosticType = "InvalidMovImm32Shift"; 185} 186def MovImm64ShifterOperand : AsmOperandClass { 187 let SuperClasses = [ShifterOperand]; 188 let Name = "MovImm64Shifter"; 189 let RenderMethod = "addShifterOperands"; 190 let DiagnosticType = "InvalidMovImm64Shift"; 191} 192 193// Shifter operand for arithmetic register shifted encodings. 194class ArithmeticShifterOperand<int width> : AsmOperandClass { 195 let SuperClasses = [ShifterOperand]; 196 let Name = "ArithmeticShifter" # width; 197 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 198 let RenderMethod = "addShifterOperands"; 199 let DiagnosticType = "AddSubRegShift" # width; 200} 201 202def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 203def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 204 205// Shifter operand for logical register shifted encodings. 206class LogicalShifterOperand<int width> : AsmOperandClass { 207 let SuperClasses = [ShifterOperand]; 208 let Name = "LogicalShifter" # width; 209 let PredicateMethod = "isLogicalShifter<" # width # ">"; 210 let RenderMethod = "addShifterOperands"; 211 let DiagnosticType = "AddSubRegShift" # width; 212} 213 214def LogicalShifterOperand32 : LogicalShifterOperand<32>; 215def LogicalShifterOperand64 : LogicalShifterOperand<64>; 216 217// Shifter operand for logical vector 128/64-bit shifted encodings. 218def LogicalVecShifterOperand : AsmOperandClass { 219 let SuperClasses = [ShifterOperand]; 220 let Name = "LogicalVecShifter"; 221 let RenderMethod = "addShifterOperands"; 222} 223def LogicalVecHalfWordShifterOperand : AsmOperandClass { 224 let SuperClasses = [LogicalVecShifterOperand]; 225 let Name = "LogicalVecHalfWordShifter"; 226 let RenderMethod = "addShifterOperands"; 227} 228 229// The "MSL" shifter on the vector MOVI instruction. 230def MoveVecShifterOperand : AsmOperandClass { 231 let SuperClasses = [ShifterOperand]; 232 let Name = "MoveVecShifter"; 233 let RenderMethod = "addShifterOperands"; 234} 235 236// Extend operand for arithmetic encodings. 237def ExtendOperand : AsmOperandClass { 238 let Name = "Extend"; 239 let DiagnosticType = "AddSubRegExtendLarge"; 240} 241def ExtendOperand64 : AsmOperandClass { 242 let SuperClasses = [ExtendOperand]; 243 let Name = "Extend64"; 244 let DiagnosticType = "AddSubRegExtendSmall"; 245} 246// 'extend' that's a lsl of a 64-bit register. 247def ExtendOperandLSL64 : AsmOperandClass { 248 let SuperClasses = [ExtendOperand]; 249 let Name = "ExtendLSL64"; 250 let RenderMethod = "addExtend64Operands"; 251 let DiagnosticType = "AddSubRegExtendLarge"; 252} 253 254// 8-bit floating-point immediate encodings. 255def FPImmOperand : AsmOperandClass { 256 let Name = "FPImm"; 257 let ParserMethod = "tryParseFPImm<true>"; 258 let DiagnosticType = "InvalidFPImm"; 259} 260 261def CondCode : AsmOperandClass { 262 let Name = "CondCode"; 263 let DiagnosticType = "InvalidCondCode"; 264} 265 266// A 32-bit register pasrsed as 64-bit 267def GPR32as64Operand : AsmOperandClass { 268 let Name = "GPR32as64"; 269 let ParserMethod = 270 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 271} 272def GPR32as64 : RegisterOperand<GPR32> { 273 let ParserMatchClass = GPR32as64Operand; 274} 275 276// A 64-bit register pasrsed as 32-bit 277def GPR64as32Operand : AsmOperandClass { 278 let Name = "GPR64as32"; 279 let ParserMethod = 280 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 281} 282def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 283 let ParserMatchClass = GPR64as32Operand; 284} 285 286// 8-bit immediate for AdvSIMD where 64-bit values of the form: 287// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 288// are encoded as the eight bit value 'abcdefgh'. 289def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 290 291class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 292 let Name = "UImm" # Width # "s" # Scale; 293 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 294 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 295 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 296} 297 298class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 299 let Name = "SImm" # Width # "s" # Scale; 300 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 301 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 302 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 303} 304 305//===----------------------------------------------------------------------===// 306// Operand Definitions. 307// 308 309// ADR[P] instruction labels. 310def AdrpOperand : AsmOperandClass { 311 let Name = "AdrpLabel"; 312 let ParserMethod = "tryParseAdrpLabel"; 313 let DiagnosticType = "InvalidLabel"; 314} 315def adrplabel : Operand<i64> { 316 let EncoderMethod = "getAdrLabelOpValue"; 317 let PrintMethod = "printAdrAdrpLabel"; 318 let ParserMatchClass = AdrpOperand; 319 let OperandType = "OPERAND_PCREL"; 320} 321 322def AdrOperand : AsmOperandClass { 323 let Name = "AdrLabel"; 324 let ParserMethod = "tryParseAdrLabel"; 325 let DiagnosticType = "InvalidLabel"; 326} 327def adrlabel : Operand<i64> { 328 let EncoderMethod = "getAdrLabelOpValue"; 329 let PrintMethod = "printAdrAdrpLabel"; 330 let ParserMatchClass = AdrOperand; 331 let OperandType = "OPERAND_PCREL"; 332} 333 334class SImmOperand<int width> : AsmOperandClass { 335 let Name = "SImm" # width; 336 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 337 let RenderMethod = "addImmOperands"; 338 let PredicateMethod = "isSImm<" # width # ">"; 339} 340 341class AsmImmRange<int Low, int High> : AsmOperandClass { 342 let Name = "Imm" # Low # "_" # High; 343 let DiagnosticType = "InvalidImm" # Low # "_" # High; 344 let RenderMethod = "addImmOperands"; 345 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 346} 347 348// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 349def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 350def simm10Scaled : Operand<i64> { 351 let ParserMatchClass = SImm10s8Operand; 352 let DecoderMethod = "DecodeSImm<10>"; 353 let PrintMethod = "printImmScale<8>"; 354} 355 356def simm9s16 : Operand<i64> { 357 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 358 let DecoderMethod = "DecodeSImm<9>"; 359 let PrintMethod = "printImmScale<16>"; 360} 361 362// uimm6 predicate - True if the immediate is in the range [0, 63]. 363def UImm6Operand : AsmOperandClass { 364 let Name = "UImm6"; 365 let DiagnosticType = "InvalidImm0_63"; 366} 367 368def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 369 let ParserMatchClass = UImm6Operand; 370} 371 372def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 373 let ParserMatchClass = AsmImmRange<0, 65535>; 374} 375 376def SImm9Operand : SImmOperand<9>; 377def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 378 let ParserMatchClass = SImm9Operand; 379 let DecoderMethod = "DecodeSImm<9>"; 380} 381 382// imm0_255 predicate - True if the immediate is in the range [0,255]. 383def Imm0_255Operand : AsmImmRange<0,255>; 384 385def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 386 let ParserMatchClass = Imm0_255Operand; 387} 388def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> { 389 let ParserMatchClass = Imm0_255Operand; 390} 391 392def SImm8Operand : SImmOperand<8>; 393def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 394 let ParserMatchClass = SImm8Operand; 395 let DecoderMethod = "DecodeSImm<8>"; 396} 397def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> { 398 let ParserMatchClass = SImm8Operand; 399 let DecoderMethod = "DecodeSImm<8>"; 400} 401 402def SImm6Operand : SImmOperand<6>; 403def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 404 let ParserMatchClass = SImm6Operand; 405 let DecoderMethod = "DecodeSImm<6>"; 406} 407 408def SImm5Operand : SImmOperand<5>; 409def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 410 let ParserMatchClass = SImm5Operand; 411 let DecoderMethod = "DecodeSImm<5>"; 412} 413 414def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 415 let ParserMatchClass = SImm5Operand; 416 let DecoderMethod = "DecodeSImm<5>"; 417} 418 419def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 420 let ParserMatchClass = SImm5Operand; 421 let DecoderMethod = "DecodeSImm<5>"; 422 let PrintMethod = "printSImm<8>"; 423} 424 425def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 426 let ParserMatchClass = SImm5Operand; 427 let DecoderMethod = "DecodeSImm<5>"; 428 let PrintMethod = "printSImm<16>"; 429} 430 431// simm7sN predicate - True if the immediate is a multiple of N in the range 432// [-64 * N, 63 * N]. 433 434def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 435def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 436def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 437 438def simm7s4 : Operand<i32> { 439 let ParserMatchClass = SImm7s4Operand; 440 let PrintMethod = "printImmScale<4>"; 441} 442 443def simm7s8 : Operand<i32> { 444 let ParserMatchClass = SImm7s8Operand; 445 let PrintMethod = "printImmScale<8>"; 446} 447 448def simm7s16 : Operand<i32> { 449 let ParserMatchClass = SImm7s16Operand; 450 let PrintMethod = "printImmScale<16>"; 451} 452 453def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>; 454 455def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>; 456def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>; 457def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>; 458def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>; 459def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>; 460 461def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>; 462def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>; 463 464def UImmS1XForm : SDNodeXForm<imm, [{ 465 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 466}]>; 467def UImmS2XForm : SDNodeXForm<imm, [{ 468 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 469}]>; 470def UImmS4XForm : SDNodeXForm<imm, [{ 471 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 472}]>; 473def UImmS8XForm : SDNodeXForm<imm, [{ 474 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 475}]>; 476 477// uimm5sN predicate - True if the immediate is a multiple of N in the range 478// [0 * N, 32 * N]. 479def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 480def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 481def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 482 483def uimm5s2 : Operand<i64>, ImmLeaf<i64, 484 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 485 UImmS2XForm> { 486 let ParserMatchClass = UImm5s2Operand; 487 let PrintMethod = "printImmScale<2>"; 488} 489def uimm5s4 : Operand<i64>, ImmLeaf<i64, 490 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 491 UImmS4XForm> { 492 let ParserMatchClass = UImm5s4Operand; 493 let PrintMethod = "printImmScale<4>"; 494} 495def uimm5s8 : Operand<i64>, ImmLeaf<i64, 496 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 497 UImmS8XForm> { 498 let ParserMatchClass = UImm5s8Operand; 499 let PrintMethod = "printImmScale<8>"; 500} 501 502// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 503// instead of ImmLeaf (Constant) 504def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 505 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 506 UImmS2XForm> { 507 let ParserMatchClass = UImm5s2Operand; 508 let PrintMethod = "printImmScale<2>"; 509} 510def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 511 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 512 UImmS4XForm> { 513 let ParserMatchClass = UImm5s4Operand; 514 let PrintMethod = "printImmScale<4>"; 515} 516def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 517 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 518 UImmS8XForm> { 519 let ParserMatchClass = UImm5s8Operand; 520 let PrintMethod = "printImmScale<8>"; 521} 522 523// uimm6sN predicate - True if the immediate is a multiple of N in the range 524// [0 * N, 64 * N]. 525def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 526def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 527def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 528def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 529def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 530 531def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 532 let ParserMatchClass = UImm6s1Operand; 533} 534def uimm6s2 : Operand<i64>, ImmLeaf<i64, 535[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 536 let PrintMethod = "printImmScale<2>"; 537 let ParserMatchClass = UImm6s2Operand; 538} 539def uimm6s4 : Operand<i64>, ImmLeaf<i64, 540[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 541 let PrintMethod = "printImmScale<4>"; 542 let ParserMatchClass = UImm6s4Operand; 543} 544def uimm6s8 : Operand<i64>, ImmLeaf<i64, 545[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 546 let PrintMethod = "printImmScale<8>"; 547 let ParserMatchClass = UImm6s8Operand; 548} 549def uimm6s16 : Operand<i64>, ImmLeaf<i64, 550[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 551 let PrintMethod = "printImmScale<16>"; 552 let ParserMatchClass = UImm6s16Operand; 553} 554 555def SImmS2XForm : SDNodeXForm<imm, [{ 556 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 557}]>; 558def SImmS3XForm : SDNodeXForm<imm, [{ 559 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 560}]>; 561def SImmS4XForm : SDNodeXForm<imm, [{ 562 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 563}]>; 564def SImmS16XForm : SDNodeXForm<imm, [{ 565 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 566}]>; 567def SImmS32XForm : SDNodeXForm<imm, [{ 568 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 569}]>; 570 571// simm6sN predicate - True if the immediate is a multiple of N in the range 572// [-32 * N, 31 * N]. 573def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 574def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 575 let ParserMatchClass = SImm6s1Operand; 576 let DecoderMethod = "DecodeSImm<6>"; 577} 578 579// simm4sN predicate - True if the immediate is a multiple of N in the range 580// [ -8* N, 7 * N]. 581def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 582def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 583def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 584def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 585def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 586def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 587 588def simm4s1 : Operand<i64>, ImmLeaf<i64, 589[{ return Imm >=-8 && Imm <= 7; }]> { 590 let ParserMatchClass = SImm4s1Operand; 591 let DecoderMethod = "DecodeSImm<4>"; 592} 593 594def simm4s2 : Operand<i64>, ImmLeaf<i64, 595[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 596 let PrintMethod = "printImmScale<2>"; 597 let ParserMatchClass = SImm4s2Operand; 598 let DecoderMethod = "DecodeSImm<4>"; 599} 600 601def simm4s3 : Operand<i64>, ImmLeaf<i64, 602[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 603 let PrintMethod = "printImmScale<3>"; 604 let ParserMatchClass = SImm4s3Operand; 605 let DecoderMethod = "DecodeSImm<4>"; 606} 607 608def simm4s4 : Operand<i64>, ImmLeaf<i64, 609[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 610 let PrintMethod = "printImmScale<4>"; 611 let ParserMatchClass = SImm4s4Operand; 612 let DecoderMethod = "DecodeSImm<4>"; 613} 614def simm4s16 : Operand<i64>, ImmLeaf<i64, 615[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 616 let PrintMethod = "printImmScale<16>"; 617 let ParserMatchClass = SImm4s16Operand; 618 let DecoderMethod = "DecodeSImm<4>"; 619} 620def simm4s32 : Operand<i64>, ImmLeaf<i64, 621[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 622 let PrintMethod = "printImmScale<32>"; 623 let ParserMatchClass = SImm4s32Operand; 624 let DecoderMethod = "DecodeSImm<4>"; 625} 626 627def Imm1_8Operand : AsmImmRange<1, 8>; 628def Imm1_16Operand : AsmImmRange<1, 16>; 629def Imm1_32Operand : AsmImmRange<1, 32>; 630def Imm1_64Operand : AsmImmRange<1, 64>; 631 632class BranchTarget<int N> : AsmOperandClass { 633 let Name = "BranchTarget" # N; 634 let DiagnosticType = "InvalidLabel"; 635 let PredicateMethod = "isBranchTarget<" # N # ">"; 636} 637 638class PCRelLabel<int N> : BranchTarget<N> { 639 let Name = "PCRelLabel" # N; 640} 641 642def BranchTarget14Operand : BranchTarget<14>; 643def BranchTarget26Operand : BranchTarget<26>; 644def PCRelLabel19Operand : PCRelLabel<19>; 645 646def MovWSymbolG3AsmOperand : AsmOperandClass { 647 let Name = "MovWSymbolG3"; 648 let RenderMethod = "addImmOperands"; 649} 650 651def movw_symbol_g3 : Operand<i32> { 652 let ParserMatchClass = MovWSymbolG3AsmOperand; 653} 654 655def MovWSymbolG2AsmOperand : AsmOperandClass { 656 let Name = "MovWSymbolG2"; 657 let RenderMethod = "addImmOperands"; 658} 659 660def movw_symbol_g2 : Operand<i32> { 661 let ParserMatchClass = MovWSymbolG2AsmOperand; 662} 663 664def MovWSymbolG1AsmOperand : AsmOperandClass { 665 let Name = "MovWSymbolG1"; 666 let RenderMethod = "addImmOperands"; 667} 668 669def movw_symbol_g1 : Operand<i32> { 670 let ParserMatchClass = MovWSymbolG1AsmOperand; 671} 672 673def MovWSymbolG0AsmOperand : AsmOperandClass { 674 let Name = "MovWSymbolG0"; 675 let RenderMethod = "addImmOperands"; 676} 677 678def movw_symbol_g0 : Operand<i32> { 679 let ParserMatchClass = MovWSymbolG0AsmOperand; 680} 681 682class fixedpoint_i32<ValueType FloatVT> 683 : Operand<FloatVT>, 684 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 685 let EncoderMethod = "getFixedPointScaleOpValue"; 686 let DecoderMethod = "DecodeFixedPointScaleImm32"; 687 let ParserMatchClass = Imm1_32Operand; 688} 689 690class fixedpoint_i64<ValueType FloatVT> 691 : Operand<FloatVT>, 692 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 693 let EncoderMethod = "getFixedPointScaleOpValue"; 694 let DecoderMethod = "DecodeFixedPointScaleImm64"; 695 let ParserMatchClass = Imm1_64Operand; 696} 697 698def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 699def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 700def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 701 702def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 703def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 704def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 705 706def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 707 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 708}]> { 709 let EncoderMethod = "getVecShiftR8OpValue"; 710 let DecoderMethod = "DecodeVecShiftR8Imm"; 711 let ParserMatchClass = Imm1_8Operand; 712} 713def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 714 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 715}]> { 716 let EncoderMethod = "getVecShiftR16OpValue"; 717 let DecoderMethod = "DecodeVecShiftR16Imm"; 718 let ParserMatchClass = Imm1_16Operand; 719} 720def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 721 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 722}]> { 723 let EncoderMethod = "getVecShiftR16OpValue"; 724 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 725 let ParserMatchClass = Imm1_8Operand; 726} 727def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 728 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 729}]> { 730 let EncoderMethod = "getVecShiftR32OpValue"; 731 let DecoderMethod = "DecodeVecShiftR32Imm"; 732 let ParserMatchClass = Imm1_32Operand; 733} 734def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 735 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 736}]> { 737 let EncoderMethod = "getVecShiftR32OpValue"; 738 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 739 let ParserMatchClass = Imm1_16Operand; 740} 741def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 742 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 743}]> { 744 let EncoderMethod = "getVecShiftR64OpValue"; 745 let DecoderMethod = "DecodeVecShiftR64Imm"; 746 let ParserMatchClass = Imm1_64Operand; 747} 748def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 749 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 750}]> { 751 let EncoderMethod = "getVecShiftR64OpValue"; 752 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 753 let ParserMatchClass = Imm1_32Operand; 754} 755 756// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 757// (ImmLeaf) 758def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 759 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 760}]> { 761 let EncoderMethod = "getVecShiftR8OpValue"; 762 let DecoderMethod = "DecodeVecShiftR8Imm"; 763 let ParserMatchClass = Imm1_8Operand; 764} 765def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 766 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 767}]> { 768 let EncoderMethod = "getVecShiftR16OpValue"; 769 let DecoderMethod = "DecodeVecShiftR16Imm"; 770 let ParserMatchClass = Imm1_16Operand; 771} 772def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 773 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 774}]> { 775 let EncoderMethod = "getVecShiftR32OpValue"; 776 let DecoderMethod = "DecodeVecShiftR32Imm"; 777 let ParserMatchClass = Imm1_32Operand; 778} 779def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 780 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 781}]> { 782 let EncoderMethod = "getVecShiftR64OpValue"; 783 let DecoderMethod = "DecodeVecShiftR64Imm"; 784 let ParserMatchClass = Imm1_64Operand; 785} 786 787def Imm0_0Operand : AsmImmRange<0, 0>; 788def Imm0_1Operand : AsmImmRange<0, 1>; 789def Imm0_3Operand : AsmImmRange<0, 3>; 790def Imm0_7Operand : AsmImmRange<0, 7>; 791def Imm0_15Operand : AsmImmRange<0, 15>; 792def Imm0_31Operand : AsmImmRange<0, 31>; 793def Imm0_63Operand : AsmImmRange<0, 63>; 794 795def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 796 return (((uint32_t)Imm) < 8); 797}]> { 798 let EncoderMethod = "getVecShiftL8OpValue"; 799 let DecoderMethod = "DecodeVecShiftL8Imm"; 800 let ParserMatchClass = Imm0_7Operand; 801} 802def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 803 return (((uint32_t)Imm) < 16); 804}]> { 805 let EncoderMethod = "getVecShiftL16OpValue"; 806 let DecoderMethod = "DecodeVecShiftL16Imm"; 807 let ParserMatchClass = Imm0_15Operand; 808} 809def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 810 return (((uint32_t)Imm) < 32); 811}]> { 812 let EncoderMethod = "getVecShiftL32OpValue"; 813 let DecoderMethod = "DecodeVecShiftL32Imm"; 814 let ParserMatchClass = Imm0_31Operand; 815} 816def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 817 return (((uint32_t)Imm) < 64); 818}]> { 819 let EncoderMethod = "getVecShiftL64OpValue"; 820 let DecoderMethod = "DecodeVecShiftL64Imm"; 821 let ParserMatchClass = Imm0_63Operand; 822} 823 824// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 825// (ImmLeaf) 826def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 827 return (((uint32_t)Imm) < 8); 828}]> { 829 let EncoderMethod = "getVecShiftL8OpValue"; 830 let DecoderMethod = "DecodeVecShiftL8Imm"; 831 let ParserMatchClass = Imm0_7Operand; 832} 833def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 834 return (((uint32_t)Imm) < 16); 835}]> { 836 let EncoderMethod = "getVecShiftL16OpValue"; 837 let DecoderMethod = "DecodeVecShiftL16Imm"; 838 let ParserMatchClass = Imm0_15Operand; 839} 840def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 841 return (((uint32_t)Imm) < 32); 842}]> { 843 let EncoderMethod = "getVecShiftL32OpValue"; 844 let DecoderMethod = "DecodeVecShiftL32Imm"; 845 let ParserMatchClass = Imm0_31Operand; 846} 847def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 848 return (((uint32_t)Imm) < 64); 849}]> { 850 let EncoderMethod = "getVecShiftL64OpValue"; 851 let DecoderMethod = "DecodeVecShiftL64Imm"; 852 let ParserMatchClass = Imm0_63Operand; 853} 854 855// Crazy immediate formats used by 32-bit and 64-bit logical immediate 856// instructions for splatting repeating bit patterns across the immediate. 857def logical_imm32_XFORM : SDNodeXForm<imm, [{ 858 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 859 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 860}]>; 861def logical_imm64_XFORM : SDNodeXForm<imm, [{ 862 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 863 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 864}]>; 865 866def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 867 GISDNodeXFormEquiv<logical_imm32_XFORM>; 868def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 869 GISDNodeXFormEquiv<logical_imm64_XFORM>; 870 871let DiagnosticType = "LogicalSecondSource" in { 872 def LogicalImm32Operand : AsmOperandClass { 873 let Name = "LogicalImm32"; 874 let PredicateMethod = "isLogicalImm<int32_t>"; 875 let RenderMethod = "addLogicalImmOperands<int32_t>"; 876 } 877 def LogicalImm64Operand : AsmOperandClass { 878 let Name = "LogicalImm64"; 879 let PredicateMethod = "isLogicalImm<int64_t>"; 880 let RenderMethod = "addLogicalImmOperands<int64_t>"; 881 } 882 def LogicalImm32NotOperand : AsmOperandClass { 883 let Name = "LogicalImm32Not"; 884 let PredicateMethod = "isLogicalImm<int32_t>"; 885 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 886 } 887 def LogicalImm64NotOperand : AsmOperandClass { 888 let Name = "LogicalImm64Not"; 889 let PredicateMethod = "isLogicalImm<int64_t>"; 890 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 891 } 892} 893 894def Imm0_127Operand : AsmImmRange<0, 127>; 895 896let OperandType = "OPERAND_IMMEDIATE" in { 897 898def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 899 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 900}], logical_imm32_XFORM> { 901 let PrintMethod = "printLogicalImm<int32_t>"; 902 let ParserMatchClass = LogicalImm32Operand; 903} 904def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 905 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 906}], logical_imm64_XFORM> { 907 let PrintMethod = "printLogicalImm<int64_t>"; 908 let ParserMatchClass = LogicalImm64Operand; 909} 910def logical_imm32_not : Operand<i32> { 911 let ParserMatchClass = LogicalImm32NotOperand; 912} 913def logical_imm64_not : Operand<i64> { 914 let ParserMatchClass = LogicalImm64NotOperand; 915} 916 917// immXX_0_65535 predicates - True if the immediate is in the range [0,65535]. 918let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 919def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{ 920 return ((uint32_t)Imm) < 65536; 921}]>; 922 923def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{ 924 return ((uint64_t)Imm) < 65536; 925}]>; 926 927def imm64_0_65535 : Operand<i64>, ImmLeaf<i64, [{ 928 return ((uint64_t)Imm) < 65536; 929}]>; 930} // ParserMatchClass 931 932def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 933 return ((uint32_t)Imm) < 256; 934}]> { 935 let ParserMatchClass = Imm0_255Operand; 936 let PrintMethod = "printImm"; 937} 938 939// imm0_127 predicate - True if the immediate is in the range [0,127] 940def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 941 return ((uint32_t)Imm) < 128; 942}]> { 943 let ParserMatchClass = Imm0_127Operand; 944 let PrintMethod = "printImm"; 945} 946 947def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 948 return ((uint64_t)Imm) < 128; 949}]> { 950 let ParserMatchClass = Imm0_127Operand; 951 let PrintMethod = "printImm"; 952} 953 954// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 955// for all shift-amounts. 956 957// imm0_63 predicate - True if the immediate is in the range [0,63] 958def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 959 return ((uint64_t)Imm) < 64; 960}]> { 961 let ParserMatchClass = Imm0_63Operand; 962} 963 964def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 965 return ((uint64_t)Imm) < 64; 966}]> { 967 let ParserMatchClass = Imm0_63Operand; 968} 969 970// imm0_31 predicate - True if the immediate is in the range [0,31] 971def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 972 return ((uint64_t)Imm) < 32; 973}]> { 974 let ParserMatchClass = Imm0_31Operand; 975} 976 977// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 978// instead of Constant (ImmLeaf) 979def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 980 return ((uint64_t)Imm) < 32; 981}]> { 982 let ParserMatchClass = Imm0_31Operand; 983} 984 985// True if the 32-bit immediate is in the range [0,31] 986def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 987 return ((uint64_t)Imm) < 32; 988}]> { 989 let ParserMatchClass = Imm0_31Operand; 990} 991 992// imm0_1 predicate - True if the immediate is in the range [0,1] 993def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 994 return ((uint64_t)Imm) < 2; 995}]> { 996 let ParserMatchClass = Imm0_1Operand; 997} 998 999// timm0_1 - as above, but use TargetConstant (TImmLeaf) 1000def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 1001 return ((uint64_t)Imm) < 2; 1002}]> { 1003 let ParserMatchClass = Imm0_1Operand; 1004} 1005 1006// timm32_0_1 predicate - True if the 32-bit immediate is in the range [0,1] 1007def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{ 1008 return ((uint32_t)Imm) < 2; 1009}]> { 1010 let ParserMatchClass = Imm0_1Operand; 1011} 1012 1013// imm0_15 predicate - True if the immediate is in the range [0,15] 1014def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 1015 return ((uint64_t)Imm) < 16; 1016}]> { 1017 let ParserMatchClass = Imm0_15Operand; 1018} 1019 1020// imm0_7 predicate - True if the immediate is in the range [0,7] 1021def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 1022 return ((uint64_t)Imm) < 8; 1023}]> { 1024 let ParserMatchClass = Imm0_7Operand; 1025} 1026 1027// imm0_3 predicate - True if the immediate is in the range [0,3] 1028def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 1029 return ((uint64_t)Imm) < 4; 1030}]> { 1031 let ParserMatchClass = Imm0_3Operand; 1032} 1033 1034// timm32_0_3 predicate - True if the 32-bit immediate is in the range [0,3] 1035def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{ 1036 return ((uint32_t)Imm) < 4; 1037}]> { 1038 let ParserMatchClass = Imm0_3Operand; 1039} 1040 1041// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 1042def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 1043 return ((uint32_t)Imm) < 8; 1044}]> { 1045 let ParserMatchClass = Imm0_7Operand; 1046} 1047 1048// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1049def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 1050 return ((uint32_t)Imm) < 16; 1051}]> { 1052 let ParserMatchClass = Imm0_15Operand; 1053} 1054 1055// timm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1056def timm32_0_15 : Operand<i32>, TImmLeaf<i32, [{ 1057 return ((uint32_t)Imm) < 16; 1058}]> { 1059 let ParserMatchClass = Imm0_15Operand; 1060} 1061 1062// timm32_0_31 predicate - True if the 32-bit immediate is in the range [0,31] 1063def timm32_0_31 : Operand<i32>, TImmLeaf<i32, [{ 1064 return ((uint32_t)Imm) < 32; 1065}]> { 1066 let ParserMatchClass = Imm0_31Operand; 1067} 1068 1069// timm32_0_255 predicate - True if the 32-bit immediate is in the range [0,255] 1070def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{ 1071 return ((uint32_t)Imm) < 256; 1072}]> { 1073 let ParserMatchClass = Imm0_255Operand; 1074} 1075 1076} // let OperandType = "OPERAND_IMMEDIATE" 1077 1078// An arithmetic shifter operand: 1079// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 1080// {5-0} - imm6 1081class arith_shift<ValueType Ty, int width> : Operand<Ty> { 1082 let PrintMethod = "printShifter"; 1083 let ParserMatchClass = !cast<AsmOperandClass>( 1084 "ArithmeticShifterOperand" # width); 1085} 1086 1087def arith_shift32 : arith_shift<i32, 32>; 1088def arith_shift64 : arith_shift<i64, 64>; 1089 1090class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 1091 : Operand<Ty>, 1092 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 1093 let PrintMethod = "printShiftedRegister"; 1094 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 1095} 1096 1097def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 1098def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 1099 1100def gi_arith_shifted_reg32 : 1101 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 1102 GIComplexPatternEquiv<arith_shifted_reg32>; 1103 1104def gi_arith_shifted_reg64 : 1105 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1106 GIComplexPatternEquiv<arith_shifted_reg64>; 1107 1108// An arithmetic shifter operand: 1109// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1110// {5-0} - imm6 1111class logical_shift<int width> : Operand<i32> { 1112 let PrintMethod = "printShifter"; 1113 let ParserMatchClass = !cast<AsmOperandClass>( 1114 "LogicalShifterOperand" # width); 1115} 1116 1117def logical_shift32 : logical_shift<32>; 1118def logical_shift64 : logical_shift<64>; 1119 1120class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1121 : Operand<Ty>, 1122 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1123 let PrintMethod = "printShiftedRegister"; 1124 let MIOperandInfo = (ops regclass, shiftop); 1125} 1126 1127def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1128def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1129 1130def gi_logical_shifted_reg32 : 1131 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1132 GIComplexPatternEquiv<logical_shifted_reg32>; 1133 1134def gi_logical_shifted_reg64 : 1135 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1136 GIComplexPatternEquiv<logical_shifted_reg64>; 1137 1138// A logical vector shifter operand: 1139// {7-6} - shift type: 00 = lsl 1140// {5-0} - imm6: #0, #8, #16, or #24 1141def logical_vec_shift : Operand<i32> { 1142 let PrintMethod = "printShifter"; 1143 let EncoderMethod = "getVecShifterOpValue"; 1144 let ParserMatchClass = LogicalVecShifterOperand; 1145} 1146 1147// A logical vector half-word shifter operand: 1148// {7-6} - shift type: 00 = lsl 1149// {5-0} - imm6: #0 or #8 1150def logical_vec_hw_shift : Operand<i32> { 1151 let PrintMethod = "printShifter"; 1152 let EncoderMethod = "getVecShifterOpValue"; 1153 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1154} 1155 1156// A vector move shifter operand: 1157// {0} - imm1: #8 or #16 1158def move_vec_shift : Operand<i32> { 1159 let PrintMethod = "printShifter"; 1160 let EncoderMethod = "getMoveVecShifterOpValue"; 1161 let ParserMatchClass = MoveVecShifterOperand; 1162} 1163 1164let DiagnosticType = "AddSubSecondSource" in { 1165 def AddSubImmOperand : AsmOperandClass { 1166 let Name = "AddSubImm"; 1167 let ParserMethod = "tryParseImmWithOptionalShift"; 1168 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1169 } 1170 def AddSubImmNegOperand : AsmOperandClass { 1171 let Name = "AddSubImmNeg"; 1172 let ParserMethod = "tryParseImmWithOptionalShift"; 1173 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1174 } 1175} 1176// An ADD/SUB immediate shifter operand: 1177// second operand: 1178// {7-6} - shift type: 00 = lsl 1179// {5-0} - imm6: #0 or #12 1180class addsub_shifted_imm<ValueType Ty> 1181 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1182 let PrintMethod = "printAddSubImm"; 1183 let EncoderMethod = "getAddSubImmOpValue"; 1184 let ParserMatchClass = AddSubImmOperand; 1185 let MIOperandInfo = (ops i32imm, i32imm); 1186} 1187 1188class addsub_shifted_imm_neg<ValueType Ty> 1189 : Operand<Ty> { 1190 let EncoderMethod = "getAddSubImmOpValue"; 1191 let ParserMatchClass = AddSubImmNegOperand; 1192 let MIOperandInfo = (ops i32imm, i32imm); 1193} 1194 1195def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1196def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1197def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1198def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1199 1200def gi_addsub_shifted_imm32 : 1201 GIComplexOperandMatcher<s32, "selectArithImmed">, 1202 GIComplexPatternEquiv<addsub_shifted_imm32>; 1203 1204def gi_addsub_shifted_imm64 : 1205 GIComplexOperandMatcher<s64, "selectArithImmed">, 1206 GIComplexPatternEquiv<addsub_shifted_imm64>; 1207 1208class neg_addsub_shifted_imm<ValueType Ty> 1209 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1210 let PrintMethod = "printAddSubImm"; 1211 let EncoderMethod = "getAddSubImmOpValue"; 1212 let ParserMatchClass = AddSubImmOperand; 1213 let MIOperandInfo = (ops i32imm, i32imm); 1214} 1215 1216def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1217def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1218 1219def gi_neg_addsub_shifted_imm32 : 1220 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1221 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1222 1223def gi_neg_addsub_shifted_imm64 : 1224 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1225 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1226 1227// An extend operand: 1228// {5-3} - extend type 1229// {2-0} - imm3 1230def arith_extend : Operand<i32> { 1231 let PrintMethod = "printArithExtend"; 1232 let ParserMatchClass = ExtendOperand; 1233} 1234def arith_extend64 : Operand<i32> { 1235 let PrintMethod = "printArithExtend"; 1236 let ParserMatchClass = ExtendOperand64; 1237} 1238 1239// 'extend' that's a lsl of a 64-bit register. 1240def arith_extendlsl64 : Operand<i32> { 1241 let PrintMethod = "printArithExtend"; 1242 let ParserMatchClass = ExtendOperandLSL64; 1243} 1244 1245class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1246 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1247 let PrintMethod = "printExtendedRegister"; 1248 let MIOperandInfo = (ops GPR32, arith_extend); 1249} 1250 1251class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1252 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1253 let PrintMethod = "printExtendedRegister"; 1254 let MIOperandInfo = (ops GPR32, arith_extend64); 1255} 1256 1257def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1258def gi_arith_extended_reg32_i32 : 1259 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1260 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1261 1262def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1263def gi_arith_extended_reg32_i64 : 1264 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1265 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1266 1267def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1268def gi_arith_extended_reg32to64_i64 : 1269 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1270 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1271 1272def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>; 1273 1274// Floating-point immediate. 1275 1276def fpimm16XForm : SDNodeXForm<fpimm, [{ 1277 APFloat InVal = N->getValueAPF(); 1278 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1279 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1280 }]>; 1281 1282def fpimm32XForm : SDNodeXForm<fpimm, [{ 1283 APFloat InVal = N->getValueAPF(); 1284 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1285 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1286 }]>; 1287 1288def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{ 1289 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF() 1290 .bitcastToAPInt() 1291 .getZExtValue()); 1292 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1293 }]>; 1294 1295def fpimm64XForm : SDNodeXForm<fpimm, [{ 1296 APFloat InVal = N->getValueAPF(); 1297 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1298 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1299 }]>; 1300 1301def fpimm16 : Operand<f16>, 1302 FPImmLeaf<f16, [{ 1303 return AArch64_AM::getFP16Imm(Imm) != -1; 1304 }], fpimm16XForm> { 1305 let ParserMatchClass = FPImmOperand; 1306 let PrintMethod = "printFPImmOperand"; 1307} 1308 1309def fpimmbf16 : Operand<bf16>, 1310 FPImmLeaf<bf16, [{ 1311 return AArch64_AM::getFP16Imm(Imm) != -1; 1312 }], fpimm16XForm>; 1313 1314def fpimm32 : Operand<f32>, 1315 FPImmLeaf<f32, [{ 1316 return AArch64_AM::getFP32Imm(Imm) != -1; 1317 }], fpimm32XForm> { 1318 let ParserMatchClass = FPImmOperand; 1319 let PrintMethod = "printFPImmOperand"; 1320} 1321 1322def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{ 1323 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue(); 1324 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc); 1325 }], fpimm32SIMDModImmType4XForm> { 1326} 1327 1328def fpimm64 : Operand<f64>, 1329 FPImmLeaf<f64, [{ 1330 return AArch64_AM::getFP64Imm(Imm) != -1; 1331 }], fpimm64XForm> { 1332 let ParserMatchClass = FPImmOperand; 1333 let PrintMethod = "printFPImmOperand"; 1334} 1335 1336def fpimm8 : Operand<i32> { 1337 let ParserMatchClass = FPImmOperand; 1338 let PrintMethod = "printFPImmOperand"; 1339} 1340 1341def fpimm0 : FPImmLeaf<fAny, [{ 1342 return Imm.isExactlyValue(+0.0); 1343}]>; 1344 1345def fpimm_minus0 : FPImmLeaf<fAny, [{ 1346 return Imm.isExactlyValue(-0.0); 1347}]>; 1348 1349def fpimm_half : FPImmLeaf<fAny, [{ 1350 return Imm.isExactlyValue(+0.5); 1351}]>; 1352 1353def fpimm_one : FPImmLeaf<fAny, [{ 1354 return Imm.isExactlyValue(+1.0); 1355}]>; 1356 1357def fpimm_two : FPImmLeaf<fAny, [{ 1358 return Imm.isExactlyValue(+2.0); 1359}]>; 1360 1361def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1362 GISDNodeXFormEquiv<fpimm16XForm>; 1363def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1364 GISDNodeXFormEquiv<fpimm32XForm>; 1365def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1366 GISDNodeXFormEquiv<fpimm64XForm>; 1367def gi_fpimm32SIMDModImmType4 : 1368 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1369 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1370 1371// Vector lane operands 1372class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1373 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1374 let DiagnosticType = "Invalid" # Name; 1375 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1376 let RenderMethod = "addVectorIndexOperands"; 1377} 1378 1379class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1380 : Operand<ty> { 1381 let ParserMatchClass = mc; 1382 let PrintMethod = "printVectorIndex"; 1383} 1384 1385multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1386 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1387 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1388} 1389 1390def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1391def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1392def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1393def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1394def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1395def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1396 1397let OperandNamespace = "AArch64" in { 1398 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1399 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1400 [{ return ((uint64_t)Imm) == 0; }]>; 1401 } 1402} 1403defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1404 [{ return ((uint64_t)Imm) == 1; }]>; 1405defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1406 [{ return ((uint64_t)Imm) < 16; }]>; 1407defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1408 [{ return ((uint64_t)Imm) < 8; }]>; 1409defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1410 [{ return ((uint64_t)Imm) < 4; }]>; 1411defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1412 [{ return ((uint64_t)Imm) < 2; }]>; 1413 1414defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1415 [{ return ((uint64_t)Imm) == 1; }]>; 1416defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1417 [{ return ((uint64_t)Imm) < 16; }]>; 1418defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1419 [{ return ((uint64_t)Imm) < 8; }]>; 1420defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1421 [{ return ((uint64_t)Imm) < 4; }]>; 1422defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1423 [{ return ((uint64_t)Imm) < 2; }]>; 1424 1425def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1426def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1427def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1428def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1429def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1430 1431defm sve_elm_idx_extdup_b 1432 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1433 [{ return ((uint64_t)Imm) < 64; }]>; 1434defm sve_elm_idx_extdup_h 1435 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1436 [{ return ((uint64_t)Imm) < 32; }]>; 1437defm sve_elm_idx_extdup_s 1438 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1439 [{ return ((uint64_t)Imm) < 16; }]>; 1440defm sve_elm_idx_extdup_d 1441 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1442 [{ return ((uint64_t)Imm) < 8; }]>; 1443defm sve_elm_idx_extdup_q 1444 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1445 [{ return ((uint64_t)Imm) < 4; }]>; 1446 1447def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{ 1448 return ((uint32_t)Imm) == 0; 1449}]> { 1450 let ParserMatchClass = Imm0_0Operand; 1451 let PrintMethod = "printMatrixIndex"; 1452 let OperandNamespace = "AArch64"; 1453 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1454} 1455def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{ 1456 return ((uint32_t)Imm) <= 1; 1457}]> { 1458 let ParserMatchClass = Imm0_1Operand; 1459 let PrintMethod = "printMatrixIndex"; 1460} 1461def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{ 1462 return ((uint32_t)Imm) <= 3; 1463}]> { 1464 let ParserMatchClass = Imm0_3Operand; 1465 let PrintMethod = "printMatrixIndex"; 1466} 1467def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{ 1468 return ((uint32_t)Imm) <= 7; 1469}]> { 1470 let ParserMatchClass = Imm0_7Operand; 1471 let PrintMethod = "printMatrixIndex"; 1472} 1473def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{ 1474 return ((uint32_t)Imm) <= 15; 1475}]> { 1476 let ParserMatchClass = Imm0_15Operand; 1477 let PrintMethod = "printMatrixIndex"; 1478} 1479 1480// SME2 vector select offset operands 1481 1482// uimm3s8 predicate 1483// True if the immediate is a multiple of 8 in the range [0,56]. 1484def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>; 1485 1486def uimm3s8 : Operand<i64>, ImmLeaf<i64, 1487[{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> { 1488 let PrintMethod = "printVectorIndex<8>"; 1489 let ParserMatchClass = UImm3s8Operand; 1490} 1491 1492class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass { 1493 let Name = "UImm" # Width # "s" # Scale # "Range"; 1494 let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width; 1495 let RenderMethod = "addImmScaledRangeOperands<" # Scale # ">"; 1496 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ", " # OffsetVal # ", /*IsRange=*/true>"; 1497 let ParserMethod = "tryParseImmRange"; 1498} 1499 1500// Implicit immediate ranges 0:1 and 0:3, scale has no meaning 1501// since the immediate is zero 1502def UImm0s2RangeOperand : UImmScaledMemoryIndexedRange<0, 2, 1>; 1503def UImm0s4RangeOperand : UImmScaledMemoryIndexedRange<0, 4, 3>; 1504 1505def UImm1s2RangeOperand : UImmScaledMemoryIndexedRange<1, 2, 1>; 1506def UImm1s4RangeOperand : UImmScaledMemoryIndexedRange<1, 4, 3>; 1507def UImm2s2RangeOperand : UImmScaledMemoryIndexedRange<2, 2, 1>; 1508def UImm2s4RangeOperand : UImmScaledMemoryIndexedRange<2, 4, 3>; 1509def UImm3s2RangeOperand : UImmScaledMemoryIndexedRange<3, 2, 1>; 1510 1511def uimm0s2range : Operand<i64>, ImmLeaf<i64, 1512[{ return Imm == 0; }], UImmS1XForm> { 1513 let PrintMethod = "printImmRangeScale<2, 1>"; 1514 let ParserMatchClass = UImm0s2RangeOperand; 1515 let OperandNamespace = "AArch64"; 1516 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1517} 1518 1519def uimm0s4range : Operand<i64>, ImmLeaf<i64, 1520[{ return Imm == 0; }], UImmS1XForm> { 1521 let PrintMethod = "printImmRangeScale<4, 3>"; 1522 let ParserMatchClass = UImm0s4RangeOperand; 1523 let OperandNamespace = "AArch64"; 1524 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1525} 1526 1527def uimm1s2range : Operand<i64>, ImmLeaf<i64, 1528[{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> { 1529 let PrintMethod = "printImmRangeScale<2, 1>"; 1530 let ParserMatchClass = UImm1s2RangeOperand; 1531} 1532 1533def uimm1s4range : Operand<i64>, ImmLeaf<i64, 1534[{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> { 1535 let PrintMethod = "printImmRangeScale<4, 3>"; 1536 let ParserMatchClass = UImm1s4RangeOperand; 1537} 1538 1539def uimm2s2range : Operand<i64>, ImmLeaf<i64, 1540[{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> { 1541 let PrintMethod = "printImmRangeScale<2, 1>"; 1542 let ParserMatchClass = UImm2s2RangeOperand; 1543} 1544 1545def uimm2s4range : Operand<i64>, ImmLeaf<i64, 1546[{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> { 1547 let PrintMethod = "printImmRangeScale<4, 3>"; 1548 let ParserMatchClass = UImm2s4RangeOperand; 1549} 1550 1551def uimm3s2range : Operand<i64>, ImmLeaf<i64, 1552[{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> { 1553 let PrintMethod = "printImmRangeScale<2, 1>"; 1554 let ParserMatchClass = UImm3s2RangeOperand; 1555} 1556 1557 1558// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1559// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1560// are encoded as the eight bit value 'abcdefgh'. 1561def simdimmtype10 : Operand<i32>, 1562 FPImmLeaf<f64, [{ 1563 return AArch64_AM::isAdvSIMDModImmType10( 1564 Imm.bitcastToAPInt().getZExtValue()); 1565 }], SDNodeXForm<fpimm, [{ 1566 APFloat InVal = N->getValueAPF(); 1567 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1568 .bitcastToAPInt() 1569 .getZExtValue()); 1570 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1571 }]>> { 1572 let ParserMatchClass = SIMDImmType10Operand; 1573 let PrintMethod = "printSIMDType10Operand"; 1574} 1575 1576 1577//--- 1578// System management 1579//--- 1580 1581// Base encoding for system instruction operands. 1582let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1583class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1584 list<dag> pattern = []> 1585 : I<oops, iops, asm, operands, "", pattern> { 1586 let Inst{31-22} = 0b1101010100; 1587 let Inst{21} = L; 1588} 1589 1590// System instructions which do not have an Rt register. 1591class SimpleSystemI<bit L, dag iops, string asm, string operands, 1592 list<dag> pattern = []> 1593 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1594 let Inst{4-0} = 0b11111; 1595} 1596 1597// System instructions which have an Rt register. 1598class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1599 list<dag> pattern = []> 1600 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1601 Sched<[WriteSys]> { 1602 bits<5> Rt; 1603 let Inst{4-0} = Rt; 1604} 1605 1606// System instructions for transactional memory extension 1607class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1608 string asm, string operands, list<dag> pattern> 1609 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1610 Sched<[WriteSys]> { 1611 let Inst{20-12} = 0b000110011; 1612 let Inst{11-8} = CRm; 1613 let Inst{7-5} = op2; 1614 let DecoderMethod = ""; 1615 1616 let mayLoad = 1; 1617 let mayStore = 1; 1618} 1619 1620// System instructions for transactional memory - single input operand 1621class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1622 : TMBaseSystemI<0b1, CRm, 0b011, 1623 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1624 bits<5> Rt; 1625 let Inst{4-0} = Rt; 1626} 1627 1628// System instructions that pass a register argument 1629// This class assumes the register is for input rather than output. 1630class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1631 list<dag> pattern = []> 1632 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1633 let Inst{20-12} = 0b000110001; 1634 let Inst{11-8} = CRm; 1635 let Inst{7-5} = Op2; 1636} 1637 1638// System instructions for transactional memory - no operand 1639class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1640 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1641 let Inst{4-0} = 0b11111; 1642} 1643 1644// System instructions for exit from transactions 1645class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1646 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1647 Sched<[WriteSys]> { 1648 bits<16> imm; 1649 let Inst{31-24} = 0b11010100; 1650 let Inst{23-21} = op1; 1651 let Inst{20-5} = imm; 1652 let Inst{4-0} = 0b00000; 1653} 1654 1655// Hint instructions that take both a CRm and a 3-bit immediate. 1656// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1657// model patterns with sufficiently fine granularity 1658let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1659 class HintI<string mnemonic> 1660 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1661 [(int_aarch64_hint imm0_127:$imm)]>, 1662 Sched<[WriteHint]> { 1663 bits <7> imm; 1664 let Inst{20-12} = 0b000110010; 1665 let Inst{11-5} = imm; 1666 } 1667 1668// System instructions taking a single literal operand which encodes into 1669// CRm. op2 differentiates the opcodes. 1670def BarrierAsmOperand : AsmOperandClass { 1671 let Name = "Barrier"; 1672 let ParserMethod = "tryParseBarrierOperand"; 1673} 1674def barrier_op : Operand<i32> { 1675 let PrintMethod = "printBarrierOption"; 1676 let ParserMatchClass = BarrierAsmOperand; 1677} 1678def BarriernXSAsmOperand : AsmOperandClass { 1679 let Name = "BarriernXS"; 1680 let ParserMethod = "tryParseBarriernXSOperand"; 1681} 1682def barrier_nxs_op : Operand<i32> { 1683 let PrintMethod = "printBarriernXSOption"; 1684 let ParserMatchClass = BarriernXSAsmOperand; 1685} 1686class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1687 list<dag> pattern = []> 1688 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1689 Sched<[WriteBarrier]> { 1690 bits<4> CRm; 1691 let Inst{20-12} = 0b000110011; 1692 let Inst{11-8} = CRm; 1693 let Inst{7-5} = opc; 1694} 1695 1696class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1697 : SimpleSystemI<0, (ins), asm, "", pattern>, 1698 Sched<[WriteHint]> { 1699 bits<4> CRm; 1700 let CRm = 0b0011; 1701 let Inst{31-12} = 0b11010101000000110010; 1702 let Inst{11-8} = CRm; 1703 let Inst{7-5} = op2; 1704 let Inst{4-0} = 0b11111; 1705} 1706 1707// MRS/MSR system instructions. These have different operand classes because 1708// a different subset of registers can be accessed through each instruction. 1709def MRSSystemRegisterOperand : AsmOperandClass { 1710 let Name = "MRSSystemRegister"; 1711 let ParserMethod = "tryParseSysReg"; 1712 let DiagnosticType = "MRS"; 1713} 1714// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1715def mrs_sysreg_op : Operand<i32> { 1716 let ParserMatchClass = MRSSystemRegisterOperand; 1717 let DecoderMethod = "DecodeMRSSystemRegister"; 1718 let PrintMethod = "printMRSSystemRegister"; 1719} 1720 1721def MSRSystemRegisterOperand : AsmOperandClass { 1722 let Name = "MSRSystemRegister"; 1723 let ParserMethod = "tryParseSysReg"; 1724 let DiagnosticType = "MSR"; 1725} 1726def msr_sysreg_op : Operand<i32> { 1727 let ParserMatchClass = MSRSystemRegisterOperand; 1728 let DecoderMethod = "DecodeMSRSystemRegister"; 1729 let PrintMethod = "printMSRSystemRegister"; 1730} 1731 1732def PSBHintOperand : AsmOperandClass { 1733 let Name = "PSBHint"; 1734 let ParserMethod = "tryParsePSBHint"; 1735} 1736def psbhint_op : Operand<i32> { 1737 let ParserMatchClass = PSBHintOperand; 1738 let PrintMethod = "printPSBHintOp"; 1739 let MCOperandPredicate = [{ 1740 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1741 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1742 if (!MCOp.isImm()) 1743 return false; 1744 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1745 }]; 1746} 1747 1748def BTIHintOperand : AsmOperandClass { 1749 let Name = "BTIHint"; 1750 let ParserMethod = "tryParseBTIHint"; 1751} 1752def btihint_op : Operand<i32> { 1753 let ParserMatchClass = BTIHintOperand; 1754 let PrintMethod = "printBTIHintOp"; 1755 let MCOperandPredicate = [{ 1756 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1757 if (!MCOp.isImm()) 1758 return false; 1759 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1760 }]; 1761} 1762 1763class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1764 "mrs", "\t$Rt, $systemreg"> { 1765 bits<16> systemreg; 1766 let Inst{20-5} = systemreg; 1767 let DecoderNamespace = "Fallback"; 1768 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1769 // require doing this. The alternative was to explicitly model each one, but 1770 // it feels like it is unnecessary because it seems there are no negative 1771 // consequences setting these flags for all. 1772 let Defs = [NZCV]; 1773} 1774 1775// FIXME: Some of these def NZCV, others don't. Best way to model that? 1776// Explicitly modeling each of the system register as a register class 1777// would do it, but feels like overkill at this point. 1778class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1779 "msr", "\t$systemreg, $Rt"> { 1780 bits<16> systemreg; 1781 let Inst{20-5} = systemreg; 1782 let DecoderNamespace = "Fallback"; 1783} 1784 1785def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1786 let Name = "SystemPStateFieldWithImm0_15"; 1787 let ParserMethod = "tryParseSysReg"; 1788} 1789def pstatefield4_op : Operand<i32> { 1790 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1791 let PrintMethod = "printSystemPStateField"; 1792 let MCOperandPredicate = [{ 1793 if (!MCOp.isImm()) 1794 return false; 1795 return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr; 1796 }]; 1797} 1798 1799// Instructions to modify PSTATE, no input reg 1800let Defs = [NZCV] in 1801class PstateWriteSimple<dag iops, string asm, string operands> 1802 : SimpleSystemI<0, iops, asm, operands> { 1803 1804 let Inst{20-19} = 0b00; 1805 let Inst{15-12} = 0b0100; 1806} 1807 1808class MSRpstateImm0_15 1809 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1810 "\t$pstatefield, $imm">, 1811 Sched<[WriteSys]> { 1812 1813 bits<6> pstatefield; 1814 bits<4> imm; 1815 let Inst{18-16} = pstatefield{5-3}; 1816 let Inst{11-8} = imm; 1817 let Inst{7-5} = pstatefield{2-0}; 1818 1819 let DecoderMethod = "DecodeSystemPStateImm0_15Instruction"; 1820 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1821 // Fail the decoder should attempt to decode the instruction as MSRI. 1822 let hasCompleteDecoder = false; 1823} 1824 1825def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1826 let Name = "SystemPStateFieldWithImm0_1"; 1827 let ParserMethod = "tryParseSysReg"; 1828} 1829def pstatefield1_op : Operand<i32> { 1830 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1831 let PrintMethod = "printSystemPStateField"; 1832 let MCOperandPredicate = [{ 1833 if (!MCOp.isImm()) 1834 return false; 1835 return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr; 1836 }]; 1837} 1838 1839class MSRpstateImm0_1 1840 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1841 "\t$pstatefield, $imm">, 1842 Sched<[WriteSys]> { 1843 1844 bits<9> pstatefield; 1845 bit imm; 1846 let Inst{18-16} = pstatefield{5-3}; 1847 let Inst{11-9} = pstatefield{8-6}; 1848 let Inst{8} = imm; 1849 let Inst{7-5} = pstatefield{2-0}; 1850 1851 let DecoderMethod = "DecodeSystemPStateImm0_1Instruction"; 1852 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1853 // Fail the decoder should attempt to decode the instruction as MSRI. 1854 let hasCompleteDecoder = false; 1855 let DecoderNamespace = "Fallback"; 1856} 1857 1858// SYS and SYSL generic system instructions. 1859def SysCRAsmOperand : AsmOperandClass { 1860 let Name = "SysCR"; 1861 let ParserMethod = "tryParseSysCROperand"; 1862} 1863 1864def sys_cr_op : Operand<i32> { 1865 let PrintMethod = "printSysCROperand"; 1866 let ParserMatchClass = SysCRAsmOperand; 1867} 1868 1869class SystemXtI<bit L, string asm> 1870 : RtSystemI<L, (outs), 1871 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1872 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1873 bits<3> op1; 1874 bits<4> Cn; 1875 bits<4> Cm; 1876 bits<3> op2; 1877 let Inst{20-19} = 0b01; 1878 let Inst{18-16} = op1; 1879 let Inst{15-12} = Cn; 1880 let Inst{11-8} = Cm; 1881 let Inst{7-5} = op2; 1882} 1883 1884class SystemLXtI<bit L, string asm> 1885 : RtSystemI<L, (outs), 1886 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1887 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1888 bits<3> op1; 1889 bits<4> Cn; 1890 bits<4> Cm; 1891 bits<3> op2; 1892 let Inst{20-19} = 0b01; 1893 let Inst{18-16} = op1; 1894 let Inst{15-12} = Cn; 1895 let Inst{11-8} = Cm; 1896 let Inst{7-5} = op2; 1897} 1898 1899def RangePrefetchOperand : AsmOperandClass { 1900 let Name = "RangePrefetch"; 1901 let ParserMethod = "tryParseRPRFMOperand"; 1902 let PredicateMethod = "isPrefetch"; 1903 let RenderMethod = "addPrefetchOperands"; 1904} 1905 1906def rprfop : Operand<i32>, TImmLeaf<i32, [{ 1907 return (((uint32_t)Imm) <= 63); 1908 }]> { 1909 let PrintMethod = "printRPRFMOperand"; 1910 let ParserMatchClass = RangePrefetchOperand; 1911} 1912 1913// Branch (register) instructions: 1914// 1915// case opc of 1916// 0001 blr 1917// 0000 br 1918// 0101 dret 1919// 0100 eret 1920// 0010 ret 1921// otherwise UNDEFINED 1922class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1923 string operands, list<dag> pattern> 1924 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1925 let Inst{31-25} = 0b1101011; 1926 let Inst{24-21} = opc; 1927 let Inst{20-16} = 0b11111; 1928 let Inst{15-10} = 0b000000; 1929 let Inst{4-0} = 0b00000; 1930} 1931 1932class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1933 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1934 bits<5> Rn; 1935 let Inst{9-5} = Rn; 1936} 1937 1938let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1939class SpecialReturn<bits<4> opc, string asm> 1940 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1941 let Inst{9-5} = 0b11111; 1942} 1943 1944let mayLoad = 1 in 1945class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1946 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1947 Sched<[]> { 1948 bits<5> Rn; 1949 bits<5> Rt; 1950 let Inst{31-30} = sz; 1951 let Inst{29-10} = 0b11100010111111110000; 1952 let Inst{9-5} = Rn; 1953 let Inst{4-0} = Rt; 1954} 1955 1956class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1957 list<dag> pattern> 1958 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1959 let isAuthenticated = 1; 1960 let Inst{31-25} = 0b1101011; 1961 let Inst{20-11} = 0b1111100001; 1962 let Inst{10} = M; 1963 let Inst{4-0} = 0b11111; 1964} 1965 1966class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1967 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1968 bits<5> Rn; 1969 bits<5> Rm; 1970 let Inst{24-22} = 0b100; 1971 let Inst{21} = op; 1972 let Inst{9-5} = Rn; 1973 let Inst{4-0} = Rm; 1974} 1975 1976class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1977 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1978 bits<5> Rn; 1979 let Inst{24} = 0; 1980 let Inst{23-21} = opc; 1981 let Inst{9-5} = Rn; 1982} 1983 1984let Uses = [LR,SP] in 1985class AuthReturn<bits<3> op, bits<1> M, string asm> 1986 : AuthBase<M, (outs), (ins), asm, "", []> { 1987 let Inst{24} = 0; 1988 let Inst{23-21} = op; 1989 let Inst{9-0} = 0b1111111111; 1990} 1991 1992let mayLoad = 1 in 1993class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1994 string operands, string cstr> 1995 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1996 bits<10> offset; 1997 bits<5> Rn; 1998 bits<5> Rt; 1999 let isAuthenticated = 1; 2000 let Inst{31-24} = 0b11111000; 2001 let Inst{23} = M; 2002 let Inst{22} = offset{9}; 2003 let Inst{21} = 1; 2004 let Inst{20-12} = offset{8-0}; 2005 let Inst{11} = W; 2006 let Inst{10} = 1; 2007 let Inst{9-5} = Rn; 2008 let Inst{4-0} = Rt; 2009 2010 let DecoderMethod = "DecodeAuthLoadInstruction"; 2011} 2012 2013multiclass AuthLoad<bit M, string asm, Operand opr> { 2014 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 2015 (ins GPR64sp:$Rn, opr:$offset), 2016 asm, "\t$Rt, [$Rn, $offset]", "">; 2017 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 2018 (ins GPR64sp:$Rn, opr:$offset), 2019 asm, "\t$Rt, [$Rn, $offset]!", 2020 "$Rn = $wback,@earlyclobber $wback">; 2021 2022 def : InstAlias<asm # "\t$Rt, [$Rn]", 2023 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 2024 2025 def : InstAlias<asm # "\t$Rt, [$wback]!", 2026 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 2027} 2028 2029//--- 2030// Conditional branch instruction. 2031//--- 2032 2033// Condition code. 2034// 4-bit immediate. Pretty-printed as <cc> 2035def ccode : Operand<i32> { 2036 let PrintMethod = "printCondCode"; 2037 let ParserMatchClass = CondCode; 2038} 2039def inv_ccode : Operand<i32> { 2040 // AL and NV are invalid in the aliases which use inv_ccode 2041 let PrintMethod = "printInverseCondCode"; 2042 let ParserMatchClass = CondCode; 2043 let MCOperandPredicate = [{ 2044 return MCOp.isImm() && 2045 MCOp.getImm() != AArch64CC::AL && 2046 MCOp.getImm() != AArch64CC::NV; 2047 }]; 2048} 2049 2050// Conditional branch target. 19-bit immediate. The low two bits of the target 2051// offset are implied zero and so are not part of the immediate. 2052def am_brcond : Operand<OtherVT> { 2053 let EncoderMethod = "getCondBranchTargetOpValue"; 2054 let DecoderMethod = "DecodePCRelLabel19"; 2055 let PrintMethod = "printAlignedLabel"; 2056 let ParserMatchClass = PCRelLabel19Operand; 2057 let OperandType = "OPERAND_PCREL"; 2058} 2059 2060class BranchCond<bit bit4, string mnemonic> 2061 : I<(outs), (ins ccode:$cond, am_brcond:$target), 2062 mnemonic, ".$cond\t$target", "", 2063 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 2064 let isBranch = 1; 2065 let isTerminator = 1; 2066 let Uses = [NZCV]; 2067 2068 bits<4> cond; 2069 bits<19> target; 2070 let Inst{31-24} = 0b01010100; 2071 let Inst{23-5} = target; 2072 let Inst{4} = bit4; 2073 let Inst{3-0} = cond; 2074} 2075 2076//--- 2077// Compare-and-branch instructions. 2078//--- 2079class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 2080 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 2081 asm, "\t$Rt, $target", "", 2082 [(node regtype:$Rt, bb:$target)]>, 2083 Sched<[WriteBr]> { 2084 let isBranch = 1; 2085 let isTerminator = 1; 2086 2087 bits<5> Rt; 2088 bits<19> target; 2089 let Inst{30-25} = 0b011010; 2090 let Inst{24} = op; 2091 let Inst{23-5} = target; 2092 let Inst{4-0} = Rt; 2093} 2094 2095multiclass CmpBranch<bit op, string asm, SDNode node> { 2096 def W : BaseCmpBranch<GPR32, op, asm, node> { 2097 let Inst{31} = 0; 2098 } 2099 def X : BaseCmpBranch<GPR64, op, asm, node> { 2100 let Inst{31} = 1; 2101 } 2102} 2103 2104//--- 2105// Test-bit-and-branch instructions. 2106//--- 2107// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 2108// the target offset are implied zero and so are not part of the immediate. 2109def am_tbrcond : Operand<OtherVT> { 2110 let EncoderMethod = "getTestBranchTargetOpValue"; 2111 let PrintMethod = "printAlignedLabel"; 2112 let ParserMatchClass = BranchTarget14Operand; 2113 let OperandType = "OPERAND_PCREL"; 2114} 2115 2116// AsmOperand classes to emit (or not) special diagnostics 2117def TBZImm0_31Operand : AsmOperandClass { 2118 let Name = "TBZImm0_31"; 2119 let PredicateMethod = "isImmInRange<0,31>"; 2120 let RenderMethod = "addImmOperands"; 2121} 2122def TBZImm32_63Operand : AsmOperandClass { 2123 let Name = "Imm32_63"; 2124 let PredicateMethod = "isImmInRange<32,63>"; 2125 let DiagnosticType = "InvalidImm0_63"; 2126 let RenderMethod = "addImmOperands"; 2127} 2128 2129class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 2130 return (((uint32_t)Imm) < 32); 2131}]> { 2132 let ParserMatchClass = matcher; 2133} 2134 2135def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 2136def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 2137 2138def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 2139 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 2140}]> { 2141 let ParserMatchClass = TBZImm32_63Operand; 2142} 2143 2144class BaseTestBranch<RegisterClass regtype, Operand immtype, 2145 bit op, string asm, SDNode node> 2146 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 2147 asm, "\t$Rt, $bit_off, $target", "", 2148 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 2149 Sched<[WriteBr]> { 2150 let isBranch = 1; 2151 let isTerminator = 1; 2152 2153 bits<5> Rt; 2154 bits<6> bit_off; 2155 bits<14> target; 2156 2157 let Inst{30-25} = 0b011011; 2158 let Inst{24} = op; 2159 let Inst{23-19} = bit_off{4-0}; 2160 let Inst{18-5} = target; 2161 let Inst{4-0} = Rt; 2162 2163 let DecoderMethod = "DecodeTestAndBranch"; 2164} 2165 2166multiclass TestBranch<bit op, string asm, SDNode node> { 2167 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 2168 let Inst{31} = 0; 2169 } 2170 2171 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 2172 let Inst{31} = 1; 2173 } 2174 2175 // Alias X-reg with 0-31 imm to W-Reg. 2176 def : InstAlias<asm # "\t$Rd, $imm, $target", 2177 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 2178 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 2179 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 2180 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 2181 tbz_imm0_31_diag:$imm, bb:$target)>; 2182} 2183 2184//--- 2185// Unconditional branch (immediate) instructions. 2186//--- 2187def am_b_target : Operand<OtherVT> { 2188 let EncoderMethod = "getBranchTargetOpValue"; 2189 let PrintMethod = "printAlignedLabel"; 2190 let ParserMatchClass = BranchTarget26Operand; 2191 let OperandType = "OPERAND_PCREL"; 2192} 2193def am_bl_target : Operand<i64> { 2194 let EncoderMethod = "getBranchTargetOpValue"; 2195 let PrintMethod = "printAlignedLabel"; 2196 let ParserMatchClass = BranchTarget26Operand; 2197 let OperandType = "OPERAND_PCREL"; 2198} 2199 2200class BImm<bit op, dag iops, string asm, list<dag> pattern> 2201 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 2202 bits<26> addr; 2203 let Inst{31} = op; 2204 let Inst{30-26} = 0b00101; 2205 let Inst{25-0} = addr; 2206 2207 let DecoderMethod = "DecodeUnconditionalBranch"; 2208} 2209 2210class BranchImm<bit op, string asm, list<dag> pattern> 2211 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 2212class CallImm<bit op, string asm, list<dag> pattern> 2213 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2214 2215//--- 2216// Basic one-operand data processing instructions. 2217//--- 2218 2219let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2220class BaseOneOperandData<bit sf, bit S, bits<5> opc2, bits<6> opc, 2221 RegisterClass regtype, string asm, 2222 SDPatternOperator node> 2223 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2224 [(set regtype:$Rd, (node regtype:$Rn))]>, 2225 Sched<[WriteI, ReadI]> { 2226 bits<5> Rd; 2227 bits<5> Rn; 2228 2229 let Inst{31} = sf; 2230 let Inst{30} = 0b1; 2231 let Inst{29} = S; 2232 let Inst{28-21} = 0b11010110; 2233 let Inst{20-16} = opc2; 2234 let Inst{15-10} = opc; 2235 let Inst{9-5} = Rn; 2236 let Inst{4-0} = Rd; 2237} 2238 2239let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2240multiclass OneOperandData<bits<6> opc, string asm, 2241 SDPatternOperator node = null_frag> { 2242 def Wr : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2243 2244 def Xr : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2245} 2246 2247class OneWRegData<bits<6> opc, string asm, SDPatternOperator node> 2248 : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2249 2250class OneXRegData<bits<6> opc, string asm, SDPatternOperator node> 2251 : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2252 2253class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2254 SDPatternOperator op> 2255 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2256 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2257 Sched<[WriteI, ReadI]> { 2258 bits<5> Rd; 2259 bits<5> Rn; 2260 let Inst{31-15} = 0b11011010110000010; 2261 let Inst{14-12} = opcode_prefix; 2262 let Inst{11-10} = opcode; 2263 let Inst{9-5} = Rn; 2264 let Inst{4-0} = Rd; 2265} 2266 2267class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2268 SDPatternOperator op> 2269 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2270 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2271 Sched<[]> { 2272 bits<5> Rd; 2273 let Inst{31-15} = 0b11011010110000010; 2274 let Inst{14-12} = opcode_prefix; 2275 let Inst{11-10} = opcode; 2276 let Inst{9-5} = 0b11111; 2277 let Inst{4-0} = Rd; 2278} 2279 2280class SignAuthTwoOperand<bits<4> opc, string asm, 2281 SDPatternOperator OpNode> 2282 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2283 asm, "\t$Rd, $Rn, $Rm", "", 2284 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2285 Sched<[WriteI, ReadI, ReadI]> { 2286 bits<5> Rd; 2287 bits<5> Rn; 2288 bits<5> Rm; 2289 let Inst{31-21} = 0b10011010110; 2290 let Inst{20-16} = Rm; 2291 let Inst{15-14} = 0b00; 2292 let Inst{13-10} = opc; 2293 let Inst{9-5} = Rn; 2294 let Inst{4-0} = Rd; 2295} 2296 2297class ClearAuth<bits<1> data, string asm> 2298 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2299 bits<5> Rd; 2300 let Inst{31-11} = 0b110110101100000101000; 2301 let Inst{10} = data; 2302 let Inst{9-5} = 0b11111; 2303 let Inst{4-0} = Rd; 2304} 2305 2306// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2307class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2308 : I<(outs), iops, asm, ops, "", []>, 2309 Sched<[WriteI, ReadI, ReadI]> { 2310 let Uses = [NZCV]; 2311 let Defs = [NZCV]; 2312 bits<5> Rn; 2313 let Inst{31} = sf; 2314 let Inst{30-15} = 0b0111010000000000; 2315 let Inst{14} = sz; 2316 let Inst{13-10} = 0b0010; 2317 let Inst{9-5} = Rn; 2318 let Inst{4-0} = 0b01101; 2319} 2320 2321class FlagRotate<dag iops, string asm, string ops> 2322 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2323 bits<6> imm; 2324 bits<4> mask; 2325 let Inst{20-15} = imm; 2326 let Inst{13-10} = 0b0001; 2327 let Inst{4} = 0b0; 2328 let Inst{3-0} = mask; 2329} 2330 2331//--- 2332// Basic two-operand data processing instructions. 2333//--- 2334class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2335 list<dag> pattern> 2336 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2337 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2338 Sched<[WriteI, ReadI, ReadI]> { 2339 let Uses = [NZCV]; 2340 bits<5> Rd; 2341 bits<5> Rn; 2342 bits<5> Rm; 2343 let Inst{30} = isSub; 2344 let Inst{28-21} = 0b11010000; 2345 let Inst{20-16} = Rm; 2346 let Inst{15-10} = 0; 2347 let Inst{9-5} = Rn; 2348 let Inst{4-0} = Rd; 2349} 2350 2351class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2352 SDNode OpNode> 2353 : BaseBaseAddSubCarry<isSub, regtype, asm, 2354 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2355 2356class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2357 SDNode OpNode> 2358 : BaseBaseAddSubCarry<isSub, regtype, asm, 2359 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2360 (implicit NZCV)]> { 2361 let Defs = [NZCV]; 2362} 2363 2364multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2365 SDNode OpNode, SDNode OpNode_setflags> { 2366 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2367 let Inst{31} = 0; 2368 let Inst{29} = 0; 2369 } 2370 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2371 let Inst{31} = 1; 2372 let Inst{29} = 0; 2373 } 2374 2375 // Sets flags. 2376 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2377 OpNode_setflags> { 2378 let Inst{31} = 0; 2379 let Inst{29} = 1; 2380 } 2381 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2382 OpNode_setflags> { 2383 let Inst{31} = 1; 2384 let Inst{29} = 1; 2385 } 2386} 2387 2388class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype, 2389 string asm, SDPatternOperator OpNode, 2390 RegisterClass in1regtype = regtype, 2391 RegisterClass in2regtype = regtype> 2392 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2393 asm, "\t$Rd, $Rn, $Rm", "", 2394 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2395 bits<5> Rd; 2396 bits<5> Rn; 2397 bits<5> Rm; 2398 let Inst{31} = sf; 2399 let Inst{30} = 0b0; 2400 let Inst{29} = S; 2401 let Inst{28-21} = 0b11010110; 2402 let Inst{20-16} = Rm; 2403 let Inst{15-10} = opc; 2404 let Inst{9-5} = Rn; 2405 let Inst{4-0} = Rd; 2406} 2407 2408class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm, 2409 SDPatternOperator OpNode> 2410 : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> { 2411 let Inst{10} = isSigned; 2412} 2413 2414multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2415 def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>, 2416 Sched<[WriteID32, ReadID, ReadID]>; 2417 2418 def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>, 2419 Sched<[WriteID64, ReadID, ReadID]>; 2420} 2421 2422class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm, 2423 SDPatternOperator OpNode = null_frag> 2424 : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>, 2425 Sched<[WriteIS, ReadI]> { 2426 let Inst{11-10} = shift_type; 2427} 2428 2429multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2430 def Wr : BaseShift<0b0, shift_type, GPR32, asm>; 2431 2432 def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>; 2433 2434 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2435 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2436 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2437 2438 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2439 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2440 2441 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2442 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2443 2444 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2445 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2446 2447 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2448 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2449 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2450 2451 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2452 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2453 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2454} 2455 2456class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2457 : InstAlias<asm#"\t$dst, $src1, $src2", 2458 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2459 2460class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2461 RegisterClass addtype, string asm, 2462 list<dag> pattern> 2463 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2464 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2465 bits<5> Rd; 2466 bits<5> Rn; 2467 bits<5> Rm; 2468 bits<5> Ra; 2469 let Inst{30-24} = 0b0011011; 2470 let Inst{23-21} = opc; 2471 let Inst{20-16} = Rm; 2472 let Inst{15} = isSub; 2473 let Inst{14-10} = Ra; 2474 let Inst{9-5} = Rn; 2475 let Inst{4-0} = Rd; 2476} 2477 2478multiclass MulAccum<bit isSub, string asm> { 2479 // MADD/MSUB generation is decided by MachineCombiner.cpp 2480 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2481 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2482 let Inst{31} = 0; 2483 } 2484 2485 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2486 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2487 let Inst{31} = 1; 2488 } 2489} 2490 2491class WideMulAccum<bit isSub, bits<3> opc, string asm, 2492 SDNode AccNode, SDNode ExtNode> 2493 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2494 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2495 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2496 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2497 let Inst{31} = 1; 2498} 2499 2500class MulHi<bits<3> opc, string asm, SDNode OpNode> 2501 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2502 asm, "\t$Rd, $Rn, $Rm", "", 2503 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2504 Sched<[WriteIM64, ReadIM, ReadIM]> { 2505 bits<5> Rd; 2506 bits<5> Rn; 2507 bits<5> Rm; 2508 let Inst{31-24} = 0b10011011; 2509 let Inst{23-21} = opc; 2510 let Inst{20-16} = Rm; 2511 let Inst{15} = 0; 2512 let Inst{9-5} = Rn; 2513 let Inst{4-0} = Rd; 2514 2515 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2516 // (i.e. all bits 1) but is ignored by the processor. 2517 let PostEncoderMethod = "fixMulHigh"; 2518} 2519 2520class MulAccumWAlias<string asm, Instruction inst> 2521 : InstAlias<asm#"\t$dst, $src1, $src2", 2522 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2523class MulAccumXAlias<string asm, Instruction inst> 2524 : InstAlias<asm#"\t$dst, $src1, $src2", 2525 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2526class WideMulAccumAlias<string asm, Instruction inst> 2527 : InstAlias<asm#"\t$dst, $src1, $src2", 2528 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2529 2530class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2531 SDPatternOperator OpNode, string asm> 2532 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2533 asm, "\t$Rd, $Rn, $Rm", "", 2534 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2535 Sched<[WriteISReg, ReadI, ReadISReg]> { 2536 bits<5> Rd; 2537 bits<5> Rn; 2538 bits<5> Rm; 2539 2540 let Inst{31} = sf; 2541 let Inst{30-21} = 0b0011010110; 2542 let Inst{20-16} = Rm; 2543 let Inst{15-13} = 0b010; 2544 let Inst{12} = C; 2545 let Inst{11-10} = sz; 2546 let Inst{9-5} = Rn; 2547 let Inst{4-0} = Rd; 2548 let Predicates = [HasCRC]; 2549} 2550 2551//--- 2552// Address generation. 2553//--- 2554 2555class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2556 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2557 pattern>, 2558 Sched<[WriteI]> { 2559 bits<5> Xd; 2560 bits<21> label; 2561 let Inst{31} = page; 2562 let Inst{30-29} = label{1-0}; 2563 let Inst{28-24} = 0b10000; 2564 let Inst{23-5} = label{20-2}; 2565 let Inst{4-0} = Xd; 2566 2567 let DecoderMethod = "DecodeAdrInstruction"; 2568} 2569 2570//--- 2571// Move immediate. 2572//--- 2573 2574def movimm32_imm : Operand<i32> { 2575 let ParserMatchClass = AsmImmRange<0, 65535>; 2576 let EncoderMethod = "getMoveWideImmOpValue"; 2577 let PrintMethod = "printImm"; 2578} 2579def movimm32_shift : Operand<i32> { 2580 let PrintMethod = "printShifter"; 2581 let ParserMatchClass = MovImm32ShifterOperand; 2582} 2583def movimm64_shift : Operand<i32> { 2584 let PrintMethod = "printShifter"; 2585 let ParserMatchClass = MovImm64ShifterOperand; 2586} 2587 2588let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2589class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2590 string asm> 2591 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2592 asm, "\t$Rd, $imm$shift", "", []>, 2593 Sched<[WriteImm]> { 2594 bits<5> Rd; 2595 bits<16> imm; 2596 bits<6> shift; 2597 let Inst{30-29} = opc; 2598 let Inst{28-23} = 0b100101; 2599 let Inst{22-21} = shift{5-4}; 2600 let Inst{20-5} = imm; 2601 let Inst{4-0} = Rd; 2602 2603 let DecoderMethod = "DecodeMoveImmInstruction"; 2604} 2605 2606multiclass MoveImmediate<bits<2> opc, string asm> { 2607 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2608 let Inst{31} = 0; 2609 } 2610 2611 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2612 let Inst{31} = 1; 2613 } 2614} 2615 2616let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2617class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2618 string asm> 2619 : I<(outs regtype:$Rd), 2620 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2621 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2622 Sched<[WriteI, ReadI]> { 2623 bits<5> Rd; 2624 bits<16> imm; 2625 bits<6> shift; 2626 let Inst{30-29} = opc; 2627 let Inst{28-23} = 0b100101; 2628 let Inst{22-21} = shift{5-4}; 2629 let Inst{20-5} = imm; 2630 let Inst{4-0} = Rd; 2631 2632 let DecoderMethod = "DecodeMoveImmInstruction"; 2633} 2634 2635multiclass InsertImmediate<bits<2> opc, string asm> { 2636 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2637 let Inst{31} = 0; 2638 } 2639 2640 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2641 let Inst{31} = 1; 2642 } 2643} 2644 2645//--- 2646// Add/Subtract 2647//--- 2648 2649class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2650 string asm_inst, string asm_ops, 2651 dag inputs, dag pattern> 2652 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2653 Sched<[WriteI, ReadI]> { 2654 bits<5> Rd; 2655 bits<5> Rn; 2656 let Inst{30} = isSub; 2657 let Inst{29} = setFlags; 2658 let Inst{28-24} = 0b10001; 2659 let Inst{9-5} = Rn; 2660 let Inst{4-0} = Rd; 2661} 2662 2663class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2664 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2665 string asm_inst, SDPatternOperator OpNode> 2666 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2667 (ins srcRegtype:$Rn, immtype:$imm), 2668 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2669 bits<14> imm; 2670 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2671 let Inst{21-10} = imm{11-0}; 2672 let DecoderMethod = "DecodeAddSubImmShift"; 2673} 2674 2675class BaseAddSubRegPseudo<RegisterClass regtype, 2676 SDPatternOperator OpNode> 2677 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2678 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2679 Sched<[WriteI, ReadI, ReadI]>; 2680 2681class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2682 arith_shifted_reg shifted_regtype, string asm, 2683 SDPatternOperator OpNode> 2684 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 2685 asm, "\t$Rd, $Rn, $Rm_and_shift", "", 2686 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>, 2687 Sched<[WriteISReg, ReadI, ReadISReg]> { 2688 bits<5> Rd; 2689 bits<5> Rn; 2690 bits<5> Rm; 2691 bits<8> shift; 2692 let Inst{30} = isSub; 2693 let Inst{29} = setFlags; 2694 let Inst{28-24} = 0b01011; 2695 let Inst{23-22} = shift{7-6}; 2696 let Inst{21} = 0; 2697 let Inst{20-16} = Rm; 2698 let Inst{15-10} = shift{5-0}; 2699 let Inst{9-5} = Rn; 2700 let Inst{4-0} = Rd; 2701 2702 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2703} 2704 2705class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2706 RegisterClass src1Regtype, Operand src2Regtype, 2707 string asm, SDPatternOperator OpNode> 2708 : I<(outs dstRegtype:$Rd), 2709 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend), 2710 asm, "\t$Rd, $Rn, $Rm_and_extend", "", 2711 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>, 2712 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2713 bits<5> Rd; 2714 bits<5> Rn; 2715 bits<5> Rm; 2716 bits<6> extend; 2717 let Inst{30} = isSub; 2718 let Inst{29} = setFlags; 2719 let Inst{28-24} = 0b01011; 2720 let Inst{23-21} = 0b001; 2721 let Inst{20-16} = Rm; 2722 let Inst{15-13} = extend{5-3}; 2723 let Inst{12-10} = extend{2-0}; 2724 let Inst{9-5} = Rn; 2725 let Inst{4-0} = Rd; 2726 2727 let DecoderMethod = "DecodeAddSubERegInstruction"; 2728} 2729 2730let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2731class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2732 RegisterClass src1Regtype, RegisterClass src2Regtype, 2733 Operand ext_op, string asm> 2734 : I<(outs dstRegtype:$Rd), 2735 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2736 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2737 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2738 bits<5> Rd; 2739 bits<5> Rn; 2740 bits<5> Rm; 2741 bits<6> ext; 2742 let Inst{30} = isSub; 2743 let Inst{29} = setFlags; 2744 let Inst{28-24} = 0b01011; 2745 let Inst{23-21} = 0b001; 2746 let Inst{20-16} = Rm; 2747 let Inst{15} = ext{5}; 2748 let Inst{12-10} = ext{2-0}; 2749 let Inst{9-5} = Rn; 2750 let Inst{4-0} = Rd; 2751 2752 let DecoderMethod = "DecodeAddSubERegInstruction"; 2753} 2754 2755// Aliases for register+register add/subtract. 2756class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2757 RegisterClass src1Regtype, RegisterClass src2Regtype, 2758 int shiftExt> 2759 : InstAlias<asm#"\t$dst, $src1, $src2", 2760 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2761 shiftExt)>; 2762 2763multiclass AddSub<bit isSub, string mnemonic, string alias, 2764 SDPatternOperator OpNode = null_frag> { 2765 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2766 // Add/Subtract immediate 2767 // Increase the weight of the immediate variant to try to match it before 2768 // the extended register variant. 2769 // We used to match the register variant before the immediate when the 2770 // register argument could be implicitly zero-extended. 2771 let AddedComplexity = 6 in 2772 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2773 mnemonic, OpNode> { 2774 let Inst{31} = 0; 2775 } 2776 let AddedComplexity = 6 in 2777 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2778 mnemonic, OpNode> { 2779 let Inst{31} = 1; 2780 } 2781 2782 // Add/Subtract register - Only used for CodeGen 2783 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2784 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2785 2786 // Add/Subtract shifted register 2787 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2788 OpNode> { 2789 let Inst{31} = 0; 2790 } 2791 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2792 OpNode> { 2793 let Inst{31} = 1; 2794 } 2795 } 2796 2797 // Add/Subtract extended register 2798 let AddedComplexity = 1, hasSideEffects = 0 in { 2799 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2800 arith_extended_reg32_i32, mnemonic, OpNode> { 2801 let Inst{31} = 0; 2802 } 2803 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2804 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2805 let Inst{31} = 1; 2806 } 2807 } 2808 2809 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2810 arith_extendlsl64, mnemonic> { 2811 // UXTX and SXTX only. 2812 let Inst{14-13} = 0b11; 2813 let Inst{31} = 1; 2814 } 2815 2816 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2817 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2818 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2819 addsub_shifted_imm32_neg:$imm), 0>; 2820 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2821 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2822 addsub_shifted_imm64_neg:$imm), 0>; 2823 2824 // Register/register aliases with no shift when SP is not used. 2825 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2826 GPR32, GPR32, GPR32, 0>; 2827 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2828 GPR64, GPR64, GPR64, 0>; 2829 2830 // Register/register aliases with no shift when either the destination or 2831 // first source register is SP. 2832 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2833 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2834 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2835 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2836 def : AddSubRegAlias<mnemonic, 2837 !cast<Instruction>(NAME#"Xrx64"), 2838 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2839 def : AddSubRegAlias<mnemonic, 2840 !cast<Instruction>(NAME#"Xrx64"), 2841 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2842} 2843 2844multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2845 string alias, string cmpAlias> { 2846 let isCompare = 1, Defs = [NZCV] in { 2847 // Add/Subtract immediate 2848 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2849 mnemonic, OpNode> { 2850 let Inst{31} = 0; 2851 } 2852 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2853 mnemonic, OpNode> { 2854 let Inst{31} = 1; 2855 } 2856 2857 // Add/Subtract register 2858 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2859 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2860 2861 // Add/Subtract shifted register 2862 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2863 OpNode> { 2864 let Inst{31} = 0; 2865 } 2866 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2867 OpNode> { 2868 let Inst{31} = 1; 2869 } 2870 2871 // Add/Subtract extended register 2872 let AddedComplexity = 1 in { 2873 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2874 arith_extended_reg32_i32, mnemonic, OpNode> { 2875 let Inst{31} = 0; 2876 } 2877 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2878 arith_extended_reg32_i64, mnemonic, OpNode> { 2879 let Inst{31} = 1; 2880 } 2881 } 2882 2883 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2884 arith_extendlsl64, mnemonic> { 2885 // UXTX and SXTX only. 2886 let Inst{14-13} = 0b11; 2887 let Inst{31} = 1; 2888 } 2889 } // Defs = [NZCV] 2890 2891 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2892 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2893 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2894 addsub_shifted_imm32_neg:$imm), 0>; 2895 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2896 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2897 addsub_shifted_imm64_neg:$imm), 0>; 2898 2899 // Compare aliases 2900 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2901 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2902 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2903 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2904 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2905 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2906 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2907 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2908 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2909 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2910 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2911 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2912 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2913 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2914 2915 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2916 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2917 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2918 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2919 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2920 2921 // Compare shorthands 2922 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2923 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2924 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2925 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2926 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2927 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2928 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2929 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2930 2931 // Register/register aliases with no shift when SP is not used. 2932 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2933 GPR32, GPR32, GPR32, 0>; 2934 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2935 GPR64, GPR64, GPR64, 0>; 2936 2937 // Register/register aliases with no shift when the first source register 2938 // is SP. 2939 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2940 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2941 def : AddSubRegAlias<mnemonic, 2942 !cast<Instruction>(NAME#"Xrx64"), 2943 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2944} 2945 2946class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2947 : BaseAddSubImm< 2948 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2949 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2950 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2951 bits<6> imm6; 2952 bits<4> imm4; 2953 let Inst{31} = 1; 2954 let Inst{23-22} = 0b10; 2955 let Inst{21-16} = imm6; 2956 let Inst{15-14} = 0b00; 2957 let Inst{13-10} = imm4; 2958 let Unpredictable{15-14} = 0b11; 2959} 2960 2961class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2962 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode, 2963 GPR64sp, GPR64sp>; 2964 2965//--- 2966// Extract 2967//--- 2968def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2969 SDTCisPtrTy<3>]>; 2970def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2971 2972class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2973 list<dag> patterns> 2974 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2975 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2976 Sched<[WriteExtr, ReadExtrHi]> { 2977 bits<5> Rd; 2978 bits<5> Rn; 2979 bits<5> Rm; 2980 bits<6> imm; 2981 2982 let Inst{30-23} = 0b00100111; 2983 let Inst{21} = 0; 2984 let Inst{20-16} = Rm; 2985 let Inst{15-10} = imm; 2986 let Inst{9-5} = Rn; 2987 let Inst{4-0} = Rd; 2988} 2989 2990multiclass ExtractImm<string asm> { 2991 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2992 [(set GPR32:$Rd, 2993 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2994 let Inst{31} = 0; 2995 let Inst{22} = 0; 2996 // imm<5> must be zero. 2997 let imm{5} = 0; 2998 } 2999 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 3000 [(set GPR64:$Rd, 3001 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 3002 3003 let Inst{31} = 1; 3004 let Inst{22} = 1; 3005 } 3006} 3007 3008//--- 3009// Bitfield 3010//--- 3011 3012let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3013class BaseBitfieldImm<bits<2> opc, 3014 RegisterClass regtype, Operand imm_type, string asm> 3015 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 3016 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 3017 Sched<[WriteIS, ReadI]> { 3018 bits<5> Rd; 3019 bits<5> Rn; 3020 bits<6> immr; 3021 bits<6> imms; 3022 3023 let Inst{30-29} = opc; 3024 let Inst{28-23} = 0b100110; 3025 let Inst{21-16} = immr; 3026 let Inst{15-10} = imms; 3027 let Inst{9-5} = Rn; 3028 let Inst{4-0} = Rd; 3029} 3030 3031multiclass BitfieldImm<bits<2> opc, string asm> { 3032 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 3033 let Inst{31} = 0; 3034 let Inst{22} = 0; 3035 // imms<5> and immr<5> must be zero, else ReservedValue(). 3036 let Inst{21} = 0; 3037 let Inst{15} = 0; 3038 } 3039 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 3040 let Inst{31} = 1; 3041 let Inst{22} = 1; 3042 } 3043} 3044 3045let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3046class BaseBitfieldImmWith2RegArgs<bits<2> opc, 3047 RegisterClass regtype, Operand imm_type, string asm> 3048 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 3049 imm_type:$imms), 3050 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 3051 Sched<[WriteIS, ReadI]> { 3052 bits<5> Rd; 3053 bits<5> Rn; 3054 bits<6> immr; 3055 bits<6> imms; 3056 3057 let Inst{30-29} = opc; 3058 let Inst{28-23} = 0b100110; 3059 let Inst{21-16} = immr; 3060 let Inst{15-10} = imms; 3061 let Inst{9-5} = Rn; 3062 let Inst{4-0} = Rd; 3063} 3064 3065multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 3066 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 3067 let Inst{31} = 0; 3068 let Inst{22} = 0; 3069 // imms<5> and immr<5> must be zero, else ReservedValue(). 3070 let Inst{21} = 0; 3071 let Inst{15} = 0; 3072 } 3073 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 3074 let Inst{31} = 1; 3075 let Inst{22} = 1; 3076 } 3077} 3078 3079//--- 3080// Logical 3081//--- 3082 3083// Logical (immediate) 3084class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 3085 RegisterClass sregtype, Operand imm_type, string asm, 3086 list<dag> pattern> 3087 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 3088 asm, "\t$Rd, $Rn, $imm", "", pattern>, 3089 Sched<[WriteI, ReadI]> { 3090 bits<5> Rd; 3091 bits<5> Rn; 3092 bits<13> imm; 3093 let Inst{30-29} = opc; 3094 let Inst{28-23} = 0b100100; 3095 let Inst{22} = imm{12}; 3096 let Inst{21-16} = imm{11-6}; 3097 let Inst{15-10} = imm{5-0}; 3098 let Inst{9-5} = Rn; 3099 let Inst{4-0} = Rd; 3100 3101 let DecoderMethod = "DecodeLogicalImmInstruction"; 3102} 3103 3104// Logical (shifted register) 3105class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 3106 logical_shifted_reg shifted_regtype, string asm, 3107 list<dag> pattern> 3108 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 3109 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>, 3110 Sched<[WriteISReg, ReadI, ReadISReg]> { 3111 bits<5> Rd; 3112 bits<5> Rn; 3113 bits<5> Rm; 3114 bits<8> shift; 3115 let Inst{30-29} = opc; 3116 let Inst{28-24} = 0b01010; 3117 let Inst{23-22} = shift{7-6}; 3118 let Inst{21} = N; 3119 let Inst{20-16} = Rm; 3120 let Inst{15-10} = shift{5-0}; 3121 let Inst{9-5} = Rn; 3122 let Inst{4-0} = Rd; 3123 3124 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 3125} 3126 3127// Aliases for register+register logical instructions. 3128class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 3129 : InstAlias<asm#"\t$dst, $src1, $src2", 3130 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 3131 3132multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 3133 string Alias> { 3134 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3135 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 3136 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 3137 logical_imm32:$imm))]> { 3138 let Inst{31} = 0; 3139 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3140 } 3141 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3142 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 3143 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 3144 logical_imm64:$imm))]> { 3145 let Inst{31} = 1; 3146 } 3147 3148 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3149 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 3150 logical_imm32_not:$imm), 0>; 3151 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3152 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 3153 logical_imm64_not:$imm), 0>; 3154} 3155 3156multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 3157 string Alias> { 3158 let isCompare = 1, Defs = [NZCV] in { 3159 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 3160 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 3161 let Inst{31} = 0; 3162 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3163 } 3164 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 3165 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 3166 let Inst{31} = 1; 3167 } 3168 } // end Defs = [NZCV] 3169 3170 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3171 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 3172 logical_imm32_not:$imm), 0>; 3173 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3174 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 3175 logical_imm64_not:$imm), 0>; 3176} 3177 3178class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 3179 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3180 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 3181 Sched<[WriteI, ReadI, ReadI]>; 3182 3183// Split from LogicalImm as not all instructions have both. 3184multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 3185 SDPatternOperator OpNode, int AddedComplexityVal = 0> { 3186 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in { 3187 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3188 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3189 } 3190 3191 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3192 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3193 logical_shifted_reg32:$Rm_and_shift))]> { 3194 let Inst{31} = 0; 3195 } 3196 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3197 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3198 logical_shifted_reg64:$Rm_and_shift))]> { 3199 let Inst{31} = 1; 3200 } 3201 3202 def : LogicalRegAlias<mnemonic, 3203 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3204 def : LogicalRegAlias<mnemonic, 3205 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3206} 3207 3208// Split from LogicalReg to allow setting NZCV Defs 3209multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3210 SDPatternOperator OpNode = null_frag> { 3211 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3212 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3213 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3214 3215 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3216 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> { 3217 let Inst{31} = 0; 3218 } 3219 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3220 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> { 3221 let Inst{31} = 1; 3222 } 3223 } // Defs = [NZCV] 3224 3225 def : LogicalRegAlias<mnemonic, 3226 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3227 def : LogicalRegAlias<mnemonic, 3228 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3229} 3230 3231//--- 3232// Conditionally set flags 3233//--- 3234 3235let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3236class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3237 string mnemonic, SDNode OpNode> 3238 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3239 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3240 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3241 (i32 imm:$cond), NZCV))]>, 3242 Sched<[WriteI, ReadI]> { 3243 let Uses = [NZCV]; 3244 let Defs = [NZCV]; 3245 3246 bits<5> Rn; 3247 bits<5> imm; 3248 bits<4> nzcv; 3249 bits<4> cond; 3250 3251 let Inst{30} = op; 3252 let Inst{29-21} = 0b111010010; 3253 let Inst{20-16} = imm; 3254 let Inst{15-12} = cond; 3255 let Inst{11-10} = 0b10; 3256 let Inst{9-5} = Rn; 3257 let Inst{4} = 0b0; 3258 let Inst{3-0} = nzcv; 3259} 3260 3261let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3262class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3263 SDNode OpNode> 3264 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3265 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3266 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3267 (i32 imm:$cond), NZCV))]>, 3268 Sched<[WriteI, ReadI, ReadI]> { 3269 let Uses = [NZCV]; 3270 let Defs = [NZCV]; 3271 3272 bits<5> Rn; 3273 bits<5> Rm; 3274 bits<4> nzcv; 3275 bits<4> cond; 3276 3277 let Inst{30} = op; 3278 let Inst{29-21} = 0b111010010; 3279 let Inst{20-16} = Rm; 3280 let Inst{15-12} = cond; 3281 let Inst{11-10} = 0b00; 3282 let Inst{9-5} = Rn; 3283 let Inst{4} = 0b0; 3284 let Inst{3-0} = nzcv; 3285} 3286 3287multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3288 // immediate operand variants 3289 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3290 let Inst{31} = 0; 3291 } 3292 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3293 let Inst{31} = 1; 3294 } 3295 // register operand variants 3296 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3297 let Inst{31} = 0; 3298 } 3299 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3300 let Inst{31} = 1; 3301 } 3302} 3303 3304//--- 3305// Conditional select 3306//--- 3307 3308class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3309 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3310 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3311 [(set regtype:$Rd, 3312 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3313 Sched<[WriteI, ReadI, ReadI]> { 3314 let Uses = [NZCV]; 3315 3316 bits<5> Rd; 3317 bits<5> Rn; 3318 bits<5> Rm; 3319 bits<4> cond; 3320 3321 let Inst{30} = op; 3322 let Inst{29-21} = 0b011010100; 3323 let Inst{20-16} = Rm; 3324 let Inst{15-12} = cond; 3325 let Inst{11-10} = op2; 3326 let Inst{9-5} = Rn; 3327 let Inst{4-0} = Rd; 3328} 3329 3330multiclass CondSelect<bit op, bits<2> op2, string asm> { 3331 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3332 let Inst{31} = 0; 3333 } 3334 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3335 let Inst{31} = 1; 3336 } 3337} 3338 3339class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3340 PatFrag frag> 3341 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3342 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3343 [(set regtype:$Rd, 3344 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3345 (i32 imm:$cond), NZCV))]>, 3346 Sched<[WriteI, ReadI, ReadI]> { 3347 let Uses = [NZCV]; 3348 3349 bits<5> Rd; 3350 bits<5> Rn; 3351 bits<5> Rm; 3352 bits<4> cond; 3353 3354 let Inst{30} = op; 3355 let Inst{29-21} = 0b011010100; 3356 let Inst{20-16} = Rm; 3357 let Inst{15-12} = cond; 3358 let Inst{11-10} = op2; 3359 let Inst{9-5} = Rn; 3360 let Inst{4-0} = Rd; 3361} 3362 3363def inv_cond_XFORM : SDNodeXForm<imm, [{ 3364 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3365 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3366 MVT::i32); 3367}]>; 3368 3369multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3370 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3371 let Inst{31} = 0; 3372 } 3373 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3374 let Inst{31} = 1; 3375 } 3376 3377 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3378 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3379 (inv_cond_XFORM imm:$cond))>; 3380 3381 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3382 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3383 (inv_cond_XFORM imm:$cond))>; 3384} 3385 3386//--- 3387// Special Mask Value 3388//--- 3389def maski8_or_more : Operand<i32>, 3390 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3391} 3392def maski16_or_more : Operand<i32>, 3393 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3394} 3395 3396 3397//--- 3398// Load/store 3399//--- 3400 3401// (unsigned immediate) 3402// Indexed for 8-bit registers. offset is in range [0,4095]. 3403def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3404def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3405def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3406def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3407def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3408 3409// (unsigned immediate) 3410// Indexed for 8-bit registers. offset is in range [0,63]. 3411def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3412def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3413def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3414def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3415 3416def gi_am_indexed8 : 3417 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3418 GIComplexPatternEquiv<am_indexed8>; 3419def gi_am_indexed16 : 3420 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3421 GIComplexPatternEquiv<am_indexed16>; 3422def gi_am_indexed32 : 3423 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3424 GIComplexPatternEquiv<am_indexed32>; 3425def gi_am_indexed64 : 3426 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3427 GIComplexPatternEquiv<am_indexed64>; 3428def gi_am_indexed128 : 3429 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3430 GIComplexPatternEquiv<am_indexed128>; 3431 3432class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3433 let Name = "UImm12Offset" # Scale; 3434 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3435 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3436 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3437} 3438 3439def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3440def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3441def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3442def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3443def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3444 3445class uimm12_scaled<int Scale> : Operand<i64> { 3446 let ParserMatchClass 3447 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3448 let EncoderMethod 3449 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3450 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3451} 3452 3453def uimm12s1 : uimm12_scaled<1>; 3454def uimm12s2 : uimm12_scaled<2>; 3455def uimm12s4 : uimm12_scaled<4>; 3456def uimm12s8 : uimm12_scaled<8>; 3457def uimm12s16 : uimm12_scaled<16>; 3458 3459class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3460 string asm, list<dag> pattern> 3461 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3462 bits<5> Rt; 3463 3464 bits<5> Rn; 3465 bits<12> offset; 3466 3467 let Inst{31-30} = sz; 3468 let Inst{29-27} = 0b111; 3469 let Inst{26} = V; 3470 let Inst{25-24} = 0b01; 3471 let Inst{23-22} = opc; 3472 let Inst{21-10} = offset; 3473 let Inst{9-5} = Rn; 3474 let Inst{4-0} = Rt; 3475 3476 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3477} 3478 3479multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3480 Operand indextype, string asm, list<dag> pattern> { 3481 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3482 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3483 (ins GPR64sp:$Rn, indextype:$offset), 3484 asm, pattern>, 3485 Sched<[WriteLD]>; 3486 3487 def : InstAlias<asm # "\t$Rt, [$Rn]", 3488 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3489} 3490 3491multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3492 Operand indextype, string asm, list<dag> pattern> { 3493 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3494 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3495 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3496 asm, pattern>, 3497 Sched<[WriteST]>; 3498 3499 def : InstAlias<asm # "\t$Rt, [$Rn]", 3500 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3501} 3502 3503// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3504// substitute zero-registers automatically. 3505// 3506// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3507// into StoreUI. 3508multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3509 Operand indextype, string asm, list<dag> pattern> { 3510 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3511 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3512 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3513 asm, pattern>, 3514 Sched<[WriteST]>; 3515 3516 def : InstAlias<asm # "\t$Rt, [$Rn]", 3517 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3518} 3519 3520def PrefetchOperand : AsmOperandClass { 3521 let Name = "Prefetch"; 3522 let ParserMethod = "tryParsePrefetch"; 3523} 3524def prfop : Operand<i32> { 3525 let PrintMethod = "printPrefetchOp"; 3526 let ParserMatchClass = PrefetchOperand; 3527} 3528 3529let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3530class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3531 : BaseLoadStoreUI<sz, V, opc, 3532 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3533 asm, pat>, 3534 Sched<[WriteLD]>; 3535 3536//--- 3537// Load literal 3538//--- 3539 3540// Load literal address: 19-bit immediate. The low two bits of the target 3541// offset are implied zero and so are not part of the immediate. 3542def am_ldrlit : Operand<iPTR> { 3543 let EncoderMethod = "getLoadLiteralOpValue"; 3544 let DecoderMethod = "DecodePCRelLabel19"; 3545 let PrintMethod = "printAlignedLabel"; 3546 let ParserMatchClass = PCRelLabel19Operand; 3547 let OperandType = "OPERAND_PCREL"; 3548} 3549 3550let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3551class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3552 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3553 asm, "\t$Rt, $label", "", pat>, 3554 Sched<[WriteLD]> { 3555 bits<5> Rt; 3556 bits<19> label; 3557 let Inst{31-30} = opc; 3558 let Inst{29-27} = 0b011; 3559 let Inst{26} = V; 3560 let Inst{25-24} = 0b00; 3561 let Inst{23-5} = label; 3562 let Inst{4-0} = Rt; 3563} 3564 3565let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3566class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3567 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3568 asm, "\t$Rt, $label", "", pat>, 3569 Sched<[WriteLD]> { 3570 bits<5> Rt; 3571 bits<19> label; 3572 let Inst{31-30} = opc; 3573 let Inst{29-27} = 0b011; 3574 let Inst{26} = V; 3575 let Inst{25-24} = 0b00; 3576 let Inst{23-5} = label; 3577 let Inst{4-0} = Rt; 3578} 3579 3580//--- 3581// Load/store register offset 3582//--- 3583 3584def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3585def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3586def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3587def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3588def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3589 3590def gi_ro_Xindexed8 : 3591 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3592 GIComplexPatternEquiv<ro_Xindexed8>; 3593def gi_ro_Xindexed16 : 3594 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3595 GIComplexPatternEquiv<ro_Xindexed16>; 3596def gi_ro_Xindexed32 : 3597 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3598 GIComplexPatternEquiv<ro_Xindexed32>; 3599def gi_ro_Xindexed64 : 3600 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3601 GIComplexPatternEquiv<ro_Xindexed64>; 3602def gi_ro_Xindexed128 : 3603 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3604 GIComplexPatternEquiv<ro_Xindexed128>; 3605 3606def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3607def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3608def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3609def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3610def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3611 3612def gi_ro_Windexed8 : 3613 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3614 GIComplexPatternEquiv<ro_Windexed8>; 3615def gi_ro_Windexed16 : 3616 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3617 GIComplexPatternEquiv<ro_Windexed16>; 3618def gi_ro_Windexed32 : 3619 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3620 GIComplexPatternEquiv<ro_Windexed32>; 3621def gi_ro_Windexed64 : 3622 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3623 GIComplexPatternEquiv<ro_Windexed64>; 3624def gi_ro_Windexed128 : 3625 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3626 GIComplexPatternEquiv<ro_Windexed128>; 3627 3628class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3629 let Name = "Mem" # Reg # "Extend" # Width; 3630 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3631 let RenderMethod = "addMemExtendOperands"; 3632 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3633} 3634 3635def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3636 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3637 // the trivial shift. 3638 let RenderMethod = "addMemExtend8Operands"; 3639} 3640def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3641def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3642def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3643def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3644 3645def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3646 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3647 // the trivial shift. 3648 let RenderMethod = "addMemExtend8Operands"; 3649} 3650def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3651def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3652def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3653def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3654 3655class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3656 : Operand<i32> { 3657 let ParserMatchClass = ParserClass; 3658 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3659 let DecoderMethod = "DecodeMemExtend"; 3660 let EncoderMethod = "getMemExtendOpValue"; 3661 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3662} 3663 3664def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3665def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3666def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3667def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3668def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3669 3670def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3671def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3672def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3673def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3674def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3675 3676class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3677 Operand wextend, Operand xextend> { 3678 // CodeGen-level pattern covering the entire addressing mode. 3679 ComplexPattern Wpat = windex; 3680 ComplexPattern Xpat = xindex; 3681 3682 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3683 Operand Wext = wextend; 3684 Operand Xext = xextend; 3685} 3686 3687def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3688def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3689def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3690def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3691def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3692 ro_Xextend128>; 3693 3694class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3695 dag outs, list<dag> pat> 3696 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3697 bits<5> Rt; 3698 bits<5> Rn; 3699 bits<5> Rm; 3700 bits<2> extend; 3701 let Inst{31-30} = sz; 3702 let Inst{29-27} = 0b111; 3703 let Inst{26} = V; 3704 let Inst{25-24} = 0b00; 3705 let Inst{23-22} = opc; 3706 let Inst{21} = 1; 3707 let Inst{20-16} = Rm; 3708 let Inst{15} = extend{1}; // sign extend Rm? 3709 let Inst{14} = 1; 3710 let Inst{12} = extend{0}; // do shift? 3711 let Inst{11-10} = 0b10; 3712 let Inst{9-5} = Rn; 3713 let Inst{4-0} = Rt; 3714} 3715 3716class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3717 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3718 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3719 3720multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3721 string asm, ValueType Ty, SDPatternOperator loadop> { 3722 let AddedComplexity = 10 in 3723 def roW : LoadStore8RO<sz, V, opc, asm, 3724 (outs regtype:$Rt), 3725 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3726 [(set (Ty regtype:$Rt), 3727 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3728 ro_Wextend8:$extend)))]>, 3729 Sched<[WriteLDIdx, ReadAdrBase]> { 3730 let Inst{13} = 0b0; 3731 } 3732 3733 let AddedComplexity = 10 in 3734 def roX : LoadStore8RO<sz, V, opc, asm, 3735 (outs regtype:$Rt), 3736 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3737 [(set (Ty regtype:$Rt), 3738 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3739 ro_Xextend8:$extend)))]>, 3740 Sched<[WriteLDIdx, ReadAdrBase]> { 3741 let Inst{13} = 0b1; 3742 } 3743 3744 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3745} 3746 3747multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3748 string asm, ValueType Ty, SDPatternOperator storeop> { 3749 let AddedComplexity = 10 in 3750 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3751 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3752 [(storeop (Ty regtype:$Rt), 3753 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3754 ro_Wextend8:$extend))]>, 3755 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3756 let Inst{13} = 0b0; 3757 } 3758 3759 let AddedComplexity = 10 in 3760 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3761 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3762 [(storeop (Ty regtype:$Rt), 3763 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3764 ro_Xextend8:$extend))]>, 3765 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3766 let Inst{13} = 0b1; 3767 } 3768 3769 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3770} 3771 3772class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3773 dag outs, list<dag> pat> 3774 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3775 bits<5> Rt; 3776 bits<5> Rn; 3777 bits<5> Rm; 3778 bits<2> extend; 3779 let Inst{31-30} = sz; 3780 let Inst{29-27} = 0b111; 3781 let Inst{26} = V; 3782 let Inst{25-24} = 0b00; 3783 let Inst{23-22} = opc; 3784 let Inst{21} = 1; 3785 let Inst{20-16} = Rm; 3786 let Inst{15} = extend{1}; // sign extend Rm? 3787 let Inst{14} = 1; 3788 let Inst{12} = extend{0}; // do shift? 3789 let Inst{11-10} = 0b10; 3790 let Inst{9-5} = Rn; 3791 let Inst{4-0} = Rt; 3792} 3793 3794multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3795 string asm, ValueType Ty, SDPatternOperator loadop> { 3796 let AddedComplexity = 10 in 3797 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3798 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3799 [(set (Ty regtype:$Rt), 3800 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3801 ro_Wextend16:$extend)))]>, 3802 Sched<[WriteLDIdx, ReadAdrBase]> { 3803 let Inst{13} = 0b0; 3804 } 3805 3806 let AddedComplexity = 10 in 3807 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3808 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3809 [(set (Ty regtype:$Rt), 3810 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3811 ro_Xextend16:$extend)))]>, 3812 Sched<[WriteLDIdx, ReadAdrBase]> { 3813 let Inst{13} = 0b1; 3814 } 3815 3816 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3817} 3818 3819multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3820 string asm, ValueType Ty, SDPatternOperator storeop> { 3821 let AddedComplexity = 10 in 3822 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3823 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3824 [(storeop (Ty regtype:$Rt), 3825 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3826 ro_Wextend16:$extend))]>, 3827 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3828 let Inst{13} = 0b0; 3829 } 3830 3831 let AddedComplexity = 10 in 3832 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3833 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3834 [(storeop (Ty regtype:$Rt), 3835 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3836 ro_Xextend16:$extend))]>, 3837 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3838 let Inst{13} = 0b1; 3839 } 3840 3841 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3842} 3843 3844class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3845 dag outs, list<dag> pat> 3846 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3847 bits<5> Rt; 3848 bits<5> Rn; 3849 bits<5> Rm; 3850 bits<2> extend; 3851 let Inst{31-30} = sz; 3852 let Inst{29-27} = 0b111; 3853 let Inst{26} = V; 3854 let Inst{25-24} = 0b00; 3855 let Inst{23-22} = opc; 3856 let Inst{21} = 1; 3857 let Inst{20-16} = Rm; 3858 let Inst{15} = extend{1}; // sign extend Rm? 3859 let Inst{14} = 1; 3860 let Inst{12} = extend{0}; // do shift? 3861 let Inst{11-10} = 0b10; 3862 let Inst{9-5} = Rn; 3863 let Inst{4-0} = Rt; 3864} 3865 3866multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3867 string asm, ValueType Ty, SDPatternOperator loadop> { 3868 let AddedComplexity = 10 in 3869 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3870 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3871 [(set (Ty regtype:$Rt), 3872 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3873 ro_Wextend32:$extend)))]>, 3874 Sched<[WriteLDIdx, ReadAdrBase]> { 3875 let Inst{13} = 0b0; 3876 } 3877 3878 let AddedComplexity = 10 in 3879 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3880 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3881 [(set (Ty regtype:$Rt), 3882 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3883 ro_Xextend32:$extend)))]>, 3884 Sched<[WriteLDIdx, ReadAdrBase]> { 3885 let Inst{13} = 0b1; 3886 } 3887 3888 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3889} 3890 3891multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3892 string asm, ValueType Ty, SDPatternOperator storeop> { 3893 let AddedComplexity = 10 in 3894 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3895 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3896 [(storeop (Ty regtype:$Rt), 3897 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3898 ro_Wextend32:$extend))]>, 3899 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3900 let Inst{13} = 0b0; 3901 } 3902 3903 let AddedComplexity = 10 in 3904 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3905 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3906 [(storeop (Ty regtype:$Rt), 3907 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3908 ro_Xextend32:$extend))]>, 3909 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3910 let Inst{13} = 0b1; 3911 } 3912 3913 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3914} 3915 3916class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3917 dag outs, list<dag> pat> 3918 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3919 bits<5> Rt; 3920 bits<5> Rn; 3921 bits<5> Rm; 3922 bits<2> extend; 3923 let Inst{31-30} = sz; 3924 let Inst{29-27} = 0b111; 3925 let Inst{26} = V; 3926 let Inst{25-24} = 0b00; 3927 let Inst{23-22} = opc; 3928 let Inst{21} = 1; 3929 let Inst{20-16} = Rm; 3930 let Inst{15} = extend{1}; // sign extend Rm? 3931 let Inst{14} = 1; 3932 let Inst{12} = extend{0}; // do shift? 3933 let Inst{11-10} = 0b10; 3934 let Inst{9-5} = Rn; 3935 let Inst{4-0} = Rt; 3936} 3937 3938multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3939 string asm, ValueType Ty, SDPatternOperator loadop> { 3940 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3941 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3942 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3943 [(set (Ty regtype:$Rt), 3944 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3945 ro_Wextend64:$extend)))]>, 3946 Sched<[WriteLDIdx, ReadAdrBase]> { 3947 let Inst{13} = 0b0; 3948 } 3949 3950 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3951 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 3952 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3953 [(set (Ty regtype:$Rt), 3954 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3955 ro_Xextend64:$extend)))]>, 3956 Sched<[WriteLDIdx, ReadAdrBase]> { 3957 let Inst{13} = 0b1; 3958 } 3959 3960 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3961} 3962 3963multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3964 string asm, ValueType Ty, SDPatternOperator storeop> { 3965 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3966 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 3967 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3968 [(storeop (Ty regtype:$Rt), 3969 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3970 ro_Wextend64:$extend))]>, 3971 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3972 let Inst{13} = 0b0; 3973 } 3974 3975 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3976 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 3977 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3978 [(storeop (Ty regtype:$Rt), 3979 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3980 ro_Xextend64:$extend))]>, 3981 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3982 let Inst{13} = 0b1; 3983 } 3984 3985 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3986} 3987 3988class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3989 dag outs, list<dag> pat> 3990 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3991 bits<5> Rt; 3992 bits<5> Rn; 3993 bits<5> Rm; 3994 bits<2> extend; 3995 let Inst{31-30} = sz; 3996 let Inst{29-27} = 0b111; 3997 let Inst{26} = V; 3998 let Inst{25-24} = 0b00; 3999 let Inst{23-22} = opc; 4000 let Inst{21} = 1; 4001 let Inst{20-16} = Rm; 4002 let Inst{15} = extend{1}; // sign extend Rm? 4003 let Inst{14} = 1; 4004 let Inst{12} = extend{0}; // do shift? 4005 let Inst{11-10} = 0b10; 4006 let Inst{9-5} = Rn; 4007 let Inst{4-0} = Rt; 4008} 4009 4010multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4011 string asm, ValueType Ty, SDPatternOperator loadop> { 4012 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4013 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4014 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4015 [(set (Ty regtype:$Rt), 4016 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 4017 ro_Wextend128:$extend)))]>, 4018 Sched<[WriteLDIdx, ReadAdrBase]> { 4019 let Inst{13} = 0b0; 4020 } 4021 4022 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4023 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4024 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4025 [(set (Ty regtype:$Rt), 4026 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 4027 ro_Xextend128:$extend)))]>, 4028 Sched<[WriteLDIdx, ReadAdrBase]> { 4029 let Inst{13} = 0b1; 4030 } 4031 4032 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4033} 4034 4035multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4036 string asm> { 4037 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4038 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 4039 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4040 []>, 4041 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4042 let Inst{13} = 0b0; 4043 } 4044 4045 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4046 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 4047 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4048 []>, 4049 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4050 let Inst{13} = 0b1; 4051 } 4052 4053 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4054} 4055 4056let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4057class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 4058 string asm, list<dag> pat> 4059 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 4060 Sched<[WriteLD]> { 4061 bits<5> Rt; 4062 bits<5> Rn; 4063 bits<5> Rm; 4064 bits<2> extend; 4065 let Inst{31-30} = sz; 4066 let Inst{29-27} = 0b111; 4067 let Inst{26} = V; 4068 let Inst{25-24} = 0b00; 4069 let Inst{23-22} = opc; 4070 let Inst{21} = 1; 4071 let Inst{20-16} = Rm; 4072 let Inst{15} = extend{1}; // sign extend Rm? 4073 let Inst{14} = 1; 4074 let Inst{12} = extend{0}; // do shift? 4075 let Inst{11-10} = 0b10; 4076 let Inst{9-5} = Rn; 4077 let Inst{4-0} = Rt; 4078 let DecoderMethod = "DecodePRFMRegInstruction"; 4079 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When 4080 // the decoder method returns Fail, the decoder should attempt to decode the 4081 // instruction as RPRFM. 4082 let hasCompleteDecoder = 0; 4083} 4084 4085multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 4086 def roW : BasePrefetchRO<sz, V, opc, (outs), 4087 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4088 asm, [(AArch64Prefetch timm:$Rt, 4089 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4090 ro_Wextend64:$extend))]> { 4091 let Inst{13} = 0b0; 4092 } 4093 4094 def roX : BasePrefetchRO<sz, V, opc, (outs), 4095 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4096 asm, [(AArch64Prefetch timm:$Rt, 4097 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4098 ro_Xextend64:$extend))]> { 4099 let Inst{13} = 0b1; 4100 } 4101 4102 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 4103 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 4104 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 4105} 4106 4107//--- 4108// Load/store unscaled immediate 4109//--- 4110 4111def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 4112def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 4113def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 4114def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 4115def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 4116 4117def gi_am_unscaled8 : 4118 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 4119 GIComplexPatternEquiv<am_unscaled8>; 4120def gi_am_unscaled16 : 4121 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 4122 GIComplexPatternEquiv<am_unscaled16>; 4123def gi_am_unscaled32 : 4124 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 4125 GIComplexPatternEquiv<am_unscaled32>; 4126def gi_am_unscaled64 : 4127 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 4128 GIComplexPatternEquiv<am_unscaled64>; 4129def gi_am_unscaled128 : 4130 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 4131 GIComplexPatternEquiv<am_unscaled128>; 4132 4133 4134class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4135 string asm, list<dag> pattern> 4136 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 4137 bits<5> Rt; 4138 bits<5> Rn; 4139 bits<9> offset; 4140 let Inst{31-30} = sz; 4141 let Inst{29-27} = 0b111; 4142 let Inst{26} = V; 4143 let Inst{25-24} = 0b00; 4144 let Inst{23-22} = opc; 4145 let Inst{21} = 0; 4146 let Inst{20-12} = offset; 4147 let Inst{11-10} = 0b00; 4148 let Inst{9-5} = Rn; 4149 let Inst{4-0} = Rt; 4150 4151 let DecoderMethod = "DecodeSignedLdStInstruction"; 4152} 4153 4154// Armv8.4 LDAPR & STLR with Immediate Offset instruction 4155multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4156 DAGOperand regtype > { 4157 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 4158 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 4159 Sched<[WriteST]> { 4160 let Inst{29} = 0; 4161 let Inst{24} = 1; 4162 } 4163 def : InstAlias<asm # "\t$Rt, [$Rn]", 4164 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4165} 4166 4167multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4168 DAGOperand regtype > { 4169 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 4170 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4171 asm, []>, 4172 Sched<[WriteST]> { 4173 let Inst{29} = 0; 4174 let Inst{24} = 1; 4175 } 4176 def : InstAlias<asm # "\t$Rt, [$Rn]", 4177 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4178} 4179 4180multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4181 string asm, list<dag> pattern> { 4182 let AddedComplexity = 1 in // try this before LoadUI 4183 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 4184 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 4185 Sched<[WriteLD]>; 4186 4187 def : InstAlias<asm # "\t$Rt, [$Rn]", 4188 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4189} 4190 4191multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4192 string asm, list<dag> pattern> { 4193 let AddedComplexity = 1 in // try this before StoreUI 4194 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4195 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4196 asm, pattern>, 4197 Sched<[WriteST]>; 4198 4199 def : InstAlias<asm # "\t$Rt, [$Rn]", 4200 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4201} 4202 4203multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4204 list<dag> pat> { 4205 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4206 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4207 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4208 asm, pat>, 4209 Sched<[WriteLD]>; 4210 4211 def : InstAlias<asm # "\t$Rt, [$Rn]", 4212 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4213} 4214 4215//--- 4216// Load/store unscaled immediate, unprivileged 4217//--- 4218 4219class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4220 dag oops, dag iops, string asm> 4221 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4222 bits<5> Rt; 4223 bits<5> Rn; 4224 bits<9> offset; 4225 let Inst{31-30} = sz; 4226 let Inst{29-27} = 0b111; 4227 let Inst{26} = V; 4228 let Inst{25-24} = 0b00; 4229 let Inst{23-22} = opc; 4230 let Inst{21} = 0; 4231 let Inst{20-12} = offset; 4232 let Inst{11-10} = 0b10; 4233 let Inst{9-5} = Rn; 4234 let Inst{4-0} = Rt; 4235 4236 let DecoderMethod = "DecodeSignedLdStInstruction"; 4237} 4238 4239multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4240 RegisterClass regtype, string asm> { 4241 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4242 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4243 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4244 Sched<[WriteLD]>; 4245 4246 def : InstAlias<asm # "\t$Rt, [$Rn]", 4247 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4248} 4249 4250multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4251 RegisterClass regtype, string asm> { 4252 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4253 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4254 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4255 asm>, 4256 Sched<[WriteST]>; 4257 4258 def : InstAlias<asm # "\t$Rt, [$Rn]", 4259 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4260} 4261 4262//--- 4263// Load/store pre-indexed 4264//--- 4265 4266class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4267 string asm, string cstr, list<dag> pat> 4268 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4269 bits<5> Rt; 4270 bits<5> Rn; 4271 bits<9> offset; 4272 let Inst{31-30} = sz; 4273 let Inst{29-27} = 0b111; 4274 let Inst{26} = V; 4275 let Inst{25-24} = 0; 4276 let Inst{23-22} = opc; 4277 let Inst{21} = 0; 4278 let Inst{20-12} = offset; 4279 let Inst{11-10} = 0b11; 4280 let Inst{9-5} = Rn; 4281 let Inst{4-0} = Rt; 4282 4283 let DecoderMethod = "DecodeSignedLdStInstruction"; 4284} 4285 4286let hasSideEffects = 0 in { 4287let mayStore = 0, mayLoad = 1 in 4288class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4289 string asm> 4290 : BaseLoadStorePreIdx<sz, V, opc, 4291 (outs GPR64sp:$wback, regtype:$Rt), 4292 (ins GPR64sp:$Rn, simm9:$offset), asm, 4293 "$Rn = $wback,@earlyclobber $wback", []>, 4294 Sched<[WriteAdr, WriteLD]>; 4295 4296let mayStore = 1, mayLoad = 0 in 4297class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4298 string asm, SDPatternOperator storeop, ValueType Ty> 4299 : BaseLoadStorePreIdx<sz, V, opc, 4300 (outs GPR64sp:$wback), 4301 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4302 asm, "$Rn = $wback,@earlyclobber $wback", 4303 [(set GPR64sp:$wback, 4304 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4305 Sched<[WriteAdr, WriteST]>; 4306} // hasSideEffects = 0 4307 4308//--- 4309// Load/store post-indexed 4310//--- 4311 4312class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4313 string asm, string cstr, list<dag> pat> 4314 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4315 bits<5> Rt; 4316 bits<5> Rn; 4317 bits<9> offset; 4318 let Inst{31-30} = sz; 4319 let Inst{29-27} = 0b111; 4320 let Inst{26} = V; 4321 let Inst{25-24} = 0b00; 4322 let Inst{23-22} = opc; 4323 let Inst{21} = 0b0; 4324 let Inst{20-12} = offset; 4325 let Inst{11-10} = 0b01; 4326 let Inst{9-5} = Rn; 4327 let Inst{4-0} = Rt; 4328 4329 let DecoderMethod = "DecodeSignedLdStInstruction"; 4330} 4331 4332let hasSideEffects = 0 in { 4333let mayStore = 0, mayLoad = 1 in 4334class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4335 string asm> 4336 : BaseLoadStorePostIdx<sz, V, opc, 4337 (outs GPR64sp:$wback, regtype:$Rt), 4338 (ins GPR64sp:$Rn, simm9:$offset), 4339 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4340 Sched<[WriteAdr, WriteLD]>; 4341 4342let mayStore = 1, mayLoad = 0 in 4343class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4344 string asm, SDPatternOperator storeop, ValueType Ty> 4345 : BaseLoadStorePostIdx<sz, V, opc, 4346 (outs GPR64sp:$wback), 4347 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4348 asm, "$Rn = $wback,@earlyclobber $wback", 4349 [(set GPR64sp:$wback, 4350 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4351 Sched<[WriteAdr, WriteST]>; 4352} // hasSideEffects = 0 4353 4354 4355//--- 4356// Load/store pair 4357//--- 4358 4359// (indexed, offset) 4360 4361class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4362 string asm> 4363 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4364 bits<5> Rt; 4365 bits<5> Rt2; 4366 bits<5> Rn; 4367 bits<7> offset; 4368 let Inst{31-30} = opc; 4369 let Inst{29-27} = 0b101; 4370 let Inst{26} = V; 4371 let Inst{25-23} = 0b010; 4372 let Inst{22} = L; 4373 let Inst{21-15} = offset; 4374 let Inst{14-10} = Rt2; 4375 let Inst{9-5} = Rn; 4376 let Inst{4-0} = Rt; 4377 4378 let DecoderMethod = "DecodePairLdStInstruction"; 4379} 4380 4381multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4382 Operand indextype, string asm> { 4383 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4384 def i : BaseLoadStorePairOffset<opc, V, 1, 4385 (outs regtype:$Rt, regtype:$Rt2), 4386 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4387 Sched<[WriteLD, WriteLDHi]>; 4388 4389 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4390 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4391 GPR64sp:$Rn, 0)>; 4392} 4393 4394 4395multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4396 Operand indextype, string asm> { 4397 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4398 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4399 (ins regtype:$Rt, regtype:$Rt2, 4400 GPR64sp:$Rn, indextype:$offset), 4401 asm>, 4402 Sched<[WriteSTP]>; 4403 4404 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4405 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4406 GPR64sp:$Rn, 0)>; 4407} 4408 4409// (pre-indexed) 4410class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4411 string asm> 4412 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4413 bits<5> Rt; 4414 bits<5> Rt2; 4415 bits<5> Rn; 4416 bits<7> offset; 4417 let Inst{31-30} = opc; 4418 let Inst{29-27} = 0b101; 4419 let Inst{26} = V; 4420 let Inst{25-23} = 0b011; 4421 let Inst{22} = L; 4422 let Inst{21-15} = offset; 4423 let Inst{14-10} = Rt2; 4424 let Inst{9-5} = Rn; 4425 let Inst{4-0} = Rt; 4426 4427 let DecoderMethod = "DecodePairLdStInstruction"; 4428} 4429 4430let hasSideEffects = 0 in { 4431let mayStore = 0, mayLoad = 1 in 4432class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4433 Operand indextype, string asm> 4434 : BaseLoadStorePairPreIdx<opc, V, 1, 4435 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4436 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4437 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4438 4439let mayStore = 1, mayLoad = 0 in 4440class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4441 Operand indextype, string asm> 4442 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4443 (ins regtype:$Rt, regtype:$Rt2, 4444 GPR64sp:$Rn, indextype:$offset), 4445 asm>, 4446 Sched<[WriteAdr, WriteSTP]>; 4447} // hasSideEffects = 0 4448 4449// (post-indexed) 4450 4451class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4452 string asm> 4453 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4454 bits<5> Rt; 4455 bits<5> Rt2; 4456 bits<5> Rn; 4457 bits<7> offset; 4458 let Inst{31-30} = opc; 4459 let Inst{29-27} = 0b101; 4460 let Inst{26} = V; 4461 let Inst{25-23} = 0b001; 4462 let Inst{22} = L; 4463 let Inst{21-15} = offset; 4464 let Inst{14-10} = Rt2; 4465 let Inst{9-5} = Rn; 4466 let Inst{4-0} = Rt; 4467 4468 let DecoderMethod = "DecodePairLdStInstruction"; 4469} 4470 4471let hasSideEffects = 0 in { 4472let mayStore = 0, mayLoad = 1 in 4473class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4474 Operand idxtype, string asm> 4475 : BaseLoadStorePairPostIdx<opc, V, 1, 4476 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4477 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4478 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4479 4480let mayStore = 1, mayLoad = 0 in 4481class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4482 Operand idxtype, string asm> 4483 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4484 (ins regtype:$Rt, regtype:$Rt2, 4485 GPR64sp:$Rn, idxtype:$offset), 4486 asm>, 4487 Sched<[WriteAdr, WriteSTP]>; 4488} // hasSideEffects = 0 4489 4490// (no-allocate) 4491 4492class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4493 string asm> 4494 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4495 bits<5> Rt; 4496 bits<5> Rt2; 4497 bits<5> Rn; 4498 bits<7> offset; 4499 let Inst{31-30} = opc; 4500 let Inst{29-27} = 0b101; 4501 let Inst{26} = V; 4502 let Inst{25-23} = 0b000; 4503 let Inst{22} = L; 4504 let Inst{21-15} = offset; 4505 let Inst{14-10} = Rt2; 4506 let Inst{9-5} = Rn; 4507 let Inst{4-0} = Rt; 4508 4509 let DecoderMethod = "DecodePairLdStInstruction"; 4510} 4511 4512multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4513 Operand indextype, string asm> { 4514 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4515 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4516 (outs regtype:$Rt, regtype:$Rt2), 4517 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4518 Sched<[WriteLD, WriteLDHi]>; 4519 4520 4521 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4522 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4523 GPR64sp:$Rn, 0)>; 4524} 4525 4526multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4527 Operand indextype, string asm> { 4528 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4529 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4530 (ins regtype:$Rt, regtype:$Rt2, 4531 GPR64sp:$Rn, indextype:$offset), 4532 asm>, 4533 Sched<[WriteSTP]>; 4534 4535 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4536 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4537 GPR64sp:$Rn, 0)>; 4538} 4539 4540//--- 4541// Load/store exclusive 4542//--- 4543 4544// True exclusive operations write to and/or read from the system's exclusive 4545// monitors, which as far as a compiler is concerned can be modelled as a 4546// random shared memory address. Hence LoadExclusive mayStore. 4547// 4548// Since these instructions have the undefined register bits set to 1 in 4549// their canonical form, we need a post encoder method to set those bits 4550// to 1 when encoding these instructions. We do this using the 4551// fixLoadStoreExclusive function. This function has template parameters: 4552// 4553// fixLoadStoreExclusive<int hasRs, int hasRt2> 4554// 4555// hasRs indicates that the instruction uses the Rs field, so we won't set 4556// it to 1 (and the same for Rt2). We don't need template parameters for 4557// the other register fields since Rt and Rn are always used. 4558// 4559let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4560class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4561 dag oops, dag iops, string asm, string operands> 4562 : I<oops, iops, asm, operands, "", []> { 4563 let Inst{31-30} = sz; 4564 let Inst{29-24} = 0b001000; 4565 let Inst{23} = o2; 4566 let Inst{22} = L; 4567 let Inst{21} = o1; 4568 let Inst{15} = o0; 4569 4570 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4571} 4572 4573// Neither Rs nor Rt2 operands. 4574class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4575 dag oops, dag iops, string asm, string operands> 4576 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4577 bits<5> Rt; 4578 bits<5> Rn; 4579 let Inst{20-16} = 0b11111; 4580 let Unpredictable{20-16} = 0b11111; 4581 let Inst{14-10} = 0b11111; 4582 let Unpredictable{14-10} = 0b11111; 4583 let Inst{9-5} = Rn; 4584 let Inst{4-0} = Rt; 4585 4586 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4587} 4588 4589// Simple load acquires don't set the exclusive monitor 4590let mayLoad = 1, mayStore = 0 in 4591class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4592 RegisterClass regtype, string asm> 4593 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4594 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4595 Sched<[WriteLD]>; 4596 4597class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4598 RegisterClass regtype, string asm> 4599 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4600 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4601 Sched<[WriteLD]>; 4602 4603class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4604 RegisterClass regtype, string asm> 4605 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4606 (outs regtype:$Rt, regtype:$Rt2), 4607 (ins GPR64sp0:$Rn), asm, 4608 "\t$Rt, $Rt2, [$Rn]">, 4609 Sched<[WriteLD, WriteLDHi]> { 4610 bits<5> Rt; 4611 bits<5> Rt2; 4612 bits<5> Rn; 4613 let Inst{14-10} = Rt2; 4614 let Inst{9-5} = Rn; 4615 let Inst{4-0} = Rt; 4616 4617 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4618} 4619 4620// Simple store release operations do not check the exclusive monitor. 4621let mayLoad = 0, mayStore = 1 in 4622class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4623 RegisterClass regtype, string asm> 4624 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4625 (ins regtype:$Rt, GPR64sp:$Rn), 4626 asm, "\t$Rt, [$Rn]">, 4627 Sched<[WriteST]>; 4628 4629let mayLoad = 1, mayStore = 1 in 4630class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4631 RegisterClass regtype, string asm> 4632 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4633 (ins regtype:$Rt, GPR64sp0:$Rn), 4634 asm, "\t$Ws, $Rt, [$Rn]">, 4635 Sched<[WriteSTX]> { 4636 bits<5> Ws; 4637 bits<5> Rt; 4638 bits<5> Rn; 4639 let Inst{20-16} = Ws; 4640 let Inst{9-5} = Rn; 4641 let Inst{4-0} = Rt; 4642 4643 let Constraints = "@earlyclobber $Ws"; 4644 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4645} 4646 4647class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4648 RegisterClass regtype, string asm> 4649 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4650 (outs GPR32:$Ws), 4651 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4652 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4653 Sched<[WriteSTX]> { 4654 bits<5> Ws; 4655 bits<5> Rt; 4656 bits<5> Rt2; 4657 bits<5> Rn; 4658 let Inst{20-16} = Ws; 4659 let Inst{14-10} = Rt2; 4660 let Inst{9-5} = Rn; 4661 let Inst{4-0} = Rt; 4662 4663 let Constraints = "@earlyclobber $Ws"; 4664} 4665 4666// Armv8.5-A Memory Tagging Extension 4667class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4668 string asm_opnds, string cstr, dag oops, dag iops> 4669 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4670 Sched<[]> { 4671 bits<5> Rn; 4672 4673 let Inst{31-24} = 0b11011001; 4674 let Inst{23-22} = opc1; 4675 let Inst{21} = 1; 4676 // Inst{20-12} defined by subclass 4677 let Inst{11-10} = opc2; 4678 let Inst{9-5} = Rn; 4679 // Inst{4-0} defined by subclass 4680} 4681 4682class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4683 dag oops, dag iops> 4684 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4685 "", oops, iops> { 4686 bits<5> Rt; 4687 4688 let Inst{20-12} = 0b000000000; 4689 let Inst{4-0} = Rt; 4690 4691 let mayLoad = Load; 4692} 4693 4694class MemTagLoad<string asm_insn, string asm_opnds> 4695 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4696 (outs GPR64:$wback), 4697 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4698 bits<5> Rt; 4699 bits<9> offset; 4700 4701 let Inst{20-12} = offset; 4702 let Inst{4-0} = Rt; 4703 4704 let mayLoad = 1; 4705} 4706 4707class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4708 string asm_opnds, string cstr, dag oops, dag iops> 4709 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4710 bits<5> Rt; 4711 bits<9> offset; 4712 4713 let Inst{20-12} = offset; 4714 let Inst{4-0} = Rt; 4715 4716 let mayStore = 1; 4717} 4718 4719multiclass MemTagStore<bits<2> opc1, string insn> { 4720 def i : 4721 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4722 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4723 def PreIndex : 4724 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4725 "$Rn = $wback", 4726 (outs GPR64sp:$wback), 4727 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4728 def PostIndex : 4729 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4730 "$Rn = $wback", 4731 (outs GPR64sp:$wback), 4732 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4733 4734 def : InstAlias<insn # "\t$Rt, [$Rn]", 4735 (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4736} 4737 4738//--- 4739// Exception generation 4740//--- 4741 4742let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4743class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4744 list<dag> pattern = []> 4745 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4746 Sched<[WriteSys]> { 4747 bits<16> imm; 4748 let Inst{31-24} = 0b11010100; 4749 let Inst{23-21} = op1; 4750 let Inst{20-5} = imm; 4751 let Inst{4-2} = 0b000; 4752 let Inst{1-0} = ll; 4753} 4754 4755//--- 4756// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4757//-- 4758let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4759class UDFType<bits<16> opc, string asm> 4760 : I<(outs), (ins uimm16:$imm), 4761 asm, "\t$imm", "", []>, 4762 Sched<[]> { 4763 bits<16> imm; 4764 let Inst{31-16} = opc; 4765 let Inst{15-0} = imm; 4766} 4767} 4768let Predicates = [HasFPARMv8] in { 4769 4770//--- 4771// Floating point to integer conversion 4772//--- 4773 4774let mayRaiseFPException = 1, Uses = [FPCR] in 4775class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4776 RegisterClass srcType, RegisterClass dstType, 4777 string asm, list<dag> pattern> 4778 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4779 asm, "\t$Rd, $Rn", "", pattern>, 4780 Sched<[WriteFCvt]> { 4781 bits<5> Rd; 4782 bits<5> Rn; 4783 let Inst{30-29} = 0b00; 4784 let Inst{28-24} = 0b11110; 4785 let Inst{23-22} = type; 4786 let Inst{21} = 1; 4787 let Inst{20-19} = rmode; 4788 let Inst{18-16} = opcode; 4789 let Inst{15-10} = 0; 4790 let Inst{9-5} = Rn; 4791 let Inst{4-0} = Rd; 4792} 4793 4794let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4795class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4796 RegisterClass srcType, RegisterClass dstType, 4797 Operand immType, string asm, list<dag> pattern> 4798 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4799 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4800 Sched<[WriteFCvt]> { 4801 bits<5> Rd; 4802 bits<5> Rn; 4803 bits<6> scale; 4804 let Inst{30-29} = 0b00; 4805 let Inst{28-24} = 0b11110; 4806 let Inst{23-22} = type; 4807 let Inst{21} = 0; 4808 let Inst{20-19} = rmode; 4809 let Inst{18-16} = opcode; 4810 let Inst{15-10} = scale; 4811 let Inst{9-5} = Rn; 4812 let Inst{4-0} = Rd; 4813} 4814 4815multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4816 SDPatternOperator OpN> { 4817 // Unscaled half-precision to 32-bit 4818 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4819 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4820 let Inst{31} = 0; // 32-bit GPR flag 4821 let Predicates = [HasFullFP16]; 4822 } 4823 4824 // Unscaled half-precision to 64-bit 4825 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4826 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4827 let Inst{31} = 1; // 64-bit GPR flag 4828 let Predicates = [HasFullFP16]; 4829 } 4830 4831 // Unscaled single-precision to 32-bit 4832 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4833 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4834 let Inst{31} = 0; // 32-bit GPR flag 4835 } 4836 4837 // Unscaled single-precision to 64-bit 4838 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4839 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4840 let Inst{31} = 1; // 64-bit GPR flag 4841 } 4842 4843 // Unscaled double-precision to 32-bit 4844 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4845 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4846 let Inst{31} = 0; // 32-bit GPR flag 4847 } 4848 4849 // Unscaled double-precision to 64-bit 4850 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4851 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4852 let Inst{31} = 1; // 64-bit GPR flag 4853 } 4854} 4855 4856multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4857 SDPatternOperator OpN> { 4858 // Scaled half-precision to 32-bit 4859 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4860 fixedpoint_f16_i32, asm, 4861 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4862 fixedpoint_f16_i32:$scale)))]> { 4863 let Inst{31} = 0; // 32-bit GPR flag 4864 let scale{5} = 1; 4865 let Predicates = [HasFullFP16]; 4866 } 4867 4868 // Scaled half-precision to 64-bit 4869 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4870 fixedpoint_f16_i64, asm, 4871 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4872 fixedpoint_f16_i64:$scale)))]> { 4873 let Inst{31} = 1; // 64-bit GPR flag 4874 let Predicates = [HasFullFP16]; 4875 } 4876 4877 // Scaled single-precision to 32-bit 4878 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4879 fixedpoint_f32_i32, asm, 4880 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4881 fixedpoint_f32_i32:$scale)))]> { 4882 let Inst{31} = 0; // 32-bit GPR flag 4883 let scale{5} = 1; 4884 } 4885 4886 // Scaled single-precision to 64-bit 4887 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4888 fixedpoint_f32_i64, asm, 4889 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4890 fixedpoint_f32_i64:$scale)))]> { 4891 let Inst{31} = 1; // 64-bit GPR flag 4892 } 4893 4894 // Scaled double-precision to 32-bit 4895 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4896 fixedpoint_f64_i32, asm, 4897 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4898 fixedpoint_f64_i32:$scale)))]> { 4899 let Inst{31} = 0; // 32-bit GPR flag 4900 let scale{5} = 1; 4901 } 4902 4903 // Scaled double-precision to 64-bit 4904 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4905 fixedpoint_f64_i64, asm, 4906 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4907 fixedpoint_f64_i64:$scale)))]> { 4908 let Inst{31} = 1; // 64-bit GPR flag 4909 } 4910} 4911 4912//--- 4913// Integer to floating point conversion 4914//--- 4915 4916let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4917class BaseIntegerToFP<bit isUnsigned, 4918 RegisterClass srcType, RegisterClass dstType, 4919 Operand immType, string asm, list<dag> pattern> 4920 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4921 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4922 Sched<[WriteFCvt]> { 4923 bits<5> Rd; 4924 bits<5> Rn; 4925 bits<6> scale; 4926 let Inst{30-24} = 0b0011110; 4927 let Inst{21-17} = 0b00001; 4928 let Inst{16} = isUnsigned; 4929 let Inst{15-10} = scale; 4930 let Inst{9-5} = Rn; 4931 let Inst{4-0} = Rd; 4932} 4933 4934let mayRaiseFPException = 1, Uses = [FPCR] in 4935class BaseIntegerToFPUnscaled<bit isUnsigned, 4936 RegisterClass srcType, RegisterClass dstType, 4937 ValueType dvt, string asm, SDPatternOperator node> 4938 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4939 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4940 Sched<[WriteFCvt]> { 4941 bits<5> Rd; 4942 bits<5> Rn; 4943 bits<6> scale; 4944 let Inst{30-24} = 0b0011110; 4945 let Inst{21-17} = 0b10001; 4946 let Inst{16} = isUnsigned; 4947 let Inst{15-10} = 0b000000; 4948 let Inst{9-5} = Rn; 4949 let Inst{4-0} = Rd; 4950} 4951 4952multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 4953 // Unscaled 4954 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4955 let Inst{31} = 0; // 32-bit GPR flag 4956 let Inst{23-22} = 0b11; // 16-bit FPR flag 4957 let Predicates = [HasFullFP16]; 4958 } 4959 4960 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4961 let Inst{31} = 0; // 32-bit GPR flag 4962 let Inst{23-22} = 0b00; // 32-bit FPR flag 4963 } 4964 4965 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4966 let Inst{31} = 0; // 32-bit GPR flag 4967 let Inst{23-22} = 0b01; // 64-bit FPR flag 4968 } 4969 4970 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4971 let Inst{31} = 1; // 64-bit GPR flag 4972 let Inst{23-22} = 0b11; // 16-bit FPR flag 4973 let Predicates = [HasFullFP16]; 4974 } 4975 4976 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4977 let Inst{31} = 1; // 64-bit GPR flag 4978 let Inst{23-22} = 0b00; // 32-bit FPR flag 4979 } 4980 4981 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4982 let Inst{31} = 1; // 64-bit GPR flag 4983 let Inst{23-22} = 0b01; // 64-bit FPR flag 4984 } 4985 4986 // Scaled 4987 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4988 [(set (f16 FPR16:$Rd), 4989 (fdiv (node GPR32:$Rn), 4990 fixedpoint_f16_i32:$scale))]> { 4991 let Inst{31} = 0; // 32-bit GPR flag 4992 let Inst{23-22} = 0b11; // 16-bit FPR flag 4993 let scale{5} = 1; 4994 let Predicates = [HasFullFP16]; 4995 } 4996 4997 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4998 [(set FPR32:$Rd, 4999 (fdiv (node GPR32:$Rn), 5000 fixedpoint_f32_i32:$scale))]> { 5001 let Inst{31} = 0; // 32-bit GPR flag 5002 let Inst{23-22} = 0b00; // 32-bit FPR flag 5003 let scale{5} = 1; 5004 } 5005 5006 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 5007 [(set FPR64:$Rd, 5008 (fdiv (node GPR32:$Rn), 5009 fixedpoint_f64_i32:$scale))]> { 5010 let Inst{31} = 0; // 32-bit GPR flag 5011 let Inst{23-22} = 0b01; // 64-bit FPR flag 5012 let scale{5} = 1; 5013 } 5014 5015 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 5016 [(set (f16 FPR16:$Rd), 5017 (fdiv (node GPR64:$Rn), 5018 fixedpoint_f16_i64:$scale))]> { 5019 let Inst{31} = 1; // 64-bit GPR flag 5020 let Inst{23-22} = 0b11; // 16-bit FPR flag 5021 let Predicates = [HasFullFP16]; 5022 } 5023 5024 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 5025 [(set FPR32:$Rd, 5026 (fdiv (node GPR64:$Rn), 5027 fixedpoint_f32_i64:$scale))]> { 5028 let Inst{31} = 1; // 64-bit GPR flag 5029 let Inst{23-22} = 0b00; // 32-bit FPR flag 5030 } 5031 5032 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 5033 [(set FPR64:$Rd, 5034 (fdiv (node GPR64:$Rn), 5035 fixedpoint_f64_i64:$scale))]> { 5036 let Inst{31} = 1; // 64-bit GPR flag 5037 let Inst{23-22} = 0b01; // 64-bit FPR flag 5038 } 5039} 5040 5041//--- 5042// Unscaled integer <-> floating point conversion (i.e. FMOV) 5043//--- 5044 5045let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5046class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 5047 RegisterClass srcType, RegisterClass dstType, 5048 string asm> 5049 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 5050 // We use COPY_TO_REGCLASS for these bitconvert operations. 5051 // copyPhysReg() expands the resultant COPY instructions after 5052 // regalloc is done. This gives greater freedom for the allocator 5053 // and related passes (coalescing, copy propagation, et. al.) to 5054 // be more effective. 5055 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 5056 Sched<[WriteFCopy]> { 5057 bits<5> Rd; 5058 bits<5> Rn; 5059 let Inst{30-24} = 0b0011110; 5060 let Inst{21} = 1; 5061 let Inst{20-19} = rmode; 5062 let Inst{18-16} = opcode; 5063 let Inst{15-10} = 0b000000; 5064 let Inst{9-5} = Rn; 5065 let Inst{4-0} = Rd; 5066} 5067 5068let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5069class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 5070 RegisterClass srcType, RegisterOperand dstType, string asm, 5071 string kind> 5072 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5073 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 5074 Sched<[WriteFCopy]> { 5075 bits<5> Rd; 5076 bits<5> Rn; 5077 let Inst{30-23} = 0b00111101; 5078 let Inst{21} = 1; 5079 let Inst{20-19} = rmode; 5080 let Inst{18-16} = opcode; 5081 let Inst{15-10} = 0b000000; 5082 let Inst{9-5} = Rn; 5083 let Inst{4-0} = Rd; 5084 5085 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5086} 5087 5088let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5089class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 5090 RegisterOperand srcType, RegisterClass dstType, string asm, 5091 string kind> 5092 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5093 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 5094 Sched<[WriteFCopy]> { 5095 bits<5> Rd; 5096 bits<5> Rn; 5097 let Inst{30-23} = 0b00111101; 5098 let Inst{21} = 1; 5099 let Inst{20-19} = rmode; 5100 let Inst{18-16} = opcode; 5101 let Inst{15-10} = 0b000000; 5102 let Inst{9-5} = Rn; 5103 let Inst{4-0} = Rd; 5104 5105 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5106} 5107 5108 5109multiclass UnscaledConversion<string asm> { 5110 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 5111 let Inst{31} = 0; // 32-bit GPR flag 5112 let Inst{23-22} = 0b11; // 16-bit FPR flag 5113 let Predicates = [HasFullFP16]; 5114 } 5115 5116 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 5117 let Inst{31} = 1; // 64-bit GPR flag 5118 let Inst{23-22} = 0b11; // 16-bit FPR flag 5119 let Predicates = [HasFullFP16]; 5120 } 5121 5122 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 5123 let Inst{31} = 0; // 32-bit GPR flag 5124 let Inst{23-22} = 0b00; // 32-bit FPR flag 5125 } 5126 5127 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 5128 let Inst{31} = 1; // 64-bit GPR flag 5129 let Inst{23-22} = 0b01; // 64-bit FPR flag 5130 } 5131 5132 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 5133 let Inst{31} = 0; // 32-bit GPR flag 5134 let Inst{23-22} = 0b11; // 16-bit FPR flag 5135 let Predicates = [HasFullFP16]; 5136 } 5137 5138 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 5139 let Inst{31} = 1; // 64-bit GPR flag 5140 let Inst{23-22} = 0b11; // 16-bit FPR flag 5141 let Predicates = [HasFullFP16]; 5142 } 5143 5144 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 5145 let Inst{31} = 0; // 32-bit GPR flag 5146 let Inst{23-22} = 0b00; // 32-bit FPR flag 5147 } 5148 5149 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 5150 let Inst{31} = 1; // 64-bit GPR flag 5151 let Inst{23-22} = 0b01; // 64-bit FPR flag 5152 } 5153 5154 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 5155 asm, ".d"> { 5156 let Inst{31} = 1; 5157 let Inst{22} = 0; 5158 } 5159 5160 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 5161 asm, ".d"> { 5162 let Inst{31} = 1; 5163 let Inst{22} = 0; 5164 } 5165} 5166 5167//--- 5168// Floating point conversion 5169//--- 5170 5171let mayRaiseFPException = 1, Uses = [FPCR] in 5172class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 5173 RegisterClass srcType, string asm, list<dag> pattern> 5174 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 5175 Sched<[WriteFCvt]> { 5176 bits<5> Rd; 5177 bits<5> Rn; 5178 let Inst{31-24} = 0b00011110; 5179 let Inst{23-22} = type; 5180 let Inst{21-17} = 0b10001; 5181 let Inst{16-15} = opcode; 5182 let Inst{14-10} = 0b10000; 5183 let Inst{9-5} = Rn; 5184 let Inst{4-0} = Rd; 5185} 5186 5187multiclass FPConversion<string asm> { 5188 // Double-precision to Half-precision 5189 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 5190 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 5191 5192 // Double-precision to Single-precision 5193 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 5194 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5195 5196 // Half-precision to Double-precision 5197 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5198 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5199 5200 // Half-precision to Single-precision 5201 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5202 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5203 5204 // Single-precision to Double-precision 5205 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5206 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5207 5208 // Single-precision to Half-precision 5209 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5210 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5211} 5212 5213//--- 5214// Single operand floating point data processing 5215//--- 5216 5217let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5218class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5219 ValueType vt, string asm, SDPatternOperator node> 5220 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5221 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5222 Sched<[WriteF]> { 5223 bits<5> Rd; 5224 bits<5> Rn; 5225 let Inst{31-24} = 0b00011110; 5226 let Inst{21} = 0b1; 5227 let Inst{20-15} = opcode; 5228 let Inst{14-10} = 0b10000; 5229 let Inst{9-5} = Rn; 5230 let Inst{4-0} = Rd; 5231} 5232 5233multiclass SingleOperandFPData<bits<4> opcode, string asm, 5234 SDPatternOperator node = null_frag, 5235 int fpexceptions = 1> { 5236 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 5237 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5238 let Inst{23-22} = 0b11; // 16-bit size flag 5239 let Predicates = [HasFullFP16]; 5240 } 5241 5242 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5243 let Inst{23-22} = 0b00; // 32-bit size flag 5244 } 5245 5246 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5247 let Inst{23-22} = 0b01; // 64-bit size flag 5248 } 5249 } 5250} 5251 5252multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5253 SDPatternOperator node = null_frag> 5254 : SingleOperandFPData<opcode, asm, node, 0>; 5255 5256let mayRaiseFPException = 1, Uses = [FPCR] in 5257multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5258 SDPatternOperator node = null_frag>{ 5259 5260 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5261 let Inst{23-22} = 0b00; // 32-bit registers 5262 } 5263 5264 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5265 let Inst{23-22} = 0b01; // 64-bit registers 5266 } 5267} 5268 5269// FRInt[32|64][Z|N] instructions 5270multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5271 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5272 5273//--- 5274// Two operand floating point data processing 5275//--- 5276 5277let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5278class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5279 string asm, list<dag> pat> 5280 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5281 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5282 Sched<[WriteF]> { 5283 bits<5> Rd; 5284 bits<5> Rn; 5285 bits<5> Rm; 5286 let Inst{31-24} = 0b00011110; 5287 let Inst{21} = 1; 5288 let Inst{20-16} = Rm; 5289 let Inst{15-12} = opcode; 5290 let Inst{11-10} = 0b10; 5291 let Inst{9-5} = Rn; 5292 let Inst{4-0} = Rd; 5293} 5294 5295multiclass TwoOperandFPData<bits<4> opcode, string asm, 5296 SDPatternOperator node = null_frag> { 5297 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5298 [(set (f16 FPR16:$Rd), 5299 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5300 let Inst{23-22} = 0b11; // 16-bit size flag 5301 let Predicates = [HasFullFP16]; 5302 } 5303 5304 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5305 [(set (f32 FPR32:$Rd), 5306 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5307 let Inst{23-22} = 0b00; // 32-bit size flag 5308 } 5309 5310 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5311 [(set (f64 FPR64:$Rd), 5312 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5313 let Inst{23-22} = 0b01; // 64-bit size flag 5314 } 5315} 5316 5317multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5318 SDPatternOperator node> { 5319 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5320 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5321 let Inst{23-22} = 0b11; // 16-bit size flag 5322 let Predicates = [HasFullFP16]; 5323 } 5324 5325 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5326 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5327 let Inst{23-22} = 0b00; // 32-bit size flag 5328 } 5329 5330 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5331 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5332 let Inst{23-22} = 0b01; // 64-bit size flag 5333 } 5334} 5335 5336 5337//--- 5338// Three operand floating point data processing 5339//--- 5340 5341let mayRaiseFPException = 1, Uses = [FPCR] in 5342class BaseThreeOperandFPData<bit isNegated, bit isSub, 5343 RegisterClass regtype, string asm, list<dag> pat> 5344 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5345 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5346 Sched<[WriteFMul]> { 5347 bits<5> Rd; 5348 bits<5> Rn; 5349 bits<5> Rm; 5350 bits<5> Ra; 5351 let Inst{31-24} = 0b00011111; 5352 let Inst{21} = isNegated; 5353 let Inst{20-16} = Rm; 5354 let Inst{15} = isSub; 5355 let Inst{14-10} = Ra; 5356 let Inst{9-5} = Rn; 5357 let Inst{4-0} = Rd; 5358} 5359 5360multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5361 SDPatternOperator node> { 5362 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5363 [(set (f16 FPR16:$Rd), 5364 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5365 let Inst{23-22} = 0b11; // 16-bit size flag 5366 let Predicates = [HasFullFP16]; 5367 } 5368 5369 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5370 [(set FPR32:$Rd, 5371 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5372 let Inst{23-22} = 0b00; // 32-bit size flag 5373 } 5374 5375 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5376 [(set FPR64:$Rd, 5377 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5378 let Inst{23-22} = 0b01; // 64-bit size flag 5379 } 5380} 5381 5382//--- 5383// Floating point data comparisons 5384//--- 5385 5386let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5387class BaseOneOperandFPComparison<bit signalAllNans, 5388 RegisterClass regtype, string asm, 5389 list<dag> pat> 5390 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5391 Sched<[WriteFCmp]> { 5392 bits<5> Rn; 5393 let Inst{31-24} = 0b00011110; 5394 let Inst{21} = 1; 5395 5396 let Inst{15-10} = 0b001000; 5397 let Inst{9-5} = Rn; 5398 let Inst{4} = signalAllNans; 5399 let Inst{3-0} = 0b1000; 5400 5401 // Rm should be 0b00000 canonically, but we need to accept any value. 5402 let PostEncoderMethod = "fixOneOperandFPComparison"; 5403} 5404 5405let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5406class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5407 string asm, list<dag> pat> 5408 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5409 Sched<[WriteFCmp]> { 5410 bits<5> Rm; 5411 bits<5> Rn; 5412 let Inst{31-24} = 0b00011110; 5413 let Inst{21} = 1; 5414 let Inst{20-16} = Rm; 5415 let Inst{15-10} = 0b001000; 5416 let Inst{9-5} = Rn; 5417 let Inst{4} = signalAllNans; 5418 let Inst{3-0} = 0b0000; 5419} 5420 5421multiclass FPComparison<bit signalAllNans, string asm, 5422 SDPatternOperator OpNode = null_frag> { 5423 let Defs = [NZCV] in { 5424 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5425 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5426 let Inst{23-22} = 0b11; 5427 let Predicates = [HasFullFP16]; 5428 } 5429 5430 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5431 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5432 let Inst{23-22} = 0b11; 5433 let Predicates = [HasFullFP16]; 5434 } 5435 5436 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5437 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5438 let Inst{23-22} = 0b00; 5439 } 5440 5441 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5442 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5443 let Inst{23-22} = 0b00; 5444 } 5445 5446 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5447 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5448 let Inst{23-22} = 0b01; 5449 } 5450 5451 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5452 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5453 let Inst{23-22} = 0b01; 5454 } 5455 } // Defs = [NZCV] 5456} 5457 5458//--- 5459// Floating point conditional comparisons 5460//--- 5461 5462let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5463class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5464 string mnemonic, list<dag> pat> 5465 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5466 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5467 Sched<[WriteFCmp]> { 5468 let Uses = [NZCV]; 5469 let Defs = [NZCV]; 5470 5471 bits<5> Rn; 5472 bits<5> Rm; 5473 bits<4> nzcv; 5474 bits<4> cond; 5475 5476 let Inst{31-24} = 0b00011110; 5477 let Inst{21} = 1; 5478 let Inst{20-16} = Rm; 5479 let Inst{15-12} = cond; 5480 let Inst{11-10} = 0b01; 5481 let Inst{9-5} = Rn; 5482 let Inst{4} = signalAllNans; 5483 let Inst{3-0} = nzcv; 5484} 5485 5486multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5487 SDPatternOperator OpNode = null_frag> { 5488 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5489 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5490 (i32 imm:$cond), NZCV))]> { 5491 let Inst{23-22} = 0b11; 5492 let Predicates = [HasFullFP16]; 5493 } 5494 5495 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5496 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5497 (i32 imm:$cond), NZCV))]> { 5498 let Inst{23-22} = 0b00; 5499 } 5500 5501 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5502 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5503 (i32 imm:$cond), NZCV))]> { 5504 let Inst{23-22} = 0b01; 5505 } 5506} 5507 5508//--- 5509// Floating point conditional select 5510//--- 5511 5512class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5513 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5514 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5515 [(set regtype:$Rd, 5516 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5517 (i32 imm:$cond), NZCV))]>, 5518 Sched<[WriteF]> { 5519 bits<5> Rd; 5520 bits<5> Rn; 5521 bits<5> Rm; 5522 bits<4> cond; 5523 5524 let Inst{31-24} = 0b00011110; 5525 let Inst{21} = 1; 5526 let Inst{20-16} = Rm; 5527 let Inst{15-12} = cond; 5528 let Inst{11-10} = 0b11; 5529 let Inst{9-5} = Rn; 5530 let Inst{4-0} = Rd; 5531} 5532 5533multiclass FPCondSelect<string asm> { 5534 let Uses = [NZCV] in { 5535 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5536 let Inst{23-22} = 0b11; 5537 let Predicates = [HasFullFP16]; 5538 } 5539 5540 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5541 let Inst{23-22} = 0b00; 5542 } 5543 5544 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5545 let Inst{23-22} = 0b01; 5546 } 5547 } // Uses = [NZCV] 5548} 5549 5550//--- 5551// Floating move immediate 5552//--- 5553 5554class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5555 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5556 [(set regtype:$Rd, fpimmtype:$imm)]>, 5557 Sched<[WriteFImm]> { 5558 bits<5> Rd; 5559 bits<8> imm; 5560 let Inst{31-24} = 0b00011110; 5561 let Inst{21} = 1; 5562 let Inst{20-13} = imm; 5563 let Inst{12-5} = 0b10000000; 5564 let Inst{4-0} = Rd; 5565} 5566 5567multiclass FPMoveImmediate<string asm> { 5568 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5569 let Inst{23-22} = 0b11; 5570 let Predicates = [HasFullFP16]; 5571 } 5572 5573 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5574 let Inst{23-22} = 0b00; 5575 } 5576 5577 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5578 let Inst{23-22} = 0b01; 5579 } 5580} 5581} // end of 'let Predicates = [HasFPARMv8]' 5582 5583//---------------------------------------------------------------------------- 5584// AdvSIMD 5585//---------------------------------------------------------------------------- 5586 5587let Predicates = [HasNEON] in { 5588 5589//---------------------------------------------------------------------------- 5590// AdvSIMD three register vector instructions 5591//---------------------------------------------------------------------------- 5592 5593let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5594class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5595 RegisterOperand regtype, string asm, string kind, 5596 list<dag> pattern> 5597 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5598 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5599 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5600 Sched<[!if(Q, WriteVq, WriteVd)]> { 5601 bits<5> Rd; 5602 bits<5> Rn; 5603 bits<5> Rm; 5604 let Inst{31} = 0; 5605 let Inst{30} = Q; 5606 let Inst{29} = U; 5607 let Inst{28-24} = 0b01110; 5608 let Inst{23-21} = size; 5609 let Inst{20-16} = Rm; 5610 let Inst{15-11} = opcode; 5611 let Inst{10} = 1; 5612 let Inst{9-5} = Rn; 5613 let Inst{4-0} = Rd; 5614} 5615 5616let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5617class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5618 RegisterOperand regtype, string asm, string kind, 5619 list<dag> pattern> 5620 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5621 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5622 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5623 Sched<[!if(Q, WriteVq, WriteVd)]> { 5624 bits<5> Rd; 5625 bits<5> Rn; 5626 bits<5> Rm; 5627 let Inst{31} = 0; 5628 let Inst{30} = Q; 5629 let Inst{29} = U; 5630 let Inst{28-24} = 0b01110; 5631 let Inst{23-21} = size; 5632 let Inst{20-16} = Rm; 5633 let Inst{15-11} = opcode; 5634 let Inst{10} = 1; 5635 let Inst{9-5} = Rn; 5636 let Inst{4-0} = Rd; 5637} 5638 5639let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5640class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5641 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5642 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5643 5644multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5645 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5646 [(set (v8i8 V64:$dst), 5647 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5648 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5649 [(set (v16i8 V128:$dst), 5650 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5651 (v16i8 V128:$Rm)))]>; 5652 5653 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5654 (v4i16 V64:$RHS))), 5655 (!cast<Instruction>(NAME#"v8i8") 5656 V64:$LHS, V64:$MHS, V64:$RHS)>; 5657 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5658 (v2i32 V64:$RHS))), 5659 (!cast<Instruction>(NAME#"v8i8") 5660 V64:$LHS, V64:$MHS, V64:$RHS)>; 5661 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5662 (v1i64 V64:$RHS))), 5663 (!cast<Instruction>(NAME#"v8i8") 5664 V64:$LHS, V64:$MHS, V64:$RHS)>; 5665 5666 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5667 (v8i16 V128:$RHS))), 5668 (!cast<Instruction>(NAME#"v16i8") 5669 V128:$LHS, V128:$MHS, V128:$RHS)>; 5670 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5671 (v4i32 V128:$RHS))), 5672 (!cast<Instruction>(NAME#"v16i8") 5673 V128:$LHS, V128:$MHS, V128:$RHS)>; 5674 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5675 (v2i64 V128:$RHS))), 5676 (!cast<Instruction>(NAME#"v16i8") 5677 V128:$LHS, V128:$MHS, V128:$RHS)>; 5678} 5679 5680// All operand sizes distinguished in the encoding. 5681multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5682 SDPatternOperator OpNode> { 5683 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5684 asm, ".8b", 5685 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5686 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5687 asm, ".16b", 5688 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5689 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5690 asm, ".4h", 5691 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5692 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5693 asm, ".8h", 5694 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5695 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5696 asm, ".2s", 5697 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5698 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5699 asm, ".4s", 5700 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5701 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5702 asm, ".2d", 5703 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5704} 5705 5706multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5707 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5708 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5709 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5710 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5711 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5712 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5713 5714 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5715 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5716 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5717 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5718 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5719 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5720 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5721 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5722} 5723 5724// As above, but D sized elements unsupported. 5725multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5726 SDPatternOperator OpNode> { 5727 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5728 asm, ".8b", 5729 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5730 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5731 asm, ".16b", 5732 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5733 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5734 asm, ".4h", 5735 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5736 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5737 asm, ".8h", 5738 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5739 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5740 asm, ".2s", 5741 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5742 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5743 asm, ".4s", 5744 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5745} 5746 5747multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5748 SDPatternOperator OpNode> { 5749 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5750 asm, ".8b", 5751 [(set (v8i8 V64:$dst), 5752 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5753 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5754 asm, ".16b", 5755 [(set (v16i8 V128:$dst), 5756 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5757 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5758 asm, ".4h", 5759 [(set (v4i16 V64:$dst), 5760 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5761 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5762 asm, ".8h", 5763 [(set (v8i16 V128:$dst), 5764 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5765 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5766 asm, ".2s", 5767 [(set (v2i32 V64:$dst), 5768 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5769 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5770 asm, ".4s", 5771 [(set (v4i32 V128:$dst), 5772 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5773} 5774 5775// As above, but only B sized elements supported. 5776multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5777 SDPatternOperator OpNode> { 5778 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5779 asm, ".8b", 5780 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5781 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5782 asm, ".16b", 5783 [(set (v16i8 V128:$Rd), 5784 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5785} 5786 5787// As above, but only floating point elements supported. 5788let mayRaiseFPException = 1, Uses = [FPCR] in 5789multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5790 string asm, SDPatternOperator OpNode> { 5791 let Predicates = [HasNEON, HasFullFP16] in { 5792 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5793 asm, ".4h", 5794 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5795 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5796 asm, ".8h", 5797 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5798 } // Predicates = [HasNEON, HasFullFP16] 5799 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5800 asm, ".2s", 5801 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5802 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5803 asm, ".4s", 5804 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5805 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5806 asm, ".2d", 5807 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5808} 5809 5810let mayRaiseFPException = 1, Uses = [FPCR] in 5811multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5812 string asm, 5813 SDPatternOperator OpNode> { 5814 let Predicates = [HasNEON, HasFullFP16] in { 5815 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5816 asm, ".4h", 5817 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5818 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5819 asm, ".8h", 5820 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5821 } // Predicates = [HasNEON, HasFullFP16] 5822 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5823 asm, ".2s", 5824 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5825 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5826 asm, ".4s", 5827 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5828 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5829 asm, ".2d", 5830 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5831} 5832 5833let mayRaiseFPException = 1, Uses = [FPCR] in 5834multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5835 string asm, SDPatternOperator OpNode> { 5836 let Predicates = [HasNEON, HasFullFP16] in { 5837 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5838 asm, ".4h", 5839 [(set (v4f16 V64:$dst), 5840 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5841 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5842 asm, ".8h", 5843 [(set (v8f16 V128:$dst), 5844 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5845 } // Predicates = [HasNEON, HasFullFP16] 5846 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5847 asm, ".2s", 5848 [(set (v2f32 V64:$dst), 5849 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5850 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5851 asm, ".4s", 5852 [(set (v4f32 V128:$dst), 5853 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5854 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5855 asm, ".2d", 5856 [(set (v2f64 V128:$dst), 5857 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5858} 5859 5860// As above, but D and B sized elements unsupported. 5861let mayRaiseFPException = 1, Uses = [FPCR] in 5862multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5863 SDPatternOperator OpNode> { 5864 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5865 asm, ".4h", 5866 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5867 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5868 asm, ".8h", 5869 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5870 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5871 asm, ".2s", 5872 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5873 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5874 asm, ".4s", 5875 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5876} 5877 5878// Logical three vector ops share opcode bits, and only use B sized elements. 5879multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5880 SDPatternOperator OpNode = null_frag> { 5881 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5882 asm, ".8b", 5883 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5884 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5885 asm, ".16b", 5886 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5887 5888 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5889 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5890 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5891 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5892 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5893 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5894 5895 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5896 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5897 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5898 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5899 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5900 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5901} 5902 5903multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5904 string asm, SDPatternOperator OpNode = null_frag> { 5905 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5906 asm, ".8b", 5907 [(set (v8i8 V64:$dst), 5908 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5909 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5910 asm, ".16b", 5911 [(set (v16i8 V128:$dst), 5912 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5913 (v16i8 V128:$Rm)))]>; 5914 5915 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5916 (v4i16 V64:$RHS))), 5917 (!cast<Instruction>(NAME#"v8i8") 5918 V64:$LHS, V64:$MHS, V64:$RHS)>; 5919 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5920 (v2i32 V64:$RHS))), 5921 (!cast<Instruction>(NAME#"v8i8") 5922 V64:$LHS, V64:$MHS, V64:$RHS)>; 5923 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5924 (v1i64 V64:$RHS))), 5925 (!cast<Instruction>(NAME#"v8i8") 5926 V64:$LHS, V64:$MHS, V64:$RHS)>; 5927 5928 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5929 (v8i16 V128:$RHS))), 5930 (!cast<Instruction>(NAME#"v16i8") 5931 V128:$LHS, V128:$MHS, V128:$RHS)>; 5932 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5933 (v4i32 V128:$RHS))), 5934 (!cast<Instruction>(NAME#"v16i8") 5935 V128:$LHS, V128:$MHS, V128:$RHS)>; 5936 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5937 (v2i64 V128:$RHS))), 5938 (!cast<Instruction>(NAME#"v16i8") 5939 V128:$LHS, V128:$MHS, V128:$RHS)>; 5940} 5941 5942// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5943// bytes from S-sized elements. 5944class BaseSIMDThreeSameVectorDot<bit Q, bit U, bit Mixed, string asm, string kind1, 5945 string kind2, RegisterOperand RegType, 5946 ValueType AccumType, ValueType InputType, 5947 SDPatternOperator OpNode> : 5948 BaseSIMDThreeSameVectorTied<Q, U, 0b100, {0b1001, Mixed}, RegType, asm, kind1, 5949 [(set (AccumType RegType:$dst), 5950 (OpNode (AccumType RegType:$Rd), 5951 (InputType RegType:$Rn), 5952 (InputType RegType:$Rm)))]> { 5953 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5954} 5955 5956multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 5957 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, Mixed, asm, ".2s", ".8b", V64, 5958 v2i32, v8i8, OpNode>; 5959 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, Mixed, asm, ".4s", ".16b", V128, 5960 v4i32, v16i8, OpNode>; 5961} 5962 5963// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5964// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5965// 8H to 4S, when Q=1). 5966let mayRaiseFPException = 1, Uses = [FPCR] in 5967class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5968 string kind2, RegisterOperand RegType, 5969 ValueType AccumType, ValueType InputType, 5970 SDPatternOperator OpNode> : 5971 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5972 [(set (AccumType RegType:$dst), 5973 (OpNode (AccumType RegType:$Rd), 5974 (InputType RegType:$Rn), 5975 (InputType RegType:$Rm)))]> { 5976 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5977 let Inst{13} = b13; 5978} 5979 5980multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5981 SDPatternOperator OpNode> { 5982 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5983 v2f32, v4f16, OpNode>; 5984 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5985 v4f32, v8f16, OpNode>; 5986} 5987 5988 5989//---------------------------------------------------------------------------- 5990// AdvSIMD two register vector instructions. 5991//---------------------------------------------------------------------------- 5992 5993let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5994class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5995 bits<2> size2, RegisterOperand regtype, string asm, 5996 string dstkind, string srckind, list<dag> pattern> 5997 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5998 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5999 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 6000 Sched<[!if(Q, WriteVq, WriteVd)]> { 6001 bits<5> Rd; 6002 bits<5> Rn; 6003 let Inst{31} = 0; 6004 let Inst{30} = Q; 6005 let Inst{29} = U; 6006 let Inst{28-24} = 0b01110; 6007 let Inst{23-22} = size; 6008 let Inst{21} = 0b1; 6009 let Inst{20-19} = size2; 6010 let Inst{18-17} = 0b00; 6011 let Inst{16-12} = opcode; 6012 let Inst{11-10} = 0b10; 6013 let Inst{9-5} = Rn; 6014 let Inst{4-0} = Rd; 6015} 6016 6017let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6018class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6019 bits<2> size2, RegisterOperand regtype, 6020 string asm, string dstkind, string srckind, 6021 list<dag> pattern> 6022 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 6023 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6024 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6025 Sched<[!if(Q, WriteVq, WriteVd)]> { 6026 bits<5> Rd; 6027 bits<5> Rn; 6028 let Inst{31} = 0; 6029 let Inst{30} = Q; 6030 let Inst{29} = U; 6031 let Inst{28-24} = 0b01110; 6032 let Inst{23-22} = size; 6033 let Inst{21} = 0b1; 6034 let Inst{20-19} = size2; 6035 let Inst{18-17} = 0b00; 6036 let Inst{16-12} = opcode; 6037 let Inst{11-10} = 0b10; 6038 let Inst{9-5} = Rn; 6039 let Inst{4-0} = Rd; 6040} 6041 6042// Supports B, H, and S element sizes. 6043multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 6044 SDPatternOperator OpNode> { 6045 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6046 asm, ".8b", ".8b", 6047 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6048 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6049 asm, ".16b", ".16b", 6050 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6051 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6052 asm, ".4h", ".4h", 6053 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6054 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6055 asm, ".8h", ".8h", 6056 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6057 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6058 asm, ".2s", ".2s", 6059 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6060 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6061 asm, ".4s", ".4s", 6062 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6063} 6064 6065class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 6066 RegisterOperand regtype, string asm, string dstkind, 6067 string srckind, string amount> 6068 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 6069 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 6070 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 6071 Sched<[WriteVq]> { 6072 bits<5> Rd; 6073 bits<5> Rn; 6074 let Inst{31} = 0; 6075 let Inst{30} = Q; 6076 let Inst{29-24} = 0b101110; 6077 let Inst{23-22} = size; 6078 let Inst{21-10} = 0b100001001110; 6079 let Inst{9-5} = Rn; 6080 let Inst{4-0} = Rd; 6081} 6082 6083multiclass SIMDVectorLShiftLongBySizeBHS { 6084 let hasSideEffects = 0 in { 6085 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 6086 "shll", ".8h", ".8b", "8">; 6087 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 6088 "shll2", ".8h", ".16b", "8">; 6089 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 6090 "shll", ".4s", ".4h", "16">; 6091 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 6092 "shll2", ".4s", ".8h", "16">; 6093 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 6094 "shll", ".2d", ".2s", "32">; 6095 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 6096 "shll2", ".2d", ".4s", "32">; 6097 } 6098} 6099 6100// Supports all element sizes. 6101multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 6102 SDPatternOperator OpNode> { 6103 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6104 asm, ".4h", ".8b", 6105 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6106 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6107 asm, ".8h", ".16b", 6108 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6109 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6110 asm, ".2s", ".4h", 6111 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6112 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6113 asm, ".4s", ".8h", 6114 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6115 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6116 asm, ".1d", ".2s", 6117 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6118 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6119 asm, ".2d", ".4s", 6120 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6121} 6122 6123multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 6124 SDPatternOperator OpNode> { 6125 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6126 asm, ".4h", ".8b", 6127 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 6128 (v8i8 V64:$Rn)))]>; 6129 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6130 asm, ".8h", ".16b", 6131 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 6132 (v16i8 V128:$Rn)))]>; 6133 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6134 asm, ".2s", ".4h", 6135 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 6136 (v4i16 V64:$Rn)))]>; 6137 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6138 asm, ".4s", ".8h", 6139 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 6140 (v8i16 V128:$Rn)))]>; 6141 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6142 asm, ".1d", ".2s", 6143 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 6144 (v2i32 V64:$Rn)))]>; 6145 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6146 asm, ".2d", ".4s", 6147 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 6148 (v4i32 V128:$Rn)))]>; 6149} 6150 6151// Supports all element sizes, except 1xD. 6152multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 6153 SDPatternOperator OpNode> { 6154 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6155 asm, ".8b", ".8b", 6156 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 6157 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6158 asm, ".16b", ".16b", 6159 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 6160 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6161 asm, ".4h", ".4h", 6162 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 6163 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6164 asm, ".8h", ".8h", 6165 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 6166 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6167 asm, ".2s", ".2s", 6168 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 6169 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6170 asm, ".4s", ".4s", 6171 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 6172 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 6173 asm, ".2d", ".2d", 6174 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 6175} 6176 6177multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 6178 SDPatternOperator OpNode = null_frag> { 6179 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6180 asm, ".8b", ".8b", 6181 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6182 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6183 asm, ".16b", ".16b", 6184 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6185 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6186 asm, ".4h", ".4h", 6187 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6188 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6189 asm, ".8h", ".8h", 6190 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6191 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6192 asm, ".2s", ".2s", 6193 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6194 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6195 asm, ".4s", ".4s", 6196 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6197 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6198 asm, ".2d", ".2d", 6199 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6200} 6201 6202 6203// Supports only B element sizes. 6204multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6205 SDPatternOperator OpNode> { 6206 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6207 asm, ".8b", ".8b", 6208 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6209 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6210 asm, ".16b", ".16b", 6211 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6212 6213} 6214 6215// Supports only B and H element sizes. 6216multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6217 SDPatternOperator OpNode> { 6218 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6219 asm, ".8b", ".8b", 6220 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6221 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6222 asm, ".16b", ".16b", 6223 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6224 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6225 asm, ".4h", ".4h", 6226 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6227 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6228 asm, ".8h", ".8h", 6229 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6230} 6231 6232// Supports H, S and D element sizes, uses high bit of the size field 6233// as an extra opcode bit. 6234multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6235 SDPatternOperator OpNode, 6236 int fpexceptions = 1> { 6237 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 6238 let Predicates = [HasNEON, HasFullFP16] in { 6239 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6240 asm, ".4h", ".4h", 6241 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6242 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6243 asm, ".8h", ".8h", 6244 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6245 } // Predicates = [HasNEON, HasFullFP16] 6246 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6247 asm, ".2s", ".2s", 6248 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6249 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6250 asm, ".4s", ".4s", 6251 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6252 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6253 asm, ".2d", ".2d", 6254 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6255 } 6256} 6257 6258multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6259 SDPatternOperator OpNode> 6260 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6261 6262// Supports only S and D element sizes 6263let mayRaiseFPException = 1, Uses = [FPCR] in 6264multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6265 SDPatternOperator OpNode = null_frag> { 6266 6267 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6268 asm, ".2s", ".2s", 6269 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6270 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6271 asm, ".4s", ".4s", 6272 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6273 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6274 asm, ".2d", ".2d", 6275 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6276} 6277 6278multiclass FRIntNNTVector<bit U, bit op, string asm, 6279 SDPatternOperator OpNode = null_frag> : 6280 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6281 6282// Supports only S element size. 6283multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6284 SDPatternOperator OpNode> { 6285 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6286 asm, ".2s", ".2s", 6287 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6288 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6289 asm, ".4s", ".4s", 6290 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6291} 6292 6293let mayRaiseFPException = 1, Uses = [FPCR] in 6294multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6295 SDPatternOperator OpNode> { 6296 let Predicates = [HasNEON, HasFullFP16] in { 6297 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6298 asm, ".4h", ".4h", 6299 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6300 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6301 asm, ".8h", ".8h", 6302 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6303 } // Predicates = [HasNEON, HasFullFP16] 6304 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6305 asm, ".2s", ".2s", 6306 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6307 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6308 asm, ".4s", ".4s", 6309 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6310 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6311 asm, ".2d", ".2d", 6312 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6313} 6314 6315let mayRaiseFPException = 1, Uses = [FPCR] in 6316multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6317 SDPatternOperator OpNode> { 6318 let Predicates = [HasNEON, HasFullFP16] in { 6319 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6320 asm, ".4h", ".4h", 6321 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6322 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6323 asm, ".8h", ".8h", 6324 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6325 } // Predicates = [HasNEON, HasFullFP16] 6326 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6327 asm, ".2s", ".2s", 6328 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6329 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6330 asm, ".4s", ".4s", 6331 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6332 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6333 asm, ".2d", ".2d", 6334 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6335} 6336 6337let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6338class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6339 RegisterOperand inreg, RegisterOperand outreg, 6340 string asm, string outkind, string inkind, 6341 list<dag> pattern> 6342 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6343 "{\t$Rd" # outkind # ", $Rn" # inkind # 6344 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6345 Sched<[WriteVq]> { 6346 bits<5> Rd; 6347 bits<5> Rn; 6348 let Inst{31} = 0; 6349 let Inst{30} = Q; 6350 let Inst{29} = U; 6351 let Inst{28-24} = 0b01110; 6352 let Inst{23-22} = size; 6353 let Inst{21-17} = 0b10000; 6354 let Inst{16-12} = opcode; 6355 let Inst{11-10} = 0b10; 6356 let Inst{9-5} = Rn; 6357 let Inst{4-0} = Rd; 6358} 6359 6360let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6361class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6362 RegisterOperand inreg, RegisterOperand outreg, 6363 string asm, string outkind, string inkind, 6364 list<dag> pattern> 6365 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6366 "{\t$Rd" # outkind # ", $Rn" # inkind # 6367 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6368 Sched<[WriteVq]> { 6369 bits<5> Rd; 6370 bits<5> Rn; 6371 let Inst{31} = 0; 6372 let Inst{30} = Q; 6373 let Inst{29} = U; 6374 let Inst{28-24} = 0b01110; 6375 let Inst{23-22} = size; 6376 let Inst{21-17} = 0b10000; 6377 let Inst{16-12} = opcode; 6378 let Inst{11-10} = 0b10; 6379 let Inst{9-5} = Rn; 6380 let Inst{4-0} = Rd; 6381} 6382 6383multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6384 SDPatternOperator OpNode> { 6385 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6386 asm, ".8b", ".8h", 6387 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6388 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6389 asm#"2", ".16b", ".8h", []>; 6390 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6391 asm, ".4h", ".4s", 6392 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6393 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6394 asm#"2", ".8h", ".4s", []>; 6395 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6396 asm, ".2s", ".2d", 6397 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6398 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6399 asm#"2", ".4s", ".2d", []>; 6400 6401 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6402 (!cast<Instruction>(NAME # "v16i8") 6403 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6404 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6405 (!cast<Instruction>(NAME # "v8i16") 6406 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6407 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6408 (!cast<Instruction>(NAME # "v4i32") 6409 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6410} 6411 6412class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6413 bits<5> opcode, RegisterOperand regtype, string asm, 6414 string kind, string zero, ValueType dty, 6415 ValueType sty, SDNode OpNode> 6416 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6417 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6418 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6419 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6420 Sched<[!if(Q, WriteVq, WriteVd)]> { 6421 bits<5> Rd; 6422 bits<5> Rn; 6423 let Inst{31} = 0; 6424 let Inst{30} = Q; 6425 let Inst{29} = U; 6426 let Inst{28-24} = 0b01110; 6427 let Inst{23-22} = size; 6428 let Inst{21} = 0b1; 6429 let Inst{20-19} = size2; 6430 let Inst{18-17} = 0b00; 6431 let Inst{16-12} = opcode; 6432 let Inst{11-10} = 0b10; 6433 let Inst{9-5} = Rn; 6434 let Inst{4-0} = Rd; 6435} 6436 6437// Comparisons support all element sizes, except 1xD. 6438multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6439 SDNode OpNode> { 6440 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6441 asm, ".8b", "0", 6442 v8i8, v8i8, OpNode>; 6443 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6444 asm, ".16b", "0", 6445 v16i8, v16i8, OpNode>; 6446 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6447 asm, ".4h", "0", 6448 v4i16, v4i16, OpNode>; 6449 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6450 asm, ".8h", "0", 6451 v8i16, v8i16, OpNode>; 6452 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6453 asm, ".2s", "0", 6454 v2i32, v2i32, OpNode>; 6455 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6456 asm, ".4s", "0", 6457 v4i32, v4i32, OpNode>; 6458 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6459 asm, ".2d", "0", 6460 v2i64, v2i64, OpNode>; 6461} 6462 6463// FP Comparisons support only S and D element sizes (and H for v8.2a). 6464multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6465 string asm, SDNode OpNode> { 6466 6467 let mayRaiseFPException = 1, Uses = [FPCR] in { 6468 let Predicates = [HasNEON, HasFullFP16] in { 6469 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6470 asm, ".4h", "0.0", 6471 v4i16, v4f16, OpNode>; 6472 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6473 asm, ".8h", "0.0", 6474 v8i16, v8f16, OpNode>; 6475 } // Predicates = [HasNEON, HasFullFP16] 6476 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6477 asm, ".2s", "0.0", 6478 v2i32, v2f32, OpNode>; 6479 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6480 asm, ".4s", "0.0", 6481 v4i32, v4f32, OpNode>; 6482 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6483 asm, ".2d", "0.0", 6484 v2i64, v2f64, OpNode>; 6485 } 6486 6487 let Predicates = [HasNEON, HasFullFP16] in { 6488 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6489 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6490 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6491 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6492 } 6493 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6494 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6495 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6496 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6497 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6498 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6499 let Predicates = [HasNEON, HasFullFP16] in { 6500 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6501 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6502 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6503 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6504 } 6505 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6506 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6507 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6508 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6509 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6510 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6511} 6512 6513let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6514class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6515 RegisterOperand outtype, RegisterOperand intype, 6516 string asm, string VdTy, string VnTy, 6517 list<dag> pattern> 6518 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6519 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6520 Sched<[WriteVq]> { 6521 bits<5> Rd; 6522 bits<5> Rn; 6523 let Inst{31} = 0; 6524 let Inst{30} = Q; 6525 let Inst{29} = U; 6526 let Inst{28-24} = 0b01110; 6527 let Inst{23-22} = size; 6528 let Inst{21-17} = 0b10000; 6529 let Inst{16-12} = opcode; 6530 let Inst{11-10} = 0b10; 6531 let Inst{9-5} = Rn; 6532 let Inst{4-0} = Rd; 6533} 6534 6535let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6536class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6537 RegisterOperand outtype, RegisterOperand intype, 6538 string asm, string VdTy, string VnTy, 6539 list<dag> pattern> 6540 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6541 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6542 Sched<[WriteVq]> { 6543 bits<5> Rd; 6544 bits<5> Rn; 6545 let Inst{31} = 0; 6546 let Inst{30} = Q; 6547 let Inst{29} = U; 6548 let Inst{28-24} = 0b01110; 6549 let Inst{23-22} = size; 6550 let Inst{21-17} = 0b10000; 6551 let Inst{16-12} = opcode; 6552 let Inst{11-10} = 0b10; 6553 let Inst{9-5} = Rn; 6554 let Inst{4-0} = Rd; 6555} 6556 6557multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6558 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6559 asm, ".4s", ".4h", []>; 6560 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6561 asm#"2", ".4s", ".8h", []>; 6562 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6563 asm, ".2d", ".2s", []>; 6564 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6565 asm#"2", ".2d", ".4s", []>; 6566} 6567 6568multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6569 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6570 asm, ".4h", ".4s", []>; 6571 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6572 asm#"2", ".8h", ".4s", []>; 6573 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6574 asm, ".2s", ".2d", []>; 6575 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6576 asm#"2", ".4s", ".2d", []>; 6577} 6578 6579multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6580 Intrinsic OpNode> { 6581 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6582 asm, ".2s", ".2d", 6583 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6584 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6585 asm#"2", ".4s", ".2d", []>; 6586 6587 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6588 (!cast<Instruction>(NAME # "v4f32") 6589 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6590} 6591 6592//---------------------------------------------------------------------------- 6593// AdvSIMD three register different-size vector instructions. 6594//---------------------------------------------------------------------------- 6595 6596let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6597class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6598 RegisterOperand outtype, RegisterOperand intype1, 6599 RegisterOperand intype2, string asm, 6600 string outkind, string inkind1, string inkind2, 6601 list<dag> pattern> 6602 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6603 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6604 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6605 Sched<[WriteVq]> { 6606 bits<5> Rd; 6607 bits<5> Rn; 6608 bits<5> Rm; 6609 let Inst{31} = 0; 6610 let Inst{30} = size{0}; 6611 let Inst{29} = U; 6612 let Inst{28-24} = 0b01110; 6613 let Inst{23-22} = size{2-1}; 6614 let Inst{21} = 1; 6615 let Inst{20-16} = Rm; 6616 let Inst{15-12} = opcode; 6617 let Inst{11-10} = 0b00; 6618 let Inst{9-5} = Rn; 6619 let Inst{4-0} = Rd; 6620} 6621 6622let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6623class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6624 RegisterOperand outtype, RegisterOperand intype1, 6625 RegisterOperand intype2, string asm, 6626 string outkind, string inkind1, string inkind2, 6627 list<dag> pattern> 6628 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6629 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6630 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6631 Sched<[WriteVq]> { 6632 bits<5> Rd; 6633 bits<5> Rn; 6634 bits<5> Rm; 6635 let Inst{31} = 0; 6636 let Inst{30} = size{0}; 6637 let Inst{29} = U; 6638 let Inst{28-24} = 0b01110; 6639 let Inst{23-22} = size{2-1}; 6640 let Inst{21} = 1; 6641 let Inst{20-16} = Rm; 6642 let Inst{15-12} = opcode; 6643 let Inst{11-10} = 0b00; 6644 let Inst{9-5} = Rn; 6645 let Inst{4-0} = Rd; 6646} 6647 6648// FIXME: TableGen doesn't know how to deal with expanded types that also 6649// change the element count (in this case, placing the results in 6650// the high elements of the result register rather than the low 6651// elements). Until that's fixed, we can't code-gen those. 6652multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6653 Intrinsic IntOp> { 6654 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6655 V64, V128, V128, 6656 asm, ".8b", ".8h", ".8h", 6657 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6658 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6659 V128, V128, V128, 6660 asm#"2", ".16b", ".8h", ".8h", 6661 []>; 6662 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6663 V64, V128, V128, 6664 asm, ".4h", ".4s", ".4s", 6665 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6666 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6667 V128, V128, V128, 6668 asm#"2", ".8h", ".4s", ".4s", 6669 []>; 6670 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6671 V64, V128, V128, 6672 asm, ".2s", ".2d", ".2d", 6673 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6674 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6675 V128, V128, V128, 6676 asm#"2", ".4s", ".2d", ".2d", 6677 []>; 6678 6679 6680 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6681 // a version attached to an instruction. 6682 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6683 (v8i16 V128:$Rm))), 6684 (!cast<Instruction>(NAME # "v8i16_v16i8") 6685 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6686 V128:$Rn, V128:$Rm)>; 6687 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6688 (v4i32 V128:$Rm))), 6689 (!cast<Instruction>(NAME # "v4i32_v8i16") 6690 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6691 V128:$Rn, V128:$Rm)>; 6692 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6693 (v2i64 V128:$Rm))), 6694 (!cast<Instruction>(NAME # "v2i64_v4i32") 6695 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6696 V128:$Rn, V128:$Rm)>; 6697} 6698 6699multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6700 SDPatternOperator OpNode> { 6701 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6702 V128, V64, V64, 6703 asm, ".8h", ".8b", ".8b", 6704 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6705 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6706 V128, V128, V128, 6707 asm#"2", ".8h", ".16b", ".16b", []>; 6708 let Predicates = [HasAES] in { 6709 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6710 V128, V64, V64, 6711 asm, ".1q", ".1d", ".1d", 6712 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>; 6713 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6714 V128, V128, V128, 6715 asm#"2", ".1q", ".2d", ".2d", 6716 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)), 6717 (extract_high_v2i64 (v2i64 V128:$Rm))))]>; 6718 } 6719 6720 def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6721 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6722 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6723} 6724 6725multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6726 SDPatternOperator OpNode> { 6727 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6728 V128, V64, V64, 6729 asm, ".4s", ".4h", ".4h", 6730 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6731 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6732 V128, V128, V128, 6733 asm#"2", ".4s", ".8h", ".8h", 6734 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6735 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6736 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6737 V128, V64, V64, 6738 asm, ".2d", ".2s", ".2s", 6739 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6740 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6741 V128, V128, V128, 6742 asm#"2", ".2d", ".4s", ".4s", 6743 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6744 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6745} 6746 6747multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6748 SDPatternOperator OpNode = null_frag> { 6749 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6750 V128, V64, V64, 6751 asm, ".8h", ".8b", ".8b", 6752 [(set (v8i16 V128:$Rd), 6753 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6754 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6755 V128, V128, V128, 6756 asm#"2", ".8h", ".16b", ".16b", 6757 [(set (v8i16 V128:$Rd), 6758 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6759 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 6760 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6761 V128, V64, V64, 6762 asm, ".4s", ".4h", ".4h", 6763 [(set (v4i32 V128:$Rd), 6764 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6765 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6766 V128, V128, V128, 6767 asm#"2", ".4s", ".8h", ".8h", 6768 [(set (v4i32 V128:$Rd), 6769 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6770 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6771 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6772 V128, V64, V64, 6773 asm, ".2d", ".2s", ".2s", 6774 [(set (v2i64 V128:$Rd), 6775 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6776 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6777 V128, V128, V128, 6778 asm#"2", ".2d", ".4s", ".4s", 6779 [(set (v2i64 V128:$Rd), 6780 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6781 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6782} 6783 6784multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6785 string asm, 6786 SDPatternOperator OpNode> { 6787 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6788 V128, V64, V64, 6789 asm, ".8h", ".8b", ".8b", 6790 [(set (v8i16 V128:$dst), 6791 (add (v8i16 V128:$Rd), 6792 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6793 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6794 V128, V128, V128, 6795 asm#"2", ".8h", ".16b", ".16b", 6796 [(set (v8i16 V128:$dst), 6797 (add (v8i16 V128:$Rd), 6798 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6799 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 6800 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6801 V128, V64, V64, 6802 asm, ".4s", ".4h", ".4h", 6803 [(set (v4i32 V128:$dst), 6804 (add (v4i32 V128:$Rd), 6805 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6806 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6807 V128, V128, V128, 6808 asm#"2", ".4s", ".8h", ".8h", 6809 [(set (v4i32 V128:$dst), 6810 (add (v4i32 V128:$Rd), 6811 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6812 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 6813 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6814 V128, V64, V64, 6815 asm, ".2d", ".2s", ".2s", 6816 [(set (v2i64 V128:$dst), 6817 (add (v2i64 V128:$Rd), 6818 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6819 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6820 V128, V128, V128, 6821 asm#"2", ".2d", ".4s", ".4s", 6822 [(set (v2i64 V128:$dst), 6823 (add (v2i64 V128:$Rd), 6824 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6825 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 6826} 6827 6828multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6829 SDPatternOperator OpNode = null_frag> { 6830 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6831 V128, V64, V64, 6832 asm, ".8h", ".8b", ".8b", 6833 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6834 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6835 V128, V128, V128, 6836 asm#"2", ".8h", ".16b", ".16b", 6837 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6838 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6839 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6840 V128, V64, V64, 6841 asm, ".4s", ".4h", ".4h", 6842 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6843 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6844 V128, V128, V128, 6845 asm#"2", ".4s", ".8h", ".8h", 6846 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6847 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6848 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6849 V128, V64, V64, 6850 asm, ".2d", ".2s", ".2s", 6851 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6852 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6853 V128, V128, V128, 6854 asm#"2", ".2d", ".4s", ".4s", 6855 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6856 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6857} 6858 6859multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6860 string asm, 6861 SDPatternOperator OpNode> { 6862 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6863 V128, V64, V64, 6864 asm, ".8h", ".8b", ".8b", 6865 [(set (v8i16 V128:$dst), 6866 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6867 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6868 V128, V128, V128, 6869 asm#"2", ".8h", ".16b", ".16b", 6870 [(set (v8i16 V128:$dst), 6871 (OpNode (v8i16 V128:$Rd), 6872 (extract_high_v16i8 (v16i8 V128:$Rn)), 6873 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6874 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6875 V128, V64, V64, 6876 asm, ".4s", ".4h", ".4h", 6877 [(set (v4i32 V128:$dst), 6878 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6879 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6880 V128, V128, V128, 6881 asm#"2", ".4s", ".8h", ".8h", 6882 [(set (v4i32 V128:$dst), 6883 (OpNode (v4i32 V128:$Rd), 6884 (extract_high_v8i16 (v8i16 V128:$Rn)), 6885 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6886 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6887 V128, V64, V64, 6888 asm, ".2d", ".2s", ".2s", 6889 [(set (v2i64 V128:$dst), 6890 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6891 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6892 V128, V128, V128, 6893 asm#"2", ".2d", ".4s", ".4s", 6894 [(set (v2i64 V128:$dst), 6895 (OpNode (v2i64 V128:$Rd), 6896 (extract_high_v4i32 (v4i32 V128:$Rn)), 6897 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6898} 6899 6900multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6901 SDPatternOperator Accum> { 6902 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6903 V128, V64, V64, 6904 asm, ".4s", ".4h", ".4h", 6905 [(set (v4i32 V128:$dst), 6906 (Accum (v4i32 V128:$Rd), 6907 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6908 (v4i16 V64:$Rm)))))]>; 6909 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6910 V128, V128, V128, 6911 asm#"2", ".4s", ".8h", ".8h", 6912 [(set (v4i32 V128:$dst), 6913 (Accum (v4i32 V128:$Rd), 6914 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 6915 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6916 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6917 V128, V64, V64, 6918 asm, ".2d", ".2s", ".2s", 6919 [(set (v2i64 V128:$dst), 6920 (Accum (v2i64 V128:$Rd), 6921 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6922 (v2i32 V64:$Rm)))))]>; 6923 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6924 V128, V128, V128, 6925 asm#"2", ".2d", ".4s", ".4s", 6926 [(set (v2i64 V128:$dst), 6927 (Accum (v2i64 V128:$Rd), 6928 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 6929 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6930} 6931 6932multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6933 SDPatternOperator OpNode> { 6934 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6935 V128, V128, V64, 6936 asm, ".8h", ".8h", ".8b", 6937 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6938 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6939 V128, V128, V128, 6940 asm#"2", ".8h", ".8h", ".16b", 6941 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6942 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 6943 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6944 V128, V128, V64, 6945 asm, ".4s", ".4s", ".4h", 6946 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6947 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6948 V128, V128, V128, 6949 asm#"2", ".4s", ".4s", ".8h", 6950 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6951 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6952 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6953 V128, V128, V64, 6954 asm, ".2d", ".2d", ".2s", 6955 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6956 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6957 V128, V128, V128, 6958 asm#"2", ".2d", ".2d", ".4s", 6959 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6960 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6961} 6962 6963//---------------------------------------------------------------------------- 6964// AdvSIMD bitwise extract from vector 6965//---------------------------------------------------------------------------- 6966 6967class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6968 string asm, string kind> 6969 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6970 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6971 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6972 [(set (vty regtype:$Rd), 6973 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6974 Sched<[!if(size, WriteVq, WriteVd)]> { 6975 bits<5> Rd; 6976 bits<5> Rn; 6977 bits<5> Rm; 6978 bits<4> imm; 6979 let Inst{31} = 0; 6980 let Inst{30} = size; 6981 let Inst{29-21} = 0b101110000; 6982 let Inst{20-16} = Rm; 6983 let Inst{15} = 0; 6984 let Inst{14-11} = imm; 6985 let Inst{10} = 0; 6986 let Inst{9-5} = Rn; 6987 let Inst{4-0} = Rd; 6988} 6989 6990 6991multiclass SIMDBitwiseExtract<string asm> { 6992 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6993 let imm{3} = 0; 6994 } 6995 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6996} 6997 6998//---------------------------------------------------------------------------- 6999// AdvSIMD zip vector 7000//---------------------------------------------------------------------------- 7001 7002class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 7003 string asm, string kind, SDNode OpNode, ValueType valty> 7004 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7005 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 7006 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 7007 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 7008 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 7009 bits<5> Rd; 7010 bits<5> Rn; 7011 bits<5> Rm; 7012 let Inst{31} = 0; 7013 let Inst{30} = size{0}; 7014 let Inst{29-24} = 0b001110; 7015 let Inst{23-22} = size{2-1}; 7016 let Inst{21} = 0; 7017 let Inst{20-16} = Rm; 7018 let Inst{15} = 0; 7019 let Inst{14-12} = opc; 7020 let Inst{11-10} = 0b10; 7021 let Inst{9-5} = Rn; 7022 let Inst{4-0} = Rd; 7023} 7024 7025multiclass SIMDZipVector<bits<3>opc, string asm, 7026 SDNode OpNode> { 7027 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 7028 asm, ".8b", OpNode, v8i8>; 7029 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 7030 asm, ".16b", OpNode, v16i8>; 7031 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 7032 asm, ".4h", OpNode, v4i16>; 7033 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 7034 asm, ".8h", OpNode, v8i16>; 7035 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 7036 asm, ".2s", OpNode, v2i32>; 7037 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 7038 asm, ".4s", OpNode, v4i32>; 7039 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 7040 asm, ".2d", OpNode, v2i64>; 7041 7042 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 7043 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7044 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)), 7045 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7046 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 7047 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7048 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)), 7049 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7050 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 7051 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 7052 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 7053 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 7054 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 7055 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 7056} 7057 7058//---------------------------------------------------------------------------- 7059// AdvSIMD three register scalar instructions 7060//---------------------------------------------------------------------------- 7061 7062let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7063class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 7064 RegisterClass regtype, string asm, 7065 list<dag> pattern> 7066 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7067 "\t$Rd, $Rn, $Rm", "", pattern>, 7068 Sched<[WriteVd]> { 7069 bits<5> Rd; 7070 bits<5> Rn; 7071 bits<5> Rm; 7072 let Inst{31-30} = 0b01; 7073 let Inst{29} = U; 7074 let Inst{28-24} = 0b11110; 7075 let Inst{23-21} = size; 7076 let Inst{20-16} = Rm; 7077 let Inst{15-11} = opcode; 7078 let Inst{10} = 1; 7079 let Inst{9-5} = Rn; 7080 let Inst{4-0} = Rd; 7081} 7082 7083let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7084class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 7085 dag oops, dag iops, string asm, 7086 list<dag> pattern> 7087 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 7088 Sched<[WriteVd]> { 7089 bits<5> Rd; 7090 bits<5> Rn; 7091 bits<5> Rm; 7092 let Inst{31-30} = 0b01; 7093 let Inst{29} = U; 7094 let Inst{28-24} = 0b11110; 7095 let Inst{23-22} = size; 7096 let Inst{21} = R; 7097 let Inst{20-16} = Rm; 7098 let Inst{15-11} = opcode; 7099 let Inst{10} = 1; 7100 let Inst{9-5} = Rn; 7101 let Inst{4-0} = Rd; 7102} 7103 7104multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 7105 SDPatternOperator OpNode> { 7106 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7107 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7108} 7109 7110multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 7111 SDPatternOperator OpNode> { 7112 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7113 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7114 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 7115 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7116 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 7117 7118 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 7119 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 7120 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 7121 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 7122} 7123 7124multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 7125 SDPatternOperator OpNode> { 7126 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 7127 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7128 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7129} 7130 7131multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 7132 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 7133 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 7134 asm, []>; 7135 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 7136 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 7137 asm, []>; 7138} 7139 7140multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 7141 SDPatternOperator OpNode = null_frag, 7142 Predicate pred = HasNEON> { 7143 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7144 let Predicates = [pred] in { 7145 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7146 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7147 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7148 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7149 } 7150 let Predicates = [pred, HasFullFP16] in { 7151 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7152 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 7153 } 7154 } 7155 7156 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7157 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7158} 7159 7160multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 7161 SDPatternOperator OpNode = null_frag> { 7162 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7163 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7164 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7165 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7166 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 7167 let Predicates = [HasNEON, HasFullFP16] in { 7168 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7169 []>; 7170 } // Predicates = [HasNEON, HasFullFP16] 7171 } 7172 7173 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7174 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7175} 7176 7177class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 7178 dag oops, dag iops, string asm, string cstr, list<dag> pat> 7179 : I<oops, iops, asm, 7180 "\t$Rd, $Rn, $Rm", cstr, pat>, 7181 Sched<[WriteVd]> { 7182 bits<5> Rd; 7183 bits<5> Rn; 7184 bits<5> Rm; 7185 let Inst{31-30} = 0b01; 7186 let Inst{29} = U; 7187 let Inst{28-24} = 0b11110; 7188 let Inst{23-22} = size; 7189 let Inst{21} = 1; 7190 let Inst{20-16} = Rm; 7191 let Inst{15-11} = opcode; 7192 let Inst{10} = 0; 7193 let Inst{9-5} = Rn; 7194 let Inst{4-0} = Rd; 7195} 7196 7197let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7198multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 7199 SDPatternOperator OpNode = null_frag> { 7200 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7201 (outs FPR32:$Rd), 7202 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7203 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7204 (outs FPR64:$Rd), 7205 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7206 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7207} 7208 7209let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7210multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7211 SDPatternOperator OpNode = null_frag> { 7212 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7213 (outs FPR32:$dst), 7214 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7215 asm, "$Rd = $dst", []>; 7216 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7217 (outs FPR64:$dst), 7218 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7219 asm, "$Rd = $dst", 7220 [(set (i64 FPR64:$dst), 7221 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7222} 7223 7224//---------------------------------------------------------------------------- 7225// AdvSIMD two register scalar instructions 7226//---------------------------------------------------------------------------- 7227 7228let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7229class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7230 RegisterClass regtype, RegisterClass regtype2, 7231 string asm, list<dag> pat> 7232 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7233 "\t$Rd, $Rn", "", pat>, 7234 Sched<[WriteVd]> { 7235 bits<5> Rd; 7236 bits<5> Rn; 7237 let Inst{31-30} = 0b01; 7238 let Inst{29} = U; 7239 let Inst{28-24} = 0b11110; 7240 let Inst{23-22} = size; 7241 let Inst{21} = 0b1; 7242 let Inst{20-19} = size2; 7243 let Inst{18-17} = 0b00; 7244 let Inst{16-12} = opcode; 7245 let Inst{11-10} = 0b10; 7246 let Inst{9-5} = Rn; 7247 let Inst{4-0} = Rd; 7248} 7249 7250let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7251class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7252 RegisterClass regtype, RegisterClass regtype2, 7253 string asm, list<dag> pat> 7254 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7255 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7256 Sched<[WriteVd]> { 7257 bits<5> Rd; 7258 bits<5> Rn; 7259 let Inst{31-30} = 0b01; 7260 let Inst{29} = U; 7261 let Inst{28-24} = 0b11110; 7262 let Inst{23-22} = size; 7263 let Inst{21-17} = 0b10000; 7264 let Inst{16-12} = opcode; 7265 let Inst{11-10} = 0b10; 7266 let Inst{9-5} = Rn; 7267 let Inst{4-0} = Rd; 7268} 7269 7270 7271let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7272class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7273 RegisterClass regtype, string asm, string zero> 7274 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7275 "\t$Rd, $Rn, #" # zero, "", []>, 7276 Sched<[WriteVd]> { 7277 bits<5> Rd; 7278 bits<5> Rn; 7279 let Inst{31-30} = 0b01; 7280 let Inst{29} = U; 7281 let Inst{28-24} = 0b11110; 7282 let Inst{23-22} = size; 7283 let Inst{21} = 0b1; 7284 let Inst{20-19} = size2; 7285 let Inst{18-17} = 0b00; 7286 let Inst{16-12} = opcode; 7287 let Inst{11-10} = 0b10; 7288 let Inst{9-5} = Rn; 7289 let Inst{4-0} = Rd; 7290} 7291 7292let mayRaiseFPException = 1, Uses = [FPCR] in 7293class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7294 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7295 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7296 Sched<[WriteVd]> { 7297 bits<5> Rd; 7298 bits<5> Rn; 7299 let Inst{31-17} = 0b011111100110000; 7300 let Inst{16-12} = opcode; 7301 let Inst{11-10} = 0b10; 7302 let Inst{9-5} = Rn; 7303 let Inst{4-0} = Rd; 7304} 7305 7306multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7307 SDPatternOperator OpNode> { 7308 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7309 7310 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7311 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7312} 7313 7314multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7315 SDPatternOperator OpNode> { 7316 let mayRaiseFPException = 1, Uses = [FPCR] in { 7317 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7318 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7319 let Predicates = [HasNEON, HasFullFP16] in { 7320 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7321 } 7322 } 7323 7324 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7325 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7326 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7327 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7328 let Predicates = [HasNEON, HasFullFP16] in { 7329 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7330 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7331 } 7332 7333 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7334 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7335} 7336 7337multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7338 SDPatternOperator OpNode = null_frag, 7339 list<Predicate> preds = []> { 7340 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7341 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7342 7343 let Predicates = preds in { 7344 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7345 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7346 } 7347} 7348 7349let mayRaiseFPException = 1, Uses = [FPCR] in 7350multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7351 Predicate pred = HasNEON> { 7352 let Predicates = [pred] in { 7353 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7354 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7355 } 7356 let Predicates = [pred, HasFullFP16] in { 7357 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7358 } 7359} 7360 7361let mayRaiseFPException = 1, Uses = [FPCR] in 7362multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7363 SDPatternOperator OpNode> { 7364 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7365 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7366 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7367 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7368 let Predicates = [HasNEON, HasFullFP16] in { 7369 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7370 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7371 } 7372} 7373 7374multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7375 SDPatternOperator OpNode = null_frag> { 7376 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7377 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7378 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7379 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7380 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7381 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7382 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7383 } 7384 7385 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7386 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7387} 7388 7389multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7390 Intrinsic OpNode> { 7391 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7392 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7393 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7394 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7395 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7396 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7397 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7398 } 7399 7400 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7401 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7402} 7403 7404 7405 7406let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7407multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7408 SDPatternOperator OpNode = null_frag> { 7409 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7410 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>; 7411 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7412 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7413} 7414 7415//---------------------------------------------------------------------------- 7416// AdvSIMD scalar pairwise instructions 7417//---------------------------------------------------------------------------- 7418 7419let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7420class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7421 RegisterOperand regtype, RegisterOperand vectype, 7422 string asm, string kind> 7423 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7424 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7425 Sched<[WriteVd]> { 7426 bits<5> Rd; 7427 bits<5> Rn; 7428 let Inst{31-30} = 0b01; 7429 let Inst{29} = U; 7430 let Inst{28-24} = 0b11110; 7431 let Inst{23-22} = size; 7432 let Inst{21-17} = 0b11000; 7433 let Inst{16-12} = opcode; 7434 let Inst{11-10} = 0b10; 7435 let Inst{9-5} = Rn; 7436 let Inst{4-0} = Rd; 7437} 7438 7439multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7440 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7441 asm, ".2d">; 7442} 7443 7444let mayRaiseFPException = 1, Uses = [FPCR] in 7445multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7446 let Predicates = [HasNEON, HasFullFP16] in { 7447 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7448 asm, ".2h">; 7449 } 7450 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7451 asm, ".2s">; 7452 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7453 asm, ".2d">; 7454} 7455 7456//---------------------------------------------------------------------------- 7457// AdvSIMD across lanes instructions 7458//---------------------------------------------------------------------------- 7459 7460let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7461class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7462 RegisterClass regtype, RegisterOperand vectype, 7463 string asm, string kind, list<dag> pattern> 7464 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7465 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7466 Sched<[!if(Q, WriteVq, WriteVd)]> { 7467 bits<5> Rd; 7468 bits<5> Rn; 7469 let Inst{31} = 0; 7470 let Inst{30} = Q; 7471 let Inst{29} = U; 7472 let Inst{28-24} = 0b01110; 7473 let Inst{23-22} = size; 7474 let Inst{21-17} = 0b11000; 7475 let Inst{16-12} = opcode; 7476 let Inst{11-10} = 0b10; 7477 let Inst{9-5} = Rn; 7478 let Inst{4-0} = Rd; 7479} 7480 7481multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7482 string asm> { 7483 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7484 asm, ".8b", []>; 7485 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7486 asm, ".16b", []>; 7487 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7488 asm, ".4h", []>; 7489 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7490 asm, ".8h", []>; 7491 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7492 asm, ".4s", []>; 7493} 7494 7495multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7496 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7497 asm, ".8b", []>; 7498 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7499 asm, ".16b", []>; 7500 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7501 asm, ".4h", []>; 7502 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7503 asm, ".8h", []>; 7504 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7505 asm, ".4s", []>; 7506} 7507 7508let mayRaiseFPException = 1, Uses = [FPCR] in 7509multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7510 SDPatternOperator intOp> { 7511 let Predicates = [HasNEON, HasFullFP16] in { 7512 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7513 asm, ".4h", 7514 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7515 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7516 asm, ".8h", 7517 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7518 } // Predicates = [HasNEON, HasFullFP16] 7519 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7520 asm, ".4s", 7521 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7522} 7523 7524//---------------------------------------------------------------------------- 7525// AdvSIMD INS/DUP instructions 7526//---------------------------------------------------------------------------- 7527 7528// FIXME: There has got to be a better way to factor these. ugh. 7529 7530class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7531 string operands, string constraints, list<dag> pattern> 7532 : I<outs, ins, asm, operands, constraints, pattern>, 7533 Sched<[!if(Q, WriteVq, WriteVd)]> { 7534 bits<5> Rd; 7535 bits<5> Rn; 7536 let Inst{31} = 0; 7537 let Inst{30} = Q; 7538 let Inst{29} = op; 7539 let Inst{28-21} = 0b01110000; 7540 let Inst{15} = 0; 7541 let Inst{10} = 1; 7542 let Inst{9-5} = Rn; 7543 let Inst{4-0} = Rd; 7544} 7545 7546class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7547 RegisterOperand vecreg, RegisterClass regtype> 7548 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7549 "{\t$Rd" # size # ", $Rn" # 7550 "|" # size # "\t$Rd, $Rn}", "", 7551 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7552 let Inst{20-16} = imm5; 7553 let Inst{14-11} = 0b0001; 7554} 7555 7556class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7557 ValueType vectype, ValueType insreg, 7558 RegisterOperand vecreg, Operand idxtype, 7559 SDNode OpNode> 7560 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7561 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7562 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7563 [(set (vectype vecreg:$Rd), 7564 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7565 let Inst{14-11} = 0b0000; 7566} 7567 7568class SIMDDup64FromElement 7569 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7570 VectorIndexD, AArch64duplane64> { 7571 bits<1> idx; 7572 let Inst{20} = idx; 7573 let Inst{19-16} = 0b1000; 7574} 7575 7576class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7577 RegisterOperand vecreg> 7578 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7579 VectorIndexS, AArch64duplane32> { 7580 bits<2> idx; 7581 let Inst{20-19} = idx; 7582 let Inst{18-16} = 0b100; 7583} 7584 7585class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7586 RegisterOperand vecreg> 7587 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7588 VectorIndexH, AArch64duplane16> { 7589 bits<3> idx; 7590 let Inst{20-18} = idx; 7591 let Inst{17-16} = 0b10; 7592} 7593 7594class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7595 RegisterOperand vecreg> 7596 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7597 VectorIndexB, AArch64duplane8> { 7598 bits<4> idx; 7599 let Inst{20-17} = idx; 7600 let Inst{16} = 1; 7601} 7602 7603class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7604 Operand idxtype, string asm, list<dag> pattern> 7605 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7606 "{\t$Rd, $Rn" # size # "$idx" # 7607 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7608 let Inst{14-11} = imm4; 7609} 7610 7611class SIMDSMov<bit Q, string size, RegisterClass regtype, 7612 Operand idxtype> 7613 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7614class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7615 Operand idxtype> 7616 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7617 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7618 7619class SIMDMovAlias<string asm, string size, Instruction inst, 7620 RegisterClass regtype, Operand idxtype> 7621 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7622 "|" # size # "\t$dst, $src$idx}", 7623 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7624 7625multiclass SMov { 7626 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7627 // streaming mode. 7628 let Predicates = [HasNEONorSME] in { 7629 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7630 let Inst{20-16} = 0b00001; 7631 } 7632 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7633 let Inst{20-16} = 0b00001; 7634 } 7635 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7636 let Inst{20-16} = 0b00010; 7637 } 7638 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7639 let Inst{20-16} = 0b00010; 7640 } 7641 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7642 let Inst{20-16} = 0b00100; 7643 } 7644 } 7645 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7646 bits<4> idx; 7647 let Inst{20-17} = idx; 7648 let Inst{16} = 1; 7649 } 7650 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7651 bits<4> idx; 7652 let Inst{20-17} = idx; 7653 let Inst{16} = 1; 7654 } 7655 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7656 bits<3> idx; 7657 let Inst{20-18} = idx; 7658 let Inst{17-16} = 0b10; 7659 } 7660 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7661 bits<3> idx; 7662 let Inst{20-18} = idx; 7663 let Inst{17-16} = 0b10; 7664 } 7665 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7666 bits<2> idx; 7667 let Inst{20-19} = idx; 7668 let Inst{18-16} = 0b100; 7669 } 7670} 7671 7672multiclass UMov { 7673 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7674 // streaming mode. 7675 let Predicates = [HasNEONorSME] in { 7676 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7677 let Inst{20-16} = 0b00001; 7678 } 7679 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7680 let Inst{20-16} = 0b00010; 7681 } 7682 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7683 let Inst{20-16} = 0b00100; 7684 } 7685 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7686 let Inst{20-16} = 0b01000; 7687 } 7688 def : SIMDMovAlias<"mov", ".s", 7689 !cast<Instruction>(NAME # vi32_idx0), 7690 GPR32, VectorIndex0>; 7691 def : SIMDMovAlias<"mov", ".d", 7692 !cast<Instruction>(NAME # vi64_idx0), 7693 GPR64, VectorIndex0>; 7694 } 7695 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7696 bits<4> idx; 7697 let Inst{20-17} = idx; 7698 let Inst{16} = 1; 7699 } 7700 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7701 bits<3> idx; 7702 let Inst{20-18} = idx; 7703 let Inst{17-16} = 0b10; 7704 } 7705 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7706 bits<2> idx; 7707 let Inst{20-19} = idx; 7708 let Inst{18-16} = 0b100; 7709 } 7710 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7711 bits<1> idx; 7712 let Inst{20} = idx; 7713 let Inst{19-16} = 0b1000; 7714 } 7715 def : SIMDMovAlias<"mov", ".s", 7716 !cast<Instruction>(NAME#"vi32"), 7717 GPR32, VectorIndexS>; 7718 def : SIMDMovAlias<"mov", ".d", 7719 !cast<Instruction>(NAME#"vi64"), 7720 GPR64, VectorIndexD>; 7721} 7722 7723class SIMDInsFromMain<string size, ValueType vectype, 7724 RegisterClass regtype, Operand idxtype> 7725 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7726 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7727 "{\t$Rd" # size # "$idx, $Rn" # 7728 "|" # size # "\t$Rd$idx, $Rn}", 7729 "$Rd = $dst", 7730 [(set V128:$dst, 7731 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7732 let Inst{14-11} = 0b0011; 7733} 7734 7735class SIMDInsFromElement<string size, ValueType vectype, 7736 ValueType elttype, Operand idxtype> 7737 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7738 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7739 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7740 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7741 "$Rd = $dst", 7742 [(set V128:$dst, 7743 (vector_insert 7744 (vectype V128:$Rd), 7745 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7746 idxtype:$idx))]>; 7747 7748class SIMDInsMainMovAlias<string size, Instruction inst, 7749 RegisterClass regtype, Operand idxtype> 7750 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7751 "|" # size #"\t$dst$idx, $src}", 7752 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7753class SIMDInsElementMovAlias<string size, Instruction inst, 7754 Operand idxtype> 7755 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7756 # "|" # size #"\t$dst$idx, $src$idx2}", 7757 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7758 7759 7760multiclass SIMDIns { 7761 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7762 bits<4> idx; 7763 let Inst{20-17} = idx; 7764 let Inst{16} = 1; 7765 } 7766 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7767 bits<3> idx; 7768 let Inst{20-18} = idx; 7769 let Inst{17-16} = 0b10; 7770 } 7771 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7772 bits<2> idx; 7773 let Inst{20-19} = idx; 7774 let Inst{18-16} = 0b100; 7775 } 7776 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7777 bits<1> idx; 7778 let Inst{20} = idx; 7779 let Inst{19-16} = 0b1000; 7780 } 7781 7782 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7783 bits<4> idx; 7784 bits<4> idx2; 7785 let Inst{20-17} = idx; 7786 let Inst{16} = 1; 7787 let Inst{14-11} = idx2; 7788 } 7789 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7790 bits<3> idx; 7791 bits<3> idx2; 7792 let Inst{20-18} = idx; 7793 let Inst{17-16} = 0b10; 7794 let Inst{14-12} = idx2; 7795 let Inst{11} = {?}; 7796 } 7797 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7798 bits<2> idx; 7799 bits<2> idx2; 7800 let Inst{20-19} = idx; 7801 let Inst{18-16} = 0b100; 7802 let Inst{14-13} = idx2; 7803 let Inst{12-11} = {?,?}; 7804 } 7805 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7806 bits<1> idx; 7807 bits<1> idx2; 7808 let Inst{20} = idx; 7809 let Inst{19-16} = 0b1000; 7810 let Inst{14} = idx2; 7811 let Inst{13-11} = {?,?,?}; 7812 } 7813 7814 // For all forms of the INS instruction, the "mov" mnemonic is the 7815 // preferred alias. Why they didn't just call the instruction "mov" in 7816 // the first place is a very good question indeed... 7817 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7818 GPR32, VectorIndexB>; 7819 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7820 GPR32, VectorIndexH>; 7821 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7822 GPR32, VectorIndexS>; 7823 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7824 GPR64, VectorIndexD>; 7825 7826 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7827 VectorIndexB>; 7828 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7829 VectorIndexH>; 7830 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7831 VectorIndexS>; 7832 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7833 VectorIndexD>; 7834} 7835 7836//---------------------------------------------------------------------------- 7837// AdvSIMD TBL/TBX 7838//---------------------------------------------------------------------------- 7839 7840let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7841class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7842 RegisterOperand listtype, string asm, string kind> 7843 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7844 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7845 Sched<[!if(Q, WriteVq, WriteVd)]> { 7846 bits<5> Vd; 7847 bits<5> Vn; 7848 bits<5> Vm; 7849 let Inst{31} = 0; 7850 let Inst{30} = Q; 7851 let Inst{29-21} = 0b001110000; 7852 let Inst{20-16} = Vm; 7853 let Inst{15} = 0; 7854 let Inst{14-13} = len; 7855 let Inst{12} = op; 7856 let Inst{11-10} = 0b00; 7857 let Inst{9-5} = Vn; 7858 let Inst{4-0} = Vd; 7859} 7860 7861let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7862class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7863 RegisterOperand listtype, string asm, string kind> 7864 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7865 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7866 Sched<[!if(Q, WriteVq, WriteVd)]> { 7867 bits<5> Vd; 7868 bits<5> Vn; 7869 bits<5> Vm; 7870 let Inst{31} = 0; 7871 let Inst{30} = Q; 7872 let Inst{29-21} = 0b001110000; 7873 let Inst{20-16} = Vm; 7874 let Inst{15} = 0; 7875 let Inst{14-13} = len; 7876 let Inst{12} = op; 7877 let Inst{11-10} = 0b00; 7878 let Inst{9-5} = Vn; 7879 let Inst{4-0} = Vd; 7880} 7881 7882class SIMDTableLookupAlias<string asm, Instruction inst, 7883 RegisterOperand vectype, RegisterOperand listtype> 7884 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7885 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7886 7887multiclass SIMDTableLookup<bit op, string asm> { 7888 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7889 asm, ".8b">; 7890 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7891 asm, ".8b">; 7892 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7893 asm, ".8b">; 7894 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7895 asm, ".8b">; 7896 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7897 asm, ".16b">; 7898 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7899 asm, ".16b">; 7900 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7901 asm, ".16b">; 7902 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7903 asm, ".16b">; 7904 7905 def : SIMDTableLookupAlias<asm # ".8b", 7906 !cast<Instruction>(NAME#"v8i8One"), 7907 V64, VecListOne128>; 7908 def : SIMDTableLookupAlias<asm # ".8b", 7909 !cast<Instruction>(NAME#"v8i8Two"), 7910 V64, VecListTwo128>; 7911 def : SIMDTableLookupAlias<asm # ".8b", 7912 !cast<Instruction>(NAME#"v8i8Three"), 7913 V64, VecListThree128>; 7914 def : SIMDTableLookupAlias<asm # ".8b", 7915 !cast<Instruction>(NAME#"v8i8Four"), 7916 V64, VecListFour128>; 7917 def : SIMDTableLookupAlias<asm # ".16b", 7918 !cast<Instruction>(NAME#"v16i8One"), 7919 V128, VecListOne128>; 7920 def : SIMDTableLookupAlias<asm # ".16b", 7921 !cast<Instruction>(NAME#"v16i8Two"), 7922 V128, VecListTwo128>; 7923 def : SIMDTableLookupAlias<asm # ".16b", 7924 !cast<Instruction>(NAME#"v16i8Three"), 7925 V128, VecListThree128>; 7926 def : SIMDTableLookupAlias<asm # ".16b", 7927 !cast<Instruction>(NAME#"v16i8Four"), 7928 V128, VecListFour128>; 7929} 7930 7931multiclass SIMDTableLookupTied<bit op, string asm> { 7932 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7933 asm, ".8b">; 7934 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7935 asm, ".8b">; 7936 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7937 asm, ".8b">; 7938 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7939 asm, ".8b">; 7940 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7941 asm, ".16b">; 7942 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7943 asm, ".16b">; 7944 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7945 asm, ".16b">; 7946 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7947 asm, ".16b">; 7948 7949 def : SIMDTableLookupAlias<asm # ".8b", 7950 !cast<Instruction>(NAME#"v8i8One"), 7951 V64, VecListOne128>; 7952 def : SIMDTableLookupAlias<asm # ".8b", 7953 !cast<Instruction>(NAME#"v8i8Two"), 7954 V64, VecListTwo128>; 7955 def : SIMDTableLookupAlias<asm # ".8b", 7956 !cast<Instruction>(NAME#"v8i8Three"), 7957 V64, VecListThree128>; 7958 def : SIMDTableLookupAlias<asm # ".8b", 7959 !cast<Instruction>(NAME#"v8i8Four"), 7960 V64, VecListFour128>; 7961 def : SIMDTableLookupAlias<asm # ".16b", 7962 !cast<Instruction>(NAME#"v16i8One"), 7963 V128, VecListOne128>; 7964 def : SIMDTableLookupAlias<asm # ".16b", 7965 !cast<Instruction>(NAME#"v16i8Two"), 7966 V128, VecListTwo128>; 7967 def : SIMDTableLookupAlias<asm # ".16b", 7968 !cast<Instruction>(NAME#"v16i8Three"), 7969 V128, VecListThree128>; 7970 def : SIMDTableLookupAlias<asm # ".16b", 7971 !cast<Instruction>(NAME#"v16i8Four"), 7972 V128, VecListFour128>; 7973} 7974 7975 7976//---------------------------------------------------------------------------- 7977// AdvSIMD scalar DUP 7978//---------------------------------------------------------------------------- 7979let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7980class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 7981 string asm, string kind, Operand idxtype> 7982 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 7983 "{\t$dst, $src" # kind # "$idx" # 7984 "|\t$dst, $src$idx}", "", []>, 7985 Sched<[WriteVd]> { 7986 bits<5> dst; 7987 bits<5> src; 7988 let Inst{31-21} = 0b01011110000; 7989 let Inst{15-10} = 0b000001; 7990 let Inst{9-5} = src; 7991 let Inst{4-0} = dst; 7992} 7993 7994class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 7995 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7996 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 7997 # "|\t$dst, $src$index}", 7998 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7999 8000 8001multiclass SIMDScalarDUP<string asm> { 8002 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 8003 bits<4> idx; 8004 let Inst{20-17} = idx; 8005 let Inst{16} = 1; 8006 } 8007 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 8008 bits<3> idx; 8009 let Inst{20-18} = idx; 8010 let Inst{17-16} = 0b10; 8011 } 8012 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 8013 bits<2> idx; 8014 let Inst{20-19} = idx; 8015 let Inst{18-16} = 0b100; 8016 } 8017 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 8018 bits<1> idx; 8019 let Inst{20} = idx; 8020 let Inst{19-16} = 0b1000; 8021 } 8022 8023 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 8024 VectorIndexD:$idx)))), 8025 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 8026 8027 // 'DUP' mnemonic aliases. 8028 def : SIMDScalarDUPAlias<"dup", ".b", 8029 !cast<Instruction>(NAME#"i8"), 8030 FPR8, V128, VectorIndexB>; 8031 def : SIMDScalarDUPAlias<"dup", ".h", 8032 !cast<Instruction>(NAME#"i16"), 8033 FPR16, V128, VectorIndexH>; 8034 def : SIMDScalarDUPAlias<"dup", ".s", 8035 !cast<Instruction>(NAME#"i32"), 8036 FPR32, V128, VectorIndexS>; 8037 def : SIMDScalarDUPAlias<"dup", ".d", 8038 !cast<Instruction>(NAME#"i64"), 8039 FPR64, V128, VectorIndexD>; 8040} 8041 8042//---------------------------------------------------------------------------- 8043// AdvSIMD modified immediate instructions 8044//---------------------------------------------------------------------------- 8045 8046class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 8047 string asm, string op_string, 8048 string cstr, list<dag> pattern> 8049 : I<oops, iops, asm, op_string, cstr, pattern>, 8050 Sched<[!if(Q, WriteVq, WriteVd)]> { 8051 bits<5> Rd; 8052 bits<8> imm8; 8053 let Inst{31} = 0; 8054 let Inst{30} = Q; 8055 let Inst{29} = op; 8056 let Inst{28-19} = 0b0111100000; 8057 let Inst{18-16} = imm8{7-5}; 8058 let Inst{11} = op2; 8059 let Inst{10} = 1; 8060 let Inst{9-5} = imm8{4-0}; 8061 let Inst{4-0} = Rd; 8062} 8063 8064class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 8065 Operand immtype, dag opt_shift_iop, 8066 string opt_shift, string asm, string kind, 8067 list<dag> pattern> 8068 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 8069 !con((ins immtype:$imm8), opt_shift_iop), asm, 8070 "{\t$Rd" # kind # ", $imm8" # opt_shift # 8071 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8072 "", pattern> { 8073 let DecoderMethod = "DecodeModImmInstruction"; 8074} 8075 8076class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 8077 Operand immtype, dag opt_shift_iop, 8078 string opt_shift, string asm, string kind, 8079 list<dag> pattern> 8080 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 8081 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 8082 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 8083 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8084 "$Rd = $dst", pattern> { 8085 let DecoderMethod = "DecodeModImmTiedInstruction"; 8086} 8087 8088class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 8089 RegisterOperand vectype, string asm, 8090 string kind, list<dag> pattern> 8091 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8092 (ins logical_vec_shift:$shift), 8093 "$shift", asm, kind, pattern> { 8094 bits<2> shift; 8095 let Inst{15} = b15_b12{1}; 8096 let Inst{14-13} = shift; 8097 let Inst{12} = b15_b12{0}; 8098} 8099 8100class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 8101 RegisterOperand vectype, string asm, 8102 string kind, list<dag> pattern> 8103 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8104 (ins logical_vec_shift:$shift), 8105 "$shift", asm, kind, pattern> { 8106 bits<2> shift; 8107 let Inst{15} = b15_b12{1}; 8108 let Inst{14-13} = shift; 8109 let Inst{12} = b15_b12{0}; 8110} 8111 8112 8113class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 8114 RegisterOperand vectype, string asm, 8115 string kind, list<dag> pattern> 8116 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8117 (ins logical_vec_hw_shift:$shift), 8118 "$shift", asm, kind, pattern> { 8119 bits<2> shift; 8120 let Inst{15} = b15_b12{1}; 8121 let Inst{14} = 0; 8122 let Inst{13} = shift{0}; 8123 let Inst{12} = b15_b12{0}; 8124} 8125 8126class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 8127 RegisterOperand vectype, string asm, 8128 string kind, list<dag> pattern> 8129 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8130 (ins logical_vec_hw_shift:$shift), 8131 "$shift", asm, kind, pattern> { 8132 bits<2> shift; 8133 let Inst{15} = b15_b12{1}; 8134 let Inst{14} = 0; 8135 let Inst{13} = shift{0}; 8136 let Inst{12} = b15_b12{0}; 8137} 8138 8139multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 8140 string asm> { 8141 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 8142 asm, ".4h", []>; 8143 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 8144 asm, ".8h", []>; 8145 8146 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 8147 asm, ".2s", []>; 8148 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 8149 asm, ".4s", []>; 8150} 8151 8152multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 8153 bits<2> w_cmode, string asm, 8154 SDNode OpNode> { 8155 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 8156 asm, ".4h", 8157 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 8158 imm0_255:$imm8, 8159 (i32 imm:$shift)))]>; 8160 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 8161 asm, ".8h", 8162 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 8163 imm0_255:$imm8, 8164 (i32 imm:$shift)))]>; 8165 8166 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 8167 asm, ".2s", 8168 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 8169 imm0_255:$imm8, 8170 (i32 imm:$shift)))]>; 8171 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 8172 asm, ".4s", 8173 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 8174 imm0_255:$imm8, 8175 (i32 imm:$shift)))]>; 8176} 8177 8178class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 8179 RegisterOperand vectype, string asm, 8180 string kind, list<dag> pattern> 8181 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8182 (ins move_vec_shift:$shift), 8183 "$shift", asm, kind, pattern> { 8184 bits<1> shift; 8185 let Inst{15-13} = cmode{3-1}; 8186 let Inst{12} = shift; 8187} 8188 8189class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 8190 RegisterOperand vectype, 8191 Operand imm_type, string asm, 8192 string kind, list<dag> pattern> 8193 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 8194 asm, kind, pattern> { 8195 let Inst{15-12} = cmode; 8196} 8197 8198class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 8199 list<dag> pattern> 8200 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 8201 "\t$Rd, $imm8", "", pattern> { 8202 let Inst{15-12} = cmode; 8203 let DecoderMethod = "DecodeModImmInstruction"; 8204} 8205 8206//---------------------------------------------------------------------------- 8207// AdvSIMD indexed element 8208//---------------------------------------------------------------------------- 8209 8210let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8211class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8212 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8213 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8214 string apple_kind, string dst_kind, string lhs_kind, 8215 string rhs_kind, list<dag> pattern> 8216 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8217 asm, 8218 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8219 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8220 Sched<[WriteVd]> { 8221 bits<5> Rd; 8222 bits<5> Rn; 8223 bits<5> Rm; 8224 8225 let Inst{31} = 0; 8226 let Inst{30} = Q; 8227 let Inst{29} = U; 8228 let Inst{28} = Scalar; 8229 let Inst{27-24} = 0b1111; 8230 let Inst{23-22} = size; 8231 // Bit 21 must be set by the derived class. 8232 let Inst{20-16} = Rm; 8233 let Inst{15-12} = opc; 8234 // Bit 11 must be set by the derived class. 8235 let Inst{10} = 0; 8236 let Inst{9-5} = Rn; 8237 let Inst{4-0} = Rd; 8238} 8239 8240let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8241class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8242 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8243 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8244 string apple_kind, string dst_kind, string lhs_kind, 8245 string rhs_kind, list<dag> pattern> 8246 : I<(outs dst_reg:$dst), 8247 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8248 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8249 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8250 Sched<[WriteVd]> { 8251 bits<5> Rd; 8252 bits<5> Rn; 8253 bits<5> Rm; 8254 8255 let Inst{31} = 0; 8256 let Inst{30} = Q; 8257 let Inst{29} = U; 8258 let Inst{28} = Scalar; 8259 let Inst{27-24} = 0b1111; 8260 let Inst{23-22} = size; 8261 // Bit 21 must be set by the derived class. 8262 let Inst{20-16} = Rm; 8263 let Inst{15-12} = opc; 8264 // Bit 11 must be set by the derived class. 8265 let Inst{10} = 0; 8266 let Inst{9-5} = Rn; 8267 let Inst{4-0} = Rd; 8268} 8269 8270 8271//---------------------------------------------------------------------------- 8272// Armv8.6 BFloat16 Extension 8273//---------------------------------------------------------------------------- 8274let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8275 8276class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8277 string kind2, RegisterOperand RegType, 8278 ValueType AccumType, ValueType InputType> 8279 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8280 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8281 (InputType RegType:$Rn), 8282 (InputType RegType:$Rm)))]> { 8283 let AsmString = !strconcat(asm, 8284 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8285 ", $Rm" # kind2 # "}"); 8286} 8287 8288multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8289 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8290 v2f32, v4bf16>; 8291 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8292 v4f32, v8bf16>; 8293} 8294 8295class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8296 string dst_kind, string lhs_kind, 8297 string rhs_kind, 8298 RegisterOperand RegType, 8299 ValueType AccumType, 8300 ValueType InputType> 8301 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8302 RegType, RegType, V128, VectorIndexS, 8303 asm, "", dst_kind, lhs_kind, rhs_kind, 8304 [(set (AccumType RegType:$dst), 8305 (AccumType (int_aarch64_neon_bfdot 8306 (AccumType RegType:$Rd), 8307 (InputType RegType:$Rn), 8308 (InputType (bitconvert (AccumType 8309 (AArch64duplane32 (v4f32 V128:$Rm), 8310 VectorIndexS:$idx)))))))]> { 8311 8312 bits<2> idx; 8313 let Inst{21} = idx{0}; // L 8314 let Inst{11} = idx{1}; // H 8315} 8316 8317multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8318 8319 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8320 ".2h", V64, v2f32, v4bf16>; 8321 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8322 ".2h", V128, v4f32, v8bf16>; 8323} 8324 8325let mayRaiseFPException = 1, Uses = [FPCR] in 8326class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8327 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8328 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8329 (v8bf16 V128:$Rn), 8330 (v8bf16 V128:$Rm)))]> { 8331 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8332} 8333 8334let mayRaiseFPException = 1, Uses = [FPCR] in 8335class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8336 : I<(outs V128:$dst), 8337 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8338 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8339 [(set (v4f32 V128:$dst), 8340 (v4f32 (OpNode (v4f32 V128:$Rd), 8341 (v8bf16 V128:$Rn), 8342 (v8bf16 8343 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8344 VectorIndexH:$idx)))))]>, 8345 Sched<[WriteVq]> { 8346 bits<5> Rd; 8347 bits<5> Rn; 8348 bits<4> Rm; 8349 bits<3> idx; 8350 8351 let Inst{31} = 0; 8352 let Inst{30} = Q; 8353 let Inst{29-22} = 0b00111111; 8354 let Inst{21-20} = idx{1-0}; 8355 let Inst{19-16} = Rm; 8356 let Inst{15-12} = 0b1111; 8357 let Inst{11} = idx{2}; // H 8358 let Inst{10} = 0; 8359 let Inst{9-5} = Rn; 8360 let Inst{4-0} = Rd; 8361} 8362 8363class SIMDThreeSameVectorBF16MatrixMul<string asm> 8364 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8365 V128, asm, ".4s", 8366 [(set (v4f32 V128:$dst), 8367 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8368 (v8bf16 V128:$Rn), 8369 (v8bf16 V128:$Rm)))]> { 8370 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8371 ", $Rm", ".8h", "}"); 8372} 8373 8374let mayRaiseFPException = 1, Uses = [FPCR] in 8375class SIMD_BFCVTN 8376 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8377 "bfcvtn", ".4h", ".4s", 8378 [(set (v8bf16 V128:$Rd), 8379 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8380 8381let mayRaiseFPException = 1, Uses = [FPCR] in 8382class SIMD_BFCVTN2 8383 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8384 "bfcvtn2", ".8h", ".4s", 8385 [(set (v8bf16 V128:$dst), 8386 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8387 8388let mayRaiseFPException = 1, Uses = [FPCR] in 8389class BF16ToSinglePrecision<string asm> 8390 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8391 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8392 Sched<[WriteFCvt]> { 8393 bits<5> Rd; 8394 bits<5> Rn; 8395 let Inst{31-10} = 0b0001111001100011010000; 8396 let Inst{9-5} = Rn; 8397 let Inst{4-0} = Rd; 8398} 8399} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8400 8401//---------------------------------------------------------------------------- 8402// Armv8.6 Matrix Multiply Extension 8403//---------------------------------------------------------------------------- 8404 8405class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8406 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8407 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8408 (v16i8 V128:$Rn), 8409 (v16i8 V128:$Rm)))]> { 8410 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8411} 8412 8413//---------------------------------------------------------------------------- 8414// ARMv8.2-A Dot Product Instructions (Indexed) 8415class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, bit Mixed, bits<2> size, string asm, 8416 string dst_kind, string lhs_kind, string rhs_kind, 8417 RegisterOperand RegType, 8418 ValueType AccumType, ValueType InputType, 8419 SDPatternOperator OpNode> : 8420 BaseSIMDIndexedTied<Q, U, 0b0, size, {0b111, Mixed}, RegType, RegType, V128, 8421 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8422 [(set (AccumType RegType:$dst), 8423 (AccumType (OpNode (AccumType RegType:$Rd), 8424 (InputType RegType:$Rn), 8425 (InputType (bitconvert (AccumType 8426 (AArch64duplane32 (v4i32 V128:$Rm), 8427 VectorIndexS:$idx)))))))]> { 8428 bits<2> idx; 8429 let Inst{21} = idx{0}; // L 8430 let Inst{11} = idx{1}; // H 8431} 8432 8433multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8434 SDPatternOperator OpNode> { 8435 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, Mixed, size, asm, ".2s", ".8b", ".4b", 8436 V64, v2i32, v8i8, OpNode>; 8437 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, Mixed, size, asm, ".4s", ".16b", ".4b", 8438 V128, v4i32, v16i8, OpNode>; 8439} 8440 8441// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8442let mayRaiseFPException = 1, Uses = [FPCR] in 8443class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 8444 string dst_kind, string lhs_kind, 8445 string rhs_kind, RegisterOperand RegType, 8446 ValueType AccumType, ValueType InputType, 8447 SDPatternOperator OpNode> : 8448 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128_lo, 8449 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8450 [(set (AccumType RegType:$dst), 8451 (AccumType (OpNode (AccumType RegType:$Rd), 8452 (InputType RegType:$Rn), 8453 (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm), 8454 VectorIndexH:$idx)))))]> { 8455 // idx = H:L:M 8456 bits<3> idx; 8457 let Inst{11} = idx{2}; // H 8458 let Inst{21} = idx{1}; // L 8459 let Inst{20} = idx{0}; // M 8460} 8461 8462multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8463 SDPatternOperator OpNode> { 8464 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 8465 V64, v2f32, v4f16, OpNode>; 8466 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 8467 V128, v4f32, v8f16, OpNode>; 8468} 8469 8470multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8471 SDPatternOperator OpNode> { 8472 let mayRaiseFPException = 1, Uses = [FPCR] in { 8473 let Predicates = [HasNEON, HasFullFP16] in { 8474 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8475 V64, V64, 8476 V128_lo, VectorIndexH, 8477 asm, ".4h", ".4h", ".4h", ".h", 8478 [(set (v4f16 V64:$Rd), 8479 (OpNode (v4f16 V64:$Rn), 8480 (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8481 bits<3> idx; 8482 let Inst{11} = idx{2}; 8483 let Inst{21} = idx{1}; 8484 let Inst{20} = idx{0}; 8485 } 8486 8487 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8488 V128, V128, 8489 V128_lo, VectorIndexH, 8490 asm, ".8h", ".8h", ".8h", ".h", 8491 [(set (v8f16 V128:$Rd), 8492 (OpNode (v8f16 V128:$Rn), 8493 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8494 bits<3> idx; 8495 let Inst{11} = idx{2}; 8496 let Inst{21} = idx{1}; 8497 let Inst{20} = idx{0}; 8498 } 8499 } // Predicates = [HasNEON, HasFullFP16] 8500 8501 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8502 V64, V64, 8503 V128, VectorIndexS, 8504 asm, ".2s", ".2s", ".2s", ".s", 8505 [(set (v2f32 V64:$Rd), 8506 (OpNode (v2f32 V64:$Rn), 8507 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> { 8508 bits<2> idx; 8509 let Inst{11} = idx{1}; 8510 let Inst{21} = idx{0}; 8511 } 8512 8513 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8514 V128, V128, 8515 V128, VectorIndexS, 8516 asm, ".4s", ".4s", ".4s", ".s", 8517 [(set (v4f32 V128:$Rd), 8518 (OpNode (v4f32 V128:$Rn), 8519 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8520 bits<2> idx; 8521 let Inst{11} = idx{1}; 8522 let Inst{21} = idx{0}; 8523 } 8524 8525 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8526 V128, V128, 8527 V128, VectorIndexD, 8528 asm, ".2d", ".2d", ".2d", ".d", 8529 [(set (v2f64 V128:$Rd), 8530 (OpNode (v2f64 V128:$Rn), 8531 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8532 bits<1> idx; 8533 let Inst{11} = idx{0}; 8534 let Inst{21} = 0; 8535 } 8536 8537 let Predicates = [HasNEON, HasFullFP16] in { 8538 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8539 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8540 asm, ".h", "", "", ".h", 8541 [(set (f16 FPR16Op:$Rd), 8542 (OpNode (f16 FPR16Op:$Rn), 8543 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8544 VectorIndexH:$idx))))]> { 8545 bits<3> idx; 8546 let Inst{11} = idx{2}; 8547 let Inst{21} = idx{1}; 8548 let Inst{20} = idx{0}; 8549 } 8550 } // Predicates = [HasNEON, HasFullFP16] 8551 8552 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8553 FPR32Op, FPR32Op, V128, VectorIndexS, 8554 asm, ".s", "", "", ".s", 8555 [(set (f32 FPR32Op:$Rd), 8556 (OpNode (f32 FPR32Op:$Rn), 8557 (f32 (vector_extract (v4f32 V128:$Rm), 8558 VectorIndexS:$idx))))]> { 8559 bits<2> idx; 8560 let Inst{11} = idx{1}; 8561 let Inst{21} = idx{0}; 8562 } 8563 8564 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8565 FPR64Op, FPR64Op, V128, VectorIndexD, 8566 asm, ".d", "", "", ".d", 8567 [(set (f64 FPR64Op:$Rd), 8568 (OpNode (f64 FPR64Op:$Rn), 8569 (f64 (vector_extract (v2f64 V128:$Rm), 8570 VectorIndexD:$idx))))]> { 8571 bits<1> idx; 8572 let Inst{11} = idx{0}; 8573 let Inst{21} = 0; 8574 } 8575 } // mayRaiseFPException = 1, Uses = [FPCR] 8576 8577 let Predicates = [HasNEON, HasFullFP16] in { 8578 def : Pat<(f16 (OpNode 8579 (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))), 8580 (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))), 8581 (!cast<Instruction>(NAME # v1i16_indexed) 8582 (EXTRACT_SUBREG V128:$Rn, hsub), V128:$Rm, VectorIndexH:$idx)>; 8583 } 8584 8585 let Predicates = [HasNEON] in { 8586 def : Pat<(f32 (OpNode 8587 (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))), 8588 (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))), 8589 (!cast<Instruction>(NAME # v1i32_indexed) 8590 (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>; 8591 8592 def : Pat<(f64 (OpNode 8593 (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))), 8594 (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))), 8595 (!cast<Instruction>(NAME # v1i64_indexed) 8596 (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>; 8597 } 8598} 8599 8600multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8601 let Predicates = [HasNEON, HasFullFP16] in { 8602 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8603 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8604 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8605 VectorIndexH:$idx))), 8606 (!cast<Instruction>(INST # "v8i16_indexed") 8607 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8608 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8609 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8610 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8611 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8612 8613 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8614 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8615 VectorIndexH:$idx))), 8616 (!cast<Instruction>(INST # "v4i16_indexed") 8617 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8618 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8619 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8620 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8621 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8622 8623 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8624 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8625 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8626 V128_lo:$Rm, VectorIndexH:$idx)>; 8627 } // Predicates = [HasNEON, HasFullFP16] 8628 8629 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8630 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8631 (AArch64duplane32 (v4f32 V128:$Rm), 8632 VectorIndexS:$idx))), 8633 (!cast<Instruction>(INST # v2i32_indexed) 8634 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8635 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8636 (AArch64dup (f32 FPR32Op:$Rm)))), 8637 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8638 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8639 8640 8641 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8642 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8643 (AArch64duplane32 (v4f32 V128:$Rm), 8644 VectorIndexS:$idx))), 8645 (!cast<Instruction>(INST # "v4i32_indexed") 8646 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8647 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8648 (AArch64dup (f32 FPR32Op:$Rm)))), 8649 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8650 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8651 8652 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8653 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8654 (AArch64duplane64 (v2f64 V128:$Rm), 8655 VectorIndexD:$idx))), 8656 (!cast<Instruction>(INST # "v2i64_indexed") 8657 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8658 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8659 (AArch64dup (f64 FPR64Op:$Rm)))), 8660 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8661 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8662 8663 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8664 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8665 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8666 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8667 V128:$Rm, VectorIndexS:$idx)>; 8668 8669 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8670 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8671 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8672 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8673 V128:$Rm, VectorIndexD:$idx)>; 8674} 8675 8676let mayRaiseFPException = 1, Uses = [FPCR] in 8677multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8678 let Predicates = [HasNEON, HasFullFP16] in { 8679 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8680 V128_lo, VectorIndexH, 8681 asm, ".4h", ".4h", ".4h", ".h", []> { 8682 bits<3> idx; 8683 let Inst{11} = idx{2}; 8684 let Inst{21} = idx{1}; 8685 let Inst{20} = idx{0}; 8686 } 8687 8688 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8689 V128, V128, 8690 V128_lo, VectorIndexH, 8691 asm, ".8h", ".8h", ".8h", ".h", []> { 8692 bits<3> idx; 8693 let Inst{11} = idx{2}; 8694 let Inst{21} = idx{1}; 8695 let Inst{20} = idx{0}; 8696 } 8697 } // Predicates = [HasNEON, HasFullFP16] 8698 8699 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8700 V128, VectorIndexS, 8701 asm, ".2s", ".2s", ".2s", ".s", []> { 8702 bits<2> idx; 8703 let Inst{11} = idx{1}; 8704 let Inst{21} = idx{0}; 8705 } 8706 8707 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8708 V128, V128, 8709 V128, VectorIndexS, 8710 asm, ".4s", ".4s", ".4s", ".s", []> { 8711 bits<2> idx; 8712 let Inst{11} = idx{1}; 8713 let Inst{21} = idx{0}; 8714 } 8715 8716 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8717 V128, V128, 8718 V128, VectorIndexD, 8719 asm, ".2d", ".2d", ".2d", ".d", []> { 8720 bits<1> idx; 8721 let Inst{11} = idx{0}; 8722 let Inst{21} = 0; 8723 } 8724 8725 let Predicates = [HasNEON, HasFullFP16] in { 8726 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8727 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8728 asm, ".h", "", "", ".h", []> { 8729 bits<3> idx; 8730 let Inst{11} = idx{2}; 8731 let Inst{21} = idx{1}; 8732 let Inst{20} = idx{0}; 8733 } 8734 } // Predicates = [HasNEON, HasFullFP16] 8735 8736 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8737 FPR32Op, FPR32Op, V128, VectorIndexS, 8738 asm, ".s", "", "", ".s", []> { 8739 bits<2> idx; 8740 let Inst{11} = idx{1}; 8741 let Inst{21} = idx{0}; 8742 } 8743 8744 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 8745 FPR64Op, FPR64Op, V128, VectorIndexD, 8746 asm, ".d", "", "", ".d", []> { 8747 bits<1> idx; 8748 let Inst{11} = idx{0}; 8749 let Inst{21} = 0; 8750 } 8751} 8752 8753multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 8754 SDPatternOperator OpNodeLaneQ> { 8755 8756 def : Pat<(v4i16 (OpNodeLane 8757 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 8758 VectorIndexS32b:$idx)), 8759 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 8760 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 8761 (UImmS1XForm $idx))>; 8762 8763 def : Pat<(v4i16 (OpNodeLaneQ 8764 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 8765 VectorIndexH32b:$idx)), 8766 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 8767 (UImmS1XForm $idx))>; 8768 8769 def : Pat<(v8i16 (OpNodeLane 8770 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 8771 VectorIndexS32b:$idx)), 8772 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 8773 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8774 (UImmS1XForm $idx))>; 8775 8776 def : Pat<(v8i16 (OpNodeLaneQ 8777 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 8778 VectorIndexH32b:$idx)), 8779 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 8780 (UImmS1XForm $idx))>; 8781 8782 def : Pat<(v2i32 (OpNodeLane 8783 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 8784 VectorIndexD32b:$idx)), 8785 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 8786 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 8787 (UImmS1XForm $idx))>; 8788 8789 def : Pat<(v2i32 (OpNodeLaneQ 8790 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 8791 VectorIndexS32b:$idx)), 8792 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 8793 (UImmS1XForm $idx))>; 8794 8795 def : Pat<(v4i32 (OpNodeLane 8796 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 8797 VectorIndexD32b:$idx)), 8798 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 8799 (SUBREG_TO_REG (i32 0), $Rm, dsub), 8800 (UImmS1XForm $idx))>; 8801 8802 def : Pat<(v4i32 (OpNodeLaneQ 8803 (v4i32 V128:$Rn), 8804 (v4i32 V128:$Rm), 8805 VectorIndexS32b:$idx)), 8806 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 8807 (UImmS1XForm $idx))>; 8808 8809} 8810 8811multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 8812 SDPatternOperator OpNode> { 8813 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 8814 V128_lo, VectorIndexH, 8815 asm, ".4h", ".4h", ".4h", ".h", 8816 [(set (v4i16 V64:$Rd), 8817 (OpNode (v4i16 V64:$Rn), 8818 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8819 bits<3> idx; 8820 let Inst{11} = idx{2}; 8821 let Inst{21} = idx{1}; 8822 let Inst{20} = idx{0}; 8823 } 8824 8825 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8826 V128, V128, 8827 V128_lo, VectorIndexH, 8828 asm, ".8h", ".8h", ".8h", ".h", 8829 [(set (v8i16 V128:$Rd), 8830 (OpNode (v8i16 V128:$Rn), 8831 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8832 bits<3> idx; 8833 let Inst{11} = idx{2}; 8834 let Inst{21} = idx{1}; 8835 let Inst{20} = idx{0}; 8836 } 8837 8838 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8839 V64, V64, 8840 V128, VectorIndexS, 8841 asm, ".2s", ".2s", ".2s", ".s", 8842 [(set (v2i32 V64:$Rd), 8843 (OpNode (v2i32 V64:$Rn), 8844 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8845 bits<2> idx; 8846 let Inst{11} = idx{1}; 8847 let Inst{21} = idx{0}; 8848 } 8849 8850 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8851 V128, V128, 8852 V128, VectorIndexS, 8853 asm, ".4s", ".4s", ".4s", ".s", 8854 [(set (v4i32 V128:$Rd), 8855 (OpNode (v4i32 V128:$Rn), 8856 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8857 bits<2> idx; 8858 let Inst{11} = idx{1}; 8859 let Inst{21} = idx{0}; 8860 } 8861 8862 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8863 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8864 asm, ".h", "", "", ".h", []> { 8865 bits<3> idx; 8866 let Inst{11} = idx{2}; 8867 let Inst{21} = idx{1}; 8868 let Inst{20} = idx{0}; 8869 } 8870 8871 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8872 FPR32Op, FPR32Op, V128, VectorIndexS, 8873 asm, ".s", "", "", ".s", 8874 [(set (i32 FPR32Op:$Rd), 8875 (OpNode FPR32Op:$Rn, 8876 (i32 (vector_extract (v4i32 V128:$Rm), 8877 VectorIndexS:$idx))))]> { 8878 bits<2> idx; 8879 let Inst{11} = idx{1}; 8880 let Inst{21} = idx{0}; 8881 } 8882} 8883 8884multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 8885 SDPatternOperator OpNode> { 8886 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8887 V64, V64, 8888 V128_lo, VectorIndexH, 8889 asm, ".4h", ".4h", ".4h", ".h", 8890 [(set (v4i16 V64:$Rd), 8891 (OpNode (v4i16 V64:$Rn), 8892 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8893 bits<3> idx; 8894 let Inst{11} = idx{2}; 8895 let Inst{21} = idx{1}; 8896 let Inst{20} = idx{0}; 8897 } 8898 8899 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8900 V128, V128, 8901 V128_lo, VectorIndexH, 8902 asm, ".8h", ".8h", ".8h", ".h", 8903 [(set (v8i16 V128:$Rd), 8904 (OpNode (v8i16 V128:$Rn), 8905 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8906 bits<3> idx; 8907 let Inst{11} = idx{2}; 8908 let Inst{21} = idx{1}; 8909 let Inst{20} = idx{0}; 8910 } 8911 8912 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8913 V64, V64, 8914 V128, VectorIndexS, 8915 asm, ".2s", ".2s", ".2s", ".s", 8916 [(set (v2i32 V64:$Rd), 8917 (OpNode (v2i32 V64:$Rn), 8918 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8919 bits<2> idx; 8920 let Inst{11} = idx{1}; 8921 let Inst{21} = idx{0}; 8922 } 8923 8924 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8925 V128, V128, 8926 V128, VectorIndexS, 8927 asm, ".4s", ".4s", ".4s", ".s", 8928 [(set (v4i32 V128:$Rd), 8929 (OpNode (v4i32 V128:$Rn), 8930 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8931 bits<2> idx; 8932 let Inst{11} = idx{1}; 8933 let Inst{21} = idx{0}; 8934 } 8935} 8936 8937multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 8938 SDPatternOperator OpNode> { 8939 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 8940 V128_lo, VectorIndexH, 8941 asm, ".4h", ".4h", ".4h", ".h", 8942 [(set (v4i16 V64:$dst), 8943 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 8944 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8945 bits<3> idx; 8946 let Inst{11} = idx{2}; 8947 let Inst{21} = idx{1}; 8948 let Inst{20} = idx{0}; 8949 } 8950 8951 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8952 V128, V128, 8953 V128_lo, VectorIndexH, 8954 asm, ".8h", ".8h", ".8h", ".h", 8955 [(set (v8i16 V128:$dst), 8956 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8957 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8958 bits<3> idx; 8959 let Inst{11} = idx{2}; 8960 let Inst{21} = idx{1}; 8961 let Inst{20} = idx{0}; 8962 } 8963 8964 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8965 V64, V64, 8966 V128, VectorIndexS, 8967 asm, ".2s", ".2s", ".2s", ".s", 8968 [(set (v2i32 V64:$dst), 8969 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8970 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 8971 bits<2> idx; 8972 let Inst{11} = idx{1}; 8973 let Inst{21} = idx{0}; 8974 } 8975 8976 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8977 V128, V128, 8978 V128, VectorIndexS, 8979 asm, ".4s", ".4s", ".4s", ".s", 8980 [(set (v4i32 V128:$dst), 8981 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8982 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8983 bits<2> idx; 8984 let Inst{11} = idx{1}; 8985 let Inst{21} = idx{0}; 8986 } 8987} 8988 8989multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8990 SDPatternOperator OpNode> { 8991 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8992 V128, V64, 8993 V128_lo, VectorIndexH, 8994 asm, ".4s", ".4s", ".4h", ".h", 8995 [(set (v4i32 V128:$Rd), 8996 (OpNode (v4i16 V64:$Rn), 8997 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8998 bits<3> idx; 8999 let Inst{11} = idx{2}; 9000 let Inst{21} = idx{1}; 9001 let Inst{20} = idx{0}; 9002 } 9003 9004 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9005 V128, V128, 9006 V128_lo, VectorIndexH, 9007 asm#"2", ".4s", ".4s", ".8h", ".h", 9008 [(set (v4i32 V128:$Rd), 9009 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9010 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9011 9012 bits<3> idx; 9013 let Inst{11} = idx{2}; 9014 let Inst{21} = idx{1}; 9015 let Inst{20} = idx{0}; 9016 } 9017 9018 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9019 V128, V64, 9020 V128, VectorIndexS, 9021 asm, ".2d", ".2d", ".2s", ".s", 9022 [(set (v2i64 V128:$Rd), 9023 (OpNode (v2i32 V64:$Rn), 9024 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9025 bits<2> idx; 9026 let Inst{11} = idx{1}; 9027 let Inst{21} = idx{0}; 9028 } 9029 9030 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9031 V128, V128, 9032 V128, VectorIndexS, 9033 asm#"2", ".2d", ".2d", ".4s", ".s", 9034 [(set (v2i64 V128:$Rd), 9035 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9036 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9037 bits<2> idx; 9038 let Inst{11} = idx{1}; 9039 let Inst{21} = idx{0}; 9040 } 9041 9042 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9043 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9044 asm, ".h", "", "", ".h", []> { 9045 bits<3> idx; 9046 let Inst{11} = idx{2}; 9047 let Inst{21} = idx{1}; 9048 let Inst{20} = idx{0}; 9049 } 9050 9051 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9052 FPR64Op, FPR32Op, V128, VectorIndexS, 9053 asm, ".s", "", "", ".s", []> { 9054 bits<2> idx; 9055 let Inst{11} = idx{1}; 9056 let Inst{21} = idx{0}; 9057 } 9058} 9059 9060multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 9061 SDPatternOperator Accum> { 9062 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9063 V128, V64, 9064 V128_lo, VectorIndexH, 9065 asm, ".4s", ".4s", ".4h", ".h", 9066 [(set (v4i32 V128:$dst), 9067 (Accum (v4i32 V128:$Rd), 9068 (v4i32 (int_aarch64_neon_sqdmull 9069 (v4i16 V64:$Rn), 9070 (dup_v8i16 (v8i16 V128_lo:$Rm), 9071 VectorIndexH:$idx)))))]> { 9072 bits<3> idx; 9073 let Inst{11} = idx{2}; 9074 let Inst{21} = idx{1}; 9075 let Inst{20} = idx{0}; 9076 } 9077 9078 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9079 V128, V128, 9080 V128_lo, VectorIndexH, 9081 asm#"2", ".4s", ".4s", ".8h", ".h", 9082 [(set (v4i32 V128:$dst), 9083 (Accum (v4i32 V128:$Rd), 9084 (v4i32 (int_aarch64_neon_sqdmull 9085 (extract_high_v8i16 (v8i16 V128:$Rn)), 9086 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 9087 bits<3> idx; 9088 let Inst{11} = idx{2}; 9089 let Inst{21} = idx{1}; 9090 let Inst{20} = idx{0}; 9091 } 9092 9093 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9094 V128, V64, 9095 V128, VectorIndexS, 9096 asm, ".2d", ".2d", ".2s", ".s", 9097 [(set (v2i64 V128:$dst), 9098 (Accum (v2i64 V128:$Rd), 9099 (v2i64 (int_aarch64_neon_sqdmull 9100 (v2i32 V64:$Rn), 9101 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9102 bits<2> idx; 9103 let Inst{11} = idx{1}; 9104 let Inst{21} = idx{0}; 9105 } 9106 9107 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9108 V128, V128, 9109 V128, VectorIndexS, 9110 asm#"2", ".2d", ".2d", ".4s", ".s", 9111 [(set (v2i64 V128:$dst), 9112 (Accum (v2i64 V128:$Rd), 9113 (v2i64 (int_aarch64_neon_sqdmull 9114 (extract_high_v4i32 (v4i32 V128:$Rn)), 9115 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9116 bits<2> idx; 9117 let Inst{11} = idx{1}; 9118 let Inst{21} = idx{0}; 9119 } 9120 9121 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9122 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9123 asm, ".h", "", "", ".h", []> { 9124 bits<3> idx; 9125 let Inst{11} = idx{2}; 9126 let Inst{21} = idx{1}; 9127 let Inst{20} = idx{0}; 9128 } 9129 9130 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9131 (i32 (vector_extract 9132 (v4i32 (int_aarch64_neon_sqdmull 9133 (v4i16 V64:$Rn), 9134 (v4i16 V64:$Rm))), 9135 (i64 0))))), 9136 (!cast<Instruction>(NAME # v1i32_indexed) 9137 FPR32Op:$Rd, 9138 (EXTRACT_SUBREG V64:$Rn, hsub), 9139 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub), 9140 (i64 0))>; 9141 9142 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9143 (i32 (vector_extract 9144 (v4i32 (int_aarch64_neon_sqdmull 9145 (v4i16 V64:$Rn), 9146 (dup_v8i16 (v8i16 V128_lo:$Rm), 9147 VectorIndexH:$idx))), 9148 (i64 0))))), 9149 (!cast<Instruction>(NAME # v1i32_indexed) 9150 FPR32Op:$Rd, 9151 (EXTRACT_SUBREG V64:$Rn, hsub), 9152 V128_lo:$Rm, 9153 VectorIndexH:$idx)>; 9154 9155 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9156 FPR64Op, FPR32Op, V128, VectorIndexS, 9157 asm, ".s", "", "", ".s", 9158 [(set (i64 FPR64Op:$dst), 9159 (Accum (i64 FPR64Op:$Rd), 9160 (i64 (int_aarch64_neon_sqdmulls_scalar 9161 (i32 FPR32Op:$Rn), 9162 (i32 (vector_extract (v4i32 V128:$Rm), 9163 VectorIndexS:$idx))))))]> { 9164 9165 bits<2> idx; 9166 let Inst{11} = idx{1}; 9167 let Inst{21} = idx{0}; 9168 } 9169} 9170 9171multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 9172 SDPatternOperator OpNode> { 9173 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9174 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9175 V128, V64, 9176 V128_lo, VectorIndexH, 9177 asm, ".4s", ".4s", ".4h", ".h", 9178 [(set (v4i32 V128:$Rd), 9179 (OpNode (v4i16 V64:$Rn), 9180 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9181 bits<3> idx; 9182 let Inst{11} = idx{2}; 9183 let Inst{21} = idx{1}; 9184 let Inst{20} = idx{0}; 9185 } 9186 9187 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9188 V128, V128, 9189 V128_lo, VectorIndexH, 9190 asm#"2", ".4s", ".4s", ".8h", ".h", 9191 [(set (v4i32 V128:$Rd), 9192 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9193 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9194 9195 bits<3> idx; 9196 let Inst{11} = idx{2}; 9197 let Inst{21} = idx{1}; 9198 let Inst{20} = idx{0}; 9199 } 9200 9201 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9202 V128, V64, 9203 V128, VectorIndexS, 9204 asm, ".2d", ".2d", ".2s", ".s", 9205 [(set (v2i64 V128:$Rd), 9206 (OpNode (v2i32 V64:$Rn), 9207 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9208 bits<2> idx; 9209 let Inst{11} = idx{1}; 9210 let Inst{21} = idx{0}; 9211 } 9212 9213 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9214 V128, V128, 9215 V128, VectorIndexS, 9216 asm#"2", ".2d", ".2d", ".4s", ".s", 9217 [(set (v2i64 V128:$Rd), 9218 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9219 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9220 bits<2> idx; 9221 let Inst{11} = idx{1}; 9222 let Inst{21} = idx{0}; 9223 } 9224 } 9225} 9226 9227multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 9228 SDPatternOperator OpNode> { 9229 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9230 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9231 V128, V64, 9232 V128_lo, VectorIndexH, 9233 asm, ".4s", ".4s", ".4h", ".h", 9234 [(set (v4i32 V128:$dst), 9235 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 9236 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9237 bits<3> idx; 9238 let Inst{11} = idx{2}; 9239 let Inst{21} = idx{1}; 9240 let Inst{20} = idx{0}; 9241 } 9242 9243 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9244 V128, V128, 9245 V128_lo, VectorIndexH, 9246 asm#"2", ".4s", ".4s", ".8h", ".h", 9247 [(set (v4i32 V128:$dst), 9248 (OpNode (v4i32 V128:$Rd), 9249 (extract_high_v8i16 (v8i16 V128:$Rn)), 9250 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9251 bits<3> idx; 9252 let Inst{11} = idx{2}; 9253 let Inst{21} = idx{1}; 9254 let Inst{20} = idx{0}; 9255 } 9256 9257 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9258 V128, V64, 9259 V128, VectorIndexS, 9260 asm, ".2d", ".2d", ".2s", ".s", 9261 [(set (v2i64 V128:$dst), 9262 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9263 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9264 bits<2> idx; 9265 let Inst{11} = idx{1}; 9266 let Inst{21} = idx{0}; 9267 } 9268 9269 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9270 V128, V128, 9271 V128, VectorIndexS, 9272 asm#"2", ".2d", ".2d", ".4s", ".s", 9273 [(set (v2i64 V128:$dst), 9274 (OpNode (v2i64 V128:$Rd), 9275 (extract_high_v4i32 (v4i32 V128:$Rn)), 9276 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9277 bits<2> idx; 9278 let Inst{11} = idx{1}; 9279 let Inst{21} = idx{0}; 9280 } 9281 } 9282} 9283 9284//---------------------------------------------------------------------------- 9285// AdvSIMD scalar shift by immediate 9286//---------------------------------------------------------------------------- 9287 9288let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9289class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9290 RegisterClass regtype1, RegisterClass regtype2, 9291 Operand immtype, string asm, list<dag> pattern> 9292 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9293 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9294 Sched<[WriteVd]> { 9295 bits<5> Rd; 9296 bits<5> Rn; 9297 bits<7> imm; 9298 let Inst{31-30} = 0b01; 9299 let Inst{29} = U; 9300 let Inst{28-23} = 0b111110; 9301 let Inst{22-16} = fixed_imm; 9302 let Inst{15-11} = opc; 9303 let Inst{10} = 1; 9304 let Inst{9-5} = Rn; 9305 let Inst{4-0} = Rd; 9306} 9307 9308let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9309class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9310 RegisterClass regtype1, RegisterClass regtype2, 9311 Operand immtype, string asm, list<dag> pattern> 9312 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9313 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9314 Sched<[WriteVd]> { 9315 bits<5> Rd; 9316 bits<5> Rn; 9317 bits<7> imm; 9318 let Inst{31-30} = 0b01; 9319 let Inst{29} = U; 9320 let Inst{28-23} = 0b111110; 9321 let Inst{22-16} = fixed_imm; 9322 let Inst{15-11} = opc; 9323 let Inst{10} = 1; 9324 let Inst{9-5} = Rn; 9325 let Inst{4-0} = Rd; 9326} 9327 9328 9329multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9330 let Predicates = [HasNEON, HasFullFP16] in { 9331 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9332 FPR16, FPR16, vecshiftR16, asm, []> { 9333 let Inst{19-16} = imm{3-0}; 9334 } 9335 } // Predicates = [HasNEON, HasFullFP16] 9336 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9337 FPR32, FPR32, vecshiftR32, asm, []> { 9338 let Inst{20-16} = imm{4-0}; 9339 } 9340 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9341 FPR64, FPR64, vecshiftR64, asm, []> { 9342 let Inst{21-16} = imm{5-0}; 9343 } 9344} 9345 9346multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9347 SDPatternOperator OpNode> { 9348 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9349 FPR64, FPR64, vecshiftR64, asm, 9350 [(set (i64 FPR64:$Rd), 9351 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9352 let Inst{21-16} = imm{5-0}; 9353 } 9354 9355 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9356 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9357} 9358 9359multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9360 SDPatternOperator OpNode = null_frag> { 9361 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9362 FPR64, FPR64, vecshiftR64, asm, 9363 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9364 (i32 vecshiftR64:$imm)))]> { 9365 let Inst{21-16} = imm{5-0}; 9366 } 9367 9368 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9369 (i32 vecshiftR64:$imm))), 9370 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9371 vecshiftR64:$imm)>; 9372} 9373 9374multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9375 SDPatternOperator OpNode> { 9376 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9377 FPR64, FPR64, vecshiftL64, asm, 9378 [(set (i64 FPR64:$Rd), 9379 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9380 let Inst{21-16} = imm{5-0}; 9381 } 9382 9383 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9384 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9385} 9386 9387let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9388multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9389 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9390 FPR64, FPR64, vecshiftL64, asm, []> { 9391 let Inst{21-16} = imm{5-0}; 9392 } 9393} 9394 9395let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9396multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9397 SDPatternOperator OpNode = null_frag> { 9398 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9399 FPR8, FPR16, vecshiftR8, asm, []> { 9400 let Inst{18-16} = imm{2-0}; 9401 } 9402 9403 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9404 FPR16, FPR32, vecshiftR16, asm, []> { 9405 let Inst{19-16} = imm{3-0}; 9406 } 9407 9408 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9409 FPR32, FPR64, vecshiftR32, asm, 9410 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9411 let Inst{20-16} = imm{4-0}; 9412 } 9413} 9414 9415multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9416 SDPatternOperator OpNode> { 9417 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9418 FPR8, FPR8, vecshiftL8, asm, []> { 9419 let Inst{18-16} = imm{2-0}; 9420 } 9421 9422 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9423 FPR16, FPR16, vecshiftL16, asm, []> { 9424 let Inst{19-16} = imm{3-0}; 9425 } 9426 9427 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9428 FPR32, FPR32, vecshiftL32, asm, 9429 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9430 let Inst{20-16} = imm{4-0}; 9431 } 9432 9433 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9434 FPR64, FPR64, vecshiftL64, asm, 9435 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9436 let Inst{21-16} = imm{5-0}; 9437 } 9438 9439 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9440 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9441} 9442 9443multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9444 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9445 FPR8, FPR8, vecshiftR8, asm, []> { 9446 let Inst{18-16} = imm{2-0}; 9447 } 9448 9449 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9450 FPR16, FPR16, vecshiftR16, asm, []> { 9451 let Inst{19-16} = imm{3-0}; 9452 } 9453 9454 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9455 FPR32, FPR32, vecshiftR32, asm, []> { 9456 let Inst{20-16} = imm{4-0}; 9457 } 9458 9459 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9460 FPR64, FPR64, vecshiftR64, asm, []> { 9461 let Inst{21-16} = imm{5-0}; 9462 } 9463} 9464 9465//---------------------------------------------------------------------------- 9466// AdvSIMD vector x indexed element 9467//---------------------------------------------------------------------------- 9468 9469let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9470class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9471 RegisterOperand dst_reg, RegisterOperand src_reg, 9472 Operand immtype, 9473 string asm, string dst_kind, string src_kind, 9474 list<dag> pattern> 9475 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9476 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9477 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9478 Sched<[!if(Q, WriteVq, WriteVd)]> { 9479 bits<5> Rd; 9480 bits<5> Rn; 9481 let Inst{31} = 0; 9482 let Inst{30} = Q; 9483 let Inst{29} = U; 9484 let Inst{28-23} = 0b011110; 9485 let Inst{22-16} = fixed_imm; 9486 let Inst{15-11} = opc; 9487 let Inst{10} = 1; 9488 let Inst{9-5} = Rn; 9489 let Inst{4-0} = Rd; 9490} 9491 9492let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9493class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9494 RegisterOperand vectype1, RegisterOperand vectype2, 9495 Operand immtype, 9496 string asm, string dst_kind, string src_kind, 9497 list<dag> pattern> 9498 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9499 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9500 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9501 Sched<[!if(Q, WriteVq, WriteVd)]> { 9502 bits<5> Rd; 9503 bits<5> Rn; 9504 let Inst{31} = 0; 9505 let Inst{30} = Q; 9506 let Inst{29} = U; 9507 let Inst{28-23} = 0b011110; 9508 let Inst{22-16} = fixed_imm; 9509 let Inst{15-11} = opc; 9510 let Inst{10} = 1; 9511 let Inst{9-5} = Rn; 9512 let Inst{4-0} = Rd; 9513} 9514 9515multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9516 Intrinsic OpNode> { 9517 let Predicates = [HasNEON, HasFullFP16] in { 9518 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9519 V64, V64, vecshiftR16, 9520 asm, ".4h", ".4h", 9521 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9522 bits<4> imm; 9523 let Inst{19-16} = imm; 9524 } 9525 9526 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9527 V128, V128, vecshiftR16, 9528 asm, ".8h", ".8h", 9529 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9530 bits<4> imm; 9531 let Inst{19-16} = imm; 9532 } 9533 } // Predicates = [HasNEON, HasFullFP16] 9534 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9535 V64, V64, vecshiftR32, 9536 asm, ".2s", ".2s", 9537 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9538 bits<5> imm; 9539 let Inst{20-16} = imm; 9540 } 9541 9542 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9543 V128, V128, vecshiftR32, 9544 asm, ".4s", ".4s", 9545 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9546 bits<5> imm; 9547 let Inst{20-16} = imm; 9548 } 9549 9550 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9551 V128, V128, vecshiftR64, 9552 asm, ".2d", ".2d", 9553 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9554 bits<6> imm; 9555 let Inst{21-16} = imm; 9556 } 9557} 9558 9559multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9560 Intrinsic OpNode> { 9561 let Predicates = [HasNEON, HasFullFP16] in { 9562 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9563 V64, V64, vecshiftR16, 9564 asm, ".4h", ".4h", 9565 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9566 bits<4> imm; 9567 let Inst{19-16} = imm; 9568 } 9569 9570 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9571 V128, V128, vecshiftR16, 9572 asm, ".8h", ".8h", 9573 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9574 bits<4> imm; 9575 let Inst{19-16} = imm; 9576 } 9577 } // Predicates = [HasNEON, HasFullFP16] 9578 9579 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9580 V64, V64, vecshiftR32, 9581 asm, ".2s", ".2s", 9582 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9583 bits<5> imm; 9584 let Inst{20-16} = imm; 9585 } 9586 9587 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9588 V128, V128, vecshiftR32, 9589 asm, ".4s", ".4s", 9590 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9591 bits<5> imm; 9592 let Inst{20-16} = imm; 9593 } 9594 9595 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9596 V128, V128, vecshiftR64, 9597 asm, ".2d", ".2d", 9598 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9599 bits<6> imm; 9600 let Inst{21-16} = imm; 9601 } 9602} 9603 9604multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9605 SDPatternOperator OpNode> { 9606 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9607 V64, V128, vecshiftR16Narrow, 9608 asm, ".8b", ".8h", 9609 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9610 bits<3> imm; 9611 let Inst{18-16} = imm; 9612 } 9613 9614 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9615 V128, V128, vecshiftR16Narrow, 9616 asm#"2", ".16b", ".8h", []> { 9617 bits<3> imm; 9618 let Inst{18-16} = imm; 9619 let hasSideEffects = 0; 9620 } 9621 9622 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9623 V64, V128, vecshiftR32Narrow, 9624 asm, ".4h", ".4s", 9625 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9626 bits<4> imm; 9627 let Inst{19-16} = imm; 9628 } 9629 9630 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9631 V128, V128, vecshiftR32Narrow, 9632 asm#"2", ".8h", ".4s", []> { 9633 bits<4> imm; 9634 let Inst{19-16} = imm; 9635 let hasSideEffects = 0; 9636 } 9637 9638 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9639 V64, V128, vecshiftR64Narrow, 9640 asm, ".2s", ".2d", 9641 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9642 bits<5> imm; 9643 let Inst{20-16} = imm; 9644 } 9645 9646 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9647 V128, V128, vecshiftR64Narrow, 9648 asm#"2", ".4s", ".2d", []> { 9649 bits<5> imm; 9650 let Inst{20-16} = imm; 9651 let hasSideEffects = 0; 9652 } 9653 9654 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9655 // themselves, so put them here instead. 9656 9657 // Patterns involving what's effectively an insert high and a normal 9658 // intrinsic, represented by CONCAT_VECTORS. 9659 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9660 vecshiftR16Narrow:$imm)), 9661 (!cast<Instruction>(NAME # "v16i8_shift") 9662 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9663 V128:$Rn, vecshiftR16Narrow:$imm)>; 9664 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9665 vecshiftR32Narrow:$imm)), 9666 (!cast<Instruction>(NAME # "v8i16_shift") 9667 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9668 V128:$Rn, vecshiftR32Narrow:$imm)>; 9669 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9670 vecshiftR64Narrow:$imm)), 9671 (!cast<Instruction>(NAME # "v4i32_shift") 9672 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9673 V128:$Rn, vecshiftR64Narrow:$imm)>; 9674} 9675 9676multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9677 SDPatternOperator OpNode> { 9678 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9679 V64, V64, vecshiftL8, 9680 asm, ".8b", ".8b", 9681 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9682 (i32 vecshiftL8:$imm)))]> { 9683 bits<3> imm; 9684 let Inst{18-16} = imm; 9685 } 9686 9687 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9688 V128, V128, vecshiftL8, 9689 asm, ".16b", ".16b", 9690 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9691 (i32 vecshiftL8:$imm)))]> { 9692 bits<3> imm; 9693 let Inst{18-16} = imm; 9694 } 9695 9696 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9697 V64, V64, vecshiftL16, 9698 asm, ".4h", ".4h", 9699 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9700 (i32 vecshiftL16:$imm)))]> { 9701 bits<4> imm; 9702 let Inst{19-16} = imm; 9703 } 9704 9705 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9706 V128, V128, vecshiftL16, 9707 asm, ".8h", ".8h", 9708 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9709 (i32 vecshiftL16:$imm)))]> { 9710 bits<4> imm; 9711 let Inst{19-16} = imm; 9712 } 9713 9714 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9715 V64, V64, vecshiftL32, 9716 asm, ".2s", ".2s", 9717 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9718 (i32 vecshiftL32:$imm)))]> { 9719 bits<5> imm; 9720 let Inst{20-16} = imm; 9721 } 9722 9723 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9724 V128, V128, vecshiftL32, 9725 asm, ".4s", ".4s", 9726 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9727 (i32 vecshiftL32:$imm)))]> { 9728 bits<5> imm; 9729 let Inst{20-16} = imm; 9730 } 9731 9732 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9733 V128, V128, vecshiftL64, 9734 asm, ".2d", ".2d", 9735 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9736 (i32 vecshiftL64:$imm)))]> { 9737 bits<6> imm; 9738 let Inst{21-16} = imm; 9739 } 9740} 9741 9742multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 9743 SDPatternOperator OpNode> { 9744 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9745 V64, V64, vecshiftR8, 9746 asm, ".8b", ".8b", 9747 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9748 (i32 vecshiftR8:$imm)))]> { 9749 bits<3> imm; 9750 let Inst{18-16} = imm; 9751 } 9752 9753 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9754 V128, V128, vecshiftR8, 9755 asm, ".16b", ".16b", 9756 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9757 (i32 vecshiftR8:$imm)))]> { 9758 bits<3> imm; 9759 let Inst{18-16} = imm; 9760 } 9761 9762 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9763 V64, V64, vecshiftR16, 9764 asm, ".4h", ".4h", 9765 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9766 (i32 vecshiftR16:$imm)))]> { 9767 bits<4> imm; 9768 let Inst{19-16} = imm; 9769 } 9770 9771 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9772 V128, V128, vecshiftR16, 9773 asm, ".8h", ".8h", 9774 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9775 (i32 vecshiftR16:$imm)))]> { 9776 bits<4> imm; 9777 let Inst{19-16} = imm; 9778 } 9779 9780 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9781 V64, V64, vecshiftR32, 9782 asm, ".2s", ".2s", 9783 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9784 (i32 vecshiftR32:$imm)))]> { 9785 bits<5> imm; 9786 let Inst{20-16} = imm; 9787 } 9788 9789 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9790 V128, V128, vecshiftR32, 9791 asm, ".4s", ".4s", 9792 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9793 (i32 vecshiftR32:$imm)))]> { 9794 bits<5> imm; 9795 let Inst{20-16} = imm; 9796 } 9797 9798 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9799 V128, V128, vecshiftR64, 9800 asm, ".2d", ".2d", 9801 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 9802 (i32 vecshiftR64:$imm)))]> { 9803 bits<6> imm; 9804 let Inst{21-16} = imm; 9805 } 9806} 9807 9808let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9809multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 9810 SDPatternOperator OpNode = null_frag> { 9811 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9812 V64, V64, vecshiftR8, asm, ".8b", ".8b", 9813 [(set (v8i8 V64:$dst), 9814 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9815 (i32 vecshiftR8:$imm)))]> { 9816 bits<3> imm; 9817 let Inst{18-16} = imm; 9818 } 9819 9820 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9821 V128, V128, vecshiftR8, asm, ".16b", ".16b", 9822 [(set (v16i8 V128:$dst), 9823 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9824 (i32 vecshiftR8:$imm)))]> { 9825 bits<3> imm; 9826 let Inst{18-16} = imm; 9827 } 9828 9829 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9830 V64, V64, vecshiftR16, asm, ".4h", ".4h", 9831 [(set (v4i16 V64:$dst), 9832 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9833 (i32 vecshiftR16:$imm)))]> { 9834 bits<4> imm; 9835 let Inst{19-16} = imm; 9836 } 9837 9838 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9839 V128, V128, vecshiftR16, asm, ".8h", ".8h", 9840 [(set (v8i16 V128:$dst), 9841 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9842 (i32 vecshiftR16:$imm)))]> { 9843 bits<4> imm; 9844 let Inst{19-16} = imm; 9845 } 9846 9847 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9848 V64, V64, vecshiftR32, asm, ".2s", ".2s", 9849 [(set (v2i32 V64:$dst), 9850 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9851 (i32 vecshiftR32:$imm)))]> { 9852 bits<5> imm; 9853 let Inst{20-16} = imm; 9854 } 9855 9856 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9857 V128, V128, vecshiftR32, asm, ".4s", ".4s", 9858 [(set (v4i32 V128:$dst), 9859 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9860 (i32 vecshiftR32:$imm)))]> { 9861 bits<5> imm; 9862 let Inst{20-16} = imm; 9863 } 9864 9865 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9866 V128, V128, vecshiftR64, 9867 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 9868 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9869 (i32 vecshiftR64:$imm)))]> { 9870 bits<6> imm; 9871 let Inst{21-16} = imm; 9872 } 9873} 9874 9875multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 9876 SDPatternOperator OpNode = null_frag> { 9877 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 9878 V64, V64, vecshiftL8, 9879 asm, ".8b", ".8b", 9880 [(set (v8i8 V64:$dst), 9881 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 9882 (i32 vecshiftL8:$imm)))]> { 9883 bits<3> imm; 9884 let Inst{18-16} = imm; 9885 } 9886 9887 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9888 V128, V128, vecshiftL8, 9889 asm, ".16b", ".16b", 9890 [(set (v16i8 V128:$dst), 9891 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 9892 (i32 vecshiftL8:$imm)))]> { 9893 bits<3> imm; 9894 let Inst{18-16} = imm; 9895 } 9896 9897 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 9898 V64, V64, vecshiftL16, 9899 asm, ".4h", ".4h", 9900 [(set (v4i16 V64:$dst), 9901 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 9902 (i32 vecshiftL16:$imm)))]> { 9903 bits<4> imm; 9904 let Inst{19-16} = imm; 9905 } 9906 9907 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9908 V128, V128, vecshiftL16, 9909 asm, ".8h", ".8h", 9910 [(set (v8i16 V128:$dst), 9911 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9912 (i32 vecshiftL16:$imm)))]> { 9913 bits<4> imm; 9914 let Inst{19-16} = imm; 9915 } 9916 9917 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 9918 V64, V64, vecshiftL32, 9919 asm, ".2s", ".2s", 9920 [(set (v2i32 V64:$dst), 9921 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9922 (i32 vecshiftL32:$imm)))]> { 9923 bits<5> imm; 9924 let Inst{20-16} = imm; 9925 } 9926 9927 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9928 V128, V128, vecshiftL32, 9929 asm, ".4s", ".4s", 9930 [(set (v4i32 V128:$dst), 9931 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9932 (i32 vecshiftL32:$imm)))]> { 9933 bits<5> imm; 9934 let Inst{20-16} = imm; 9935 } 9936 9937 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 9938 V128, V128, vecshiftL64, 9939 asm, ".2d", ".2d", 9940 [(set (v2i64 V128:$dst), 9941 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 9942 (i32 vecshiftL64:$imm)))]> { 9943 bits<6> imm; 9944 let Inst{21-16} = imm; 9945 } 9946} 9947 9948multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 9949 SDPatternOperator OpNode> { 9950 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9951 V128, V64, vecshiftL8, asm, ".8h", ".8b", 9952 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 9953 bits<3> imm; 9954 let Inst{18-16} = imm; 9955 } 9956 9957 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9958 V128, V128, vecshiftL8, 9959 asm#"2", ".8h", ".16b", 9960 [(set (v8i16 V128:$Rd), 9961 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 9962 bits<3> imm; 9963 let Inst{18-16} = imm; 9964 } 9965 9966 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9967 V128, V64, vecshiftL16, asm, ".4s", ".4h", 9968 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 9969 bits<4> imm; 9970 let Inst{19-16} = imm; 9971 } 9972 9973 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9974 V128, V128, vecshiftL16, 9975 asm#"2", ".4s", ".8h", 9976 [(set (v4i32 V128:$Rd), 9977 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 9978 9979 bits<4> imm; 9980 let Inst{19-16} = imm; 9981 } 9982 9983 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9984 V128, V64, vecshiftL32, asm, ".2d", ".2s", 9985 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 9986 bits<5> imm; 9987 let Inst{20-16} = imm; 9988 } 9989 9990 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9991 V128, V128, vecshiftL32, 9992 asm#"2", ".2d", ".4s", 9993 [(set (v2i64 V128:$Rd), 9994 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 9995 bits<5> imm; 9996 let Inst{20-16} = imm; 9997 } 9998} 9999 10000 10001//--- 10002// Vector load/store 10003//--- 10004// SIMD ldX/stX no-index memory references don't allow the optional 10005// ", #0" constant and handle post-indexing explicitly, so we use 10006// a more specialized parse method for them. Otherwise, it's the same as 10007// the general GPR64sp handling. 10008 10009class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 10010 string asm, dag oops, dag iops, list<dag> pattern> 10011 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 10012 bits<5> Vt; 10013 bits<5> Rn; 10014 let Inst{31} = 0; 10015 let Inst{30} = Q; 10016 let Inst{29-23} = 0b0011000; 10017 let Inst{22} = L; 10018 let Inst{21-16} = 0b000000; 10019 let Inst{15-12} = opcode; 10020 let Inst{11-10} = size; 10021 let Inst{9-5} = Rn; 10022 let Inst{4-0} = Vt; 10023} 10024 10025class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 10026 string asm, dag oops, dag iops> 10027 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 10028 bits<5> Vt; 10029 bits<5> Rn; 10030 bits<5> Xm; 10031 let Inst{31} = 0; 10032 let Inst{30} = Q; 10033 let Inst{29-23} = 0b0011001; 10034 let Inst{22} = L; 10035 let Inst{21} = 0; 10036 let Inst{20-16} = Xm; 10037 let Inst{15-12} = opcode; 10038 let Inst{11-10} = size; 10039 let Inst{9-5} = Rn; 10040 let Inst{4-0} = Vt; 10041} 10042 10043// The immediate form of AdvSIMD post-indexed addressing is encoded with 10044// register post-index addressing from the zero register. 10045multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 10046 int Offset, int Size> { 10047 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 10048 // "ld1\t$Vt, [$Rn], #16" 10049 // may get mapped to 10050 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 10051 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10052 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10053 GPR64sp:$Rn, 10054 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10055 XZR), 1>; 10056 10057 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 10058 // "ld1.8b\t$Vt, [$Rn], #16" 10059 // may get mapped to 10060 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 10061 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10062 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10063 GPR64sp:$Rn, 10064 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10065 XZR), 0>; 10066 10067 // E.g. "ld1.8b { v0, v1 }, [x1]" 10068 // "ld1\t$Vt, [$Rn]" 10069 // may get mapped to 10070 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 10071 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10072 (!cast<Instruction>(BaseName # Count # "v" # layout) 10073 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10074 GPR64sp:$Rn), 0>; 10075 10076 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 10077 // "ld1\t$Vt, [$Rn], $Xm" 10078 // may get mapped to 10079 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 10080 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10081 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10082 GPR64sp:$Rn, 10083 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10084 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10085} 10086 10087multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 10088 int Offset128, int Offset64, bits<4> opcode> { 10089 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10090 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 10091 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 10092 (ins GPR64sp:$Rn), []>; 10093 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 10094 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 10095 (ins GPR64sp:$Rn), []>; 10096 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 10097 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 10098 (ins GPR64sp:$Rn), []>; 10099 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 10100 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 10101 (ins GPR64sp:$Rn), []>; 10102 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 10103 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 10104 (ins GPR64sp:$Rn), []>; 10105 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 10106 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 10107 (ins GPR64sp:$Rn), []>; 10108 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 10109 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 10110 (ins GPR64sp:$Rn), []>; 10111 10112 10113 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 10114 (outs GPR64sp:$wback, 10115 !cast<RegisterOperand>(veclist # "16b"):$Vt), 10116 (ins GPR64sp:$Rn, 10117 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10118 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 10119 (outs GPR64sp:$wback, 10120 !cast<RegisterOperand>(veclist # "8h"):$Vt), 10121 (ins GPR64sp:$Rn, 10122 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10123 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 10124 (outs GPR64sp:$wback, 10125 !cast<RegisterOperand>(veclist # "4s"):$Vt), 10126 (ins GPR64sp:$Rn, 10127 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10128 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 10129 (outs GPR64sp:$wback, 10130 !cast<RegisterOperand>(veclist # "2d"):$Vt), 10131 (ins GPR64sp:$Rn, 10132 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10133 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 10134 (outs GPR64sp:$wback, 10135 !cast<RegisterOperand>(veclist # "8b"):$Vt), 10136 (ins GPR64sp:$Rn, 10137 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10138 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 10139 (outs GPR64sp:$wback, 10140 !cast<RegisterOperand>(veclist # "4h"):$Vt), 10141 (ins GPR64sp:$Rn, 10142 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10143 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 10144 (outs GPR64sp:$wback, 10145 !cast<RegisterOperand>(veclist # "2s"):$Vt), 10146 (ins GPR64sp:$Rn, 10147 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10148 } 10149 10150 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10151 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10152 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10153 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10154 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10155 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10156 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10157} 10158 10159// Only ld1/st1 has a v1d version. 10160multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 10161 int Offset128, int Offset64, bits<4> opcode> { 10162 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 10163 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 10164 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10165 GPR64sp:$Rn), []>; 10166 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 10167 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10168 GPR64sp:$Rn), []>; 10169 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 10170 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10171 GPR64sp:$Rn), []>; 10172 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 10173 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10174 GPR64sp:$Rn), []>; 10175 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 10176 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10177 GPR64sp:$Rn), []>; 10178 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 10179 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10180 GPR64sp:$Rn), []>; 10181 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 10182 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10183 GPR64sp:$Rn), []>; 10184 10185 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 10186 (outs GPR64sp:$wback), 10187 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10188 GPR64sp:$Rn, 10189 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10190 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 10191 (outs GPR64sp:$wback), 10192 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10193 GPR64sp:$Rn, 10194 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10195 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 10196 (outs GPR64sp:$wback), 10197 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10198 GPR64sp:$Rn, 10199 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10200 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 10201 (outs GPR64sp:$wback), 10202 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10203 GPR64sp:$Rn, 10204 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10205 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 10206 (outs GPR64sp:$wback), 10207 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10208 GPR64sp:$Rn, 10209 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10210 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 10211 (outs GPR64sp:$wback), 10212 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10213 GPR64sp:$Rn, 10214 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10215 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 10216 (outs GPR64sp:$wback), 10217 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10218 GPR64sp:$Rn, 10219 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10220 } 10221 10222 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10223 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10224 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10225 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10226 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10227 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10228 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10229} 10230 10231multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 10232 int Offset128, int Offset64, bits<4> opcode> 10233 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10234 10235 // LD1 instructions have extra "1d" variants. 10236 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10237 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 10238 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10239 (ins GPR64sp:$Rn), []>; 10240 10241 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10242 (outs GPR64sp:$wback, 10243 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10244 (ins GPR64sp:$Rn, 10245 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10246 } 10247 10248 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10249} 10250 10251multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10252 int Offset128, int Offset64, bits<4> opcode> 10253 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10254 10255 // ST1 instructions have extra "1d" variants. 10256 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10257 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10258 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10259 GPR64sp:$Rn), []>; 10260 10261 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10262 (outs GPR64sp:$wback), 10263 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10264 GPR64sp:$Rn, 10265 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10266 } 10267 10268 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10269} 10270 10271multiclass SIMDLd1Multiple<string asm> { 10272 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10273 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10274 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10275 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10276} 10277 10278multiclass SIMDSt1Multiple<string asm> { 10279 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10280 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10281 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10282 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10283} 10284 10285multiclass SIMDLd2Multiple<string asm> { 10286 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10287} 10288 10289multiclass SIMDSt2Multiple<string asm> { 10290 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10291} 10292 10293multiclass SIMDLd3Multiple<string asm> { 10294 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10295} 10296 10297multiclass SIMDSt3Multiple<string asm> { 10298 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10299} 10300 10301multiclass SIMDLd4Multiple<string asm> { 10302 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10303} 10304 10305multiclass SIMDSt4Multiple<string asm> { 10306 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10307} 10308 10309//--- 10310// AdvSIMD Load/store single-element 10311//--- 10312 10313class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10314 string asm, string operands, string cst, 10315 dag oops, dag iops, list<dag> pattern> 10316 : I<oops, iops, asm, operands, cst, pattern> { 10317 bits<5> Vt; 10318 bits<5> Rn; 10319 let Inst{31} = 0; 10320 let Inst{29-24} = 0b001101; 10321 let Inst{22} = L; 10322 let Inst{21} = R; 10323 let Inst{15-13} = opcode; 10324 let Inst{9-5} = Rn; 10325 let Inst{4-0} = Vt; 10326} 10327 10328class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10329 string asm, string operands, string cst, 10330 dag oops, dag iops, list<dag> pattern> 10331 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10332 bits<5> Vt; 10333 bits<5> Rn; 10334 let Inst{31} = 0; 10335 let Inst{29-24} = 0b001101; 10336 let Inst{22} = L; 10337 let Inst{21} = R; 10338 let Inst{15-13} = opcode; 10339 let Inst{9-5} = Rn; 10340 let Inst{4-0} = Vt; 10341} 10342 10343 10344let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10345class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10346 DAGOperand listtype> 10347 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10348 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10349 []> { 10350 let Inst{30} = Q; 10351 let Inst{23} = 0; 10352 let Inst{20-16} = 0b00000; 10353 let Inst{12} = S; 10354 let Inst{11-10} = size; 10355} 10356let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10357class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10358 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10359 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10360 "$Rn = $wback", 10361 (outs GPR64sp:$wback, listtype:$Vt), 10362 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10363 bits<5> Xm; 10364 let Inst{30} = Q; 10365 let Inst{23} = 1; 10366 let Inst{20-16} = Xm; 10367 let Inst{12} = S; 10368 let Inst{11-10} = size; 10369} 10370 10371multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10372 int Offset, int Size> { 10373 // E.g. "ld1r { v0.8b }, [x1], #1" 10374 // "ld1r.8b\t$Vt, [$Rn], #1" 10375 // may get mapped to 10376 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10377 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10378 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10379 GPR64sp:$Rn, 10380 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10381 XZR), 1>; 10382 10383 // E.g. "ld1r.8b { v0 }, [x1], #1" 10384 // "ld1r.8b\t$Vt, [$Rn], #1" 10385 // may get mapped to 10386 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10387 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10388 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10389 GPR64sp:$Rn, 10390 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10391 XZR), 0>; 10392 10393 // E.g. "ld1r.8b { v0 }, [x1]" 10394 // "ld1r.8b\t$Vt, [$Rn]" 10395 // may get mapped to 10396 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10397 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10398 (!cast<Instruction>(BaseName # "v" # layout) 10399 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10400 GPR64sp:$Rn), 0>; 10401 10402 // E.g. "ld1r.8b { v0 }, [x1], x2" 10403 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10404 // may get mapped to 10405 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10406 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10407 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10408 GPR64sp:$Rn, 10409 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10410 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10411} 10412 10413multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10414 int Offset1, int Offset2, int Offset4, int Offset8> { 10415 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10416 !cast<DAGOperand>("VecList" # Count # "8b")>; 10417 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10418 !cast<DAGOperand>("VecList" # Count #"16b")>; 10419 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10420 !cast<DAGOperand>("VecList" # Count #"4h")>; 10421 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10422 !cast<DAGOperand>("VecList" # Count #"8h")>; 10423 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10424 !cast<DAGOperand>("VecList" # Count #"2s")>; 10425 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10426 !cast<DAGOperand>("VecList" # Count #"4s")>; 10427 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10428 !cast<DAGOperand>("VecList" # Count #"1d")>; 10429 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10430 !cast<DAGOperand>("VecList" # Count #"2d")>; 10431 10432 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10433 !cast<DAGOperand>("VecList" # Count # "8b"), 10434 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10435 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10436 !cast<DAGOperand>("VecList" # Count # "16b"), 10437 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10438 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10439 !cast<DAGOperand>("VecList" # Count # "4h"), 10440 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10441 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10442 !cast<DAGOperand>("VecList" # Count # "8h"), 10443 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10444 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10445 !cast<DAGOperand>("VecList" # Count # "2s"), 10446 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10447 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10448 !cast<DAGOperand>("VecList" # Count # "4s"), 10449 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10450 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10451 !cast<DAGOperand>("VecList" # Count # "1d"), 10452 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10453 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10454 !cast<DAGOperand>("VecList" # Count # "2d"), 10455 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10456 10457 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10458 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10459 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10460 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10461 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10462 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10463 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10464 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10465} 10466 10467class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10468 dag oops, dag iops, list<dag> pattern> 10469 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10470 pattern> { 10471 // idx encoded in Q:S:size fields. 10472 bits<4> idx; 10473 let Inst{30} = idx{3}; 10474 let Inst{23} = 0; 10475 let Inst{20-16} = 0b00000; 10476 let Inst{12} = idx{2}; 10477 let Inst{11-10} = idx{1-0}; 10478} 10479class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10480 dag oops, dag iops, list<dag> pattern> 10481 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10482 oops, iops, pattern> { 10483 // idx encoded in Q:S:size fields. 10484 bits<4> idx; 10485 let Inst{30} = idx{3}; 10486 let Inst{23} = 0; 10487 let Inst{20-16} = 0b00000; 10488 let Inst{12} = idx{2}; 10489 let Inst{11-10} = idx{1-0}; 10490} 10491class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10492 dag oops, dag iops> 10493 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10494 "$Rn = $wback", oops, iops, []> { 10495 // idx encoded in Q:S:size fields. 10496 bits<4> idx; 10497 bits<5> Xm; 10498 let Inst{30} = idx{3}; 10499 let Inst{23} = 1; 10500 let Inst{20-16} = Xm; 10501 let Inst{12} = idx{2}; 10502 let Inst{11-10} = idx{1-0}; 10503} 10504class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10505 dag oops, dag iops> 10506 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10507 "$Rn = $wback", oops, iops, []> { 10508 // idx encoded in Q:S:size fields. 10509 bits<4> idx; 10510 bits<5> Xm; 10511 let Inst{30} = idx{3}; 10512 let Inst{23} = 1; 10513 let Inst{20-16} = Xm; 10514 let Inst{12} = idx{2}; 10515 let Inst{11-10} = idx{1-0}; 10516} 10517 10518class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10519 dag oops, dag iops, list<dag> pattern> 10520 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10521 pattern> { 10522 // idx encoded in Q:S:size<1> fields. 10523 bits<3> idx; 10524 let Inst{30} = idx{2}; 10525 let Inst{23} = 0; 10526 let Inst{20-16} = 0b00000; 10527 let Inst{12} = idx{1}; 10528 let Inst{11} = idx{0}; 10529 let Inst{10} = size; 10530} 10531class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10532 dag oops, dag iops, list<dag> pattern> 10533 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10534 oops, iops, pattern> { 10535 // idx encoded in Q:S:size<1> fields. 10536 bits<3> idx; 10537 let Inst{30} = idx{2}; 10538 let Inst{23} = 0; 10539 let Inst{20-16} = 0b00000; 10540 let Inst{12} = idx{1}; 10541 let Inst{11} = idx{0}; 10542 let Inst{10} = size; 10543} 10544 10545class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10546 dag oops, dag iops> 10547 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10548 "$Rn = $wback", oops, iops, []> { 10549 // idx encoded in Q:S:size<1> fields. 10550 bits<3> idx; 10551 bits<5> Xm; 10552 let Inst{30} = idx{2}; 10553 let Inst{23} = 1; 10554 let Inst{20-16} = Xm; 10555 let Inst{12} = idx{1}; 10556 let Inst{11} = idx{0}; 10557 let Inst{10} = size; 10558} 10559class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10560 dag oops, dag iops> 10561 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10562 "$Rn = $wback", oops, iops, []> { 10563 // idx encoded in Q:S:size<1> fields. 10564 bits<3> idx; 10565 bits<5> Xm; 10566 let Inst{30} = idx{2}; 10567 let Inst{23} = 1; 10568 let Inst{20-16} = Xm; 10569 let Inst{12} = idx{1}; 10570 let Inst{11} = idx{0}; 10571 let Inst{10} = size; 10572} 10573class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10574 dag oops, dag iops, list<dag> pattern> 10575 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10576 pattern> { 10577 // idx encoded in Q:S fields. 10578 bits<2> idx; 10579 let Inst{30} = idx{1}; 10580 let Inst{23} = 0; 10581 let Inst{20-16} = 0b00000; 10582 let Inst{12} = idx{0}; 10583 let Inst{11-10} = size; 10584} 10585class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10586 dag oops, dag iops, list<dag> pattern> 10587 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10588 oops, iops, pattern> { 10589 // idx encoded in Q:S fields. 10590 bits<2> idx; 10591 let Inst{30} = idx{1}; 10592 let Inst{23} = 0; 10593 let Inst{20-16} = 0b00000; 10594 let Inst{12} = idx{0}; 10595 let Inst{11-10} = size; 10596} 10597class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10598 string asm, dag oops, dag iops> 10599 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10600 "$Rn = $wback", oops, iops, []> { 10601 // idx encoded in Q:S fields. 10602 bits<2> idx; 10603 bits<5> Xm; 10604 let Inst{30} = idx{1}; 10605 let Inst{23} = 1; 10606 let Inst{20-16} = Xm; 10607 let Inst{12} = idx{0}; 10608 let Inst{11-10} = size; 10609} 10610class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10611 string asm, dag oops, dag iops> 10612 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10613 "$Rn = $wback", oops, iops, []> { 10614 // idx encoded in Q:S fields. 10615 bits<2> idx; 10616 bits<5> Xm; 10617 let Inst{30} = idx{1}; 10618 let Inst{23} = 1; 10619 let Inst{20-16} = Xm; 10620 let Inst{12} = idx{0}; 10621 let Inst{11-10} = size; 10622} 10623class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10624 dag oops, dag iops, list<dag> pattern> 10625 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10626 pattern> { 10627 // idx encoded in Q field. 10628 bits<1> idx; 10629 let Inst{30} = idx; 10630 let Inst{23} = 0; 10631 let Inst{20-16} = 0b00000; 10632 let Inst{12} = 0; 10633 let Inst{11-10} = size; 10634} 10635class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10636 dag oops, dag iops, list<dag> pattern> 10637 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10638 oops, iops, pattern> { 10639 // idx encoded in Q field. 10640 bits<1> idx; 10641 let Inst{30} = idx; 10642 let Inst{23} = 0; 10643 let Inst{20-16} = 0b00000; 10644 let Inst{12} = 0; 10645 let Inst{11-10} = size; 10646} 10647class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10648 string asm, dag oops, dag iops> 10649 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10650 "$Rn = $wback", oops, iops, []> { 10651 // idx encoded in Q field. 10652 bits<1> idx; 10653 bits<5> Xm; 10654 let Inst{30} = idx; 10655 let Inst{23} = 1; 10656 let Inst{20-16} = Xm; 10657 let Inst{12} = 0; 10658 let Inst{11-10} = size; 10659} 10660class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10661 string asm, dag oops, dag iops> 10662 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10663 "$Rn = $wback", oops, iops, []> { 10664 // idx encoded in Q field. 10665 bits<1> idx; 10666 bits<5> Xm; 10667 let Inst{30} = idx; 10668 let Inst{23} = 1; 10669 let Inst{20-16} = Xm; 10670 let Inst{12} = 0; 10671 let Inst{11-10} = size; 10672} 10673 10674let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10675multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10676 RegisterOperand listtype, 10677 RegisterOperand GPR64pi> { 10678 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10679 (outs listtype:$dst), 10680 (ins listtype:$Vt, VectorIndexB:$idx, 10681 GPR64sp:$Rn), []>; 10682 10683 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10684 (outs GPR64sp:$wback, listtype:$dst), 10685 (ins listtype:$Vt, VectorIndexB:$idx, 10686 GPR64sp:$Rn, GPR64pi:$Xm)>; 10687} 10688let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10689multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10690 RegisterOperand listtype, 10691 RegisterOperand GPR64pi> { 10692 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10693 (outs listtype:$dst), 10694 (ins listtype:$Vt, VectorIndexH:$idx, 10695 GPR64sp:$Rn), []>; 10696 10697 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10698 (outs GPR64sp:$wback, listtype:$dst), 10699 (ins listtype:$Vt, VectorIndexH:$idx, 10700 GPR64sp:$Rn, GPR64pi:$Xm)>; 10701} 10702let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10703multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10704 RegisterOperand listtype, 10705 RegisterOperand GPR64pi> { 10706 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10707 (outs listtype:$dst), 10708 (ins listtype:$Vt, VectorIndexS:$idx, 10709 GPR64sp:$Rn), []>; 10710 10711 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10712 (outs GPR64sp:$wback, listtype:$dst), 10713 (ins listtype:$Vt, VectorIndexS:$idx, 10714 GPR64sp:$Rn, GPR64pi:$Xm)>; 10715} 10716let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10717multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10718 RegisterOperand listtype, RegisterOperand GPR64pi> { 10719 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10720 (outs listtype:$dst), 10721 (ins listtype:$Vt, VectorIndexD:$idx, 10722 GPR64sp:$Rn), []>; 10723 10724 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10725 (outs GPR64sp:$wback, listtype:$dst), 10726 (ins listtype:$Vt, VectorIndexD:$idx, 10727 GPR64sp:$Rn, GPR64pi:$Xm)>; 10728} 10729let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10730multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 10731 RegisterOperand listtype, RegisterOperand GPR64pi> { 10732 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 10733 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 10734 GPR64sp:$Rn), []>; 10735 10736 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 10737 (outs GPR64sp:$wback), 10738 (ins listtype:$Vt, VectorIndexB:$idx, 10739 GPR64sp:$Rn, GPR64pi:$Xm)>; 10740} 10741let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10742multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 10743 RegisterOperand listtype, RegisterOperand GPR64pi> { 10744 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 10745 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 10746 GPR64sp:$Rn), []>; 10747 10748 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 10749 (outs GPR64sp:$wback), 10750 (ins listtype:$Vt, VectorIndexH:$idx, 10751 GPR64sp:$Rn, GPR64pi:$Xm)>; 10752} 10753let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10754multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 10755 RegisterOperand listtype, RegisterOperand GPR64pi> { 10756 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 10757 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 10758 GPR64sp:$Rn), []>; 10759 10760 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 10761 (outs GPR64sp:$wback), 10762 (ins listtype:$Vt, VectorIndexS:$idx, 10763 GPR64sp:$Rn, GPR64pi:$Xm)>; 10764} 10765let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 10766multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 10767 RegisterOperand listtype, RegisterOperand GPR64pi> { 10768 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 10769 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 10770 GPR64sp:$Rn), []>; 10771 10772 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 10773 (outs GPR64sp:$wback), 10774 (ins listtype:$Vt, VectorIndexD:$idx, 10775 GPR64sp:$Rn, GPR64pi:$Xm)>; 10776} 10777 10778multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 10779 string Count, int Offset, Operand idxtype> { 10780 // E.g. "ld1 { v0.8b }[0], [x1], #1" 10781 // "ld1\t$Vt, [$Rn], #1" 10782 // may get mapped to 10783 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10784 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 10785 (!cast<Instruction>(NAME # Type # "_POST") 10786 GPR64sp:$Rn, 10787 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10788 idxtype:$idx, XZR), 1>; 10789 10790 // E.g. "ld1.8b { v0 }[0], [x1], #1" 10791 // "ld1.8b\t$Vt, [$Rn], #1" 10792 // may get mapped to 10793 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10794 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 10795 (!cast<Instruction>(NAME # Type # "_POST") 10796 GPR64sp:$Rn, 10797 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10798 idxtype:$idx, XZR), 0>; 10799 10800 // E.g. "ld1.8b { v0 }[0], [x1]" 10801 // "ld1.8b\t$Vt, [$Rn]" 10802 // may get mapped to 10803 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10804 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 10805 (!cast<Instruction>(NAME # Type) 10806 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10807 idxtype:$idx, GPR64sp:$Rn), 0>; 10808 10809 // E.g. "ld1.8b { v0 }[0], [x1], x2" 10810 // "ld1.8b\t$Vt, [$Rn], $Xm" 10811 // may get mapped to 10812 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10813 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 10814 (!cast<Instruction>(NAME # Type # "_POST") 10815 GPR64sp:$Rn, 10816 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 10817 idxtype:$idx, 10818 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10819} 10820 10821multiclass SIMDLdSt1SingleAliases<string asm> { 10822 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 10823 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 10824 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 10825 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 10826} 10827 10828multiclass SIMDLdSt2SingleAliases<string asm> { 10829 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 10830 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 10831 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 10832 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 10833} 10834 10835multiclass SIMDLdSt3SingleAliases<string asm> { 10836 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 10837 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 10838 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 10839 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 10840} 10841 10842multiclass SIMDLdSt4SingleAliases<string asm> { 10843 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 10844 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 10845 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 10846 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 10847} 10848} // end of 'let Predicates = [HasNEON]' 10849 10850//---------------------------------------------------------------------------- 10851// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 10852//---------------------------------------------------------------------------- 10853 10854let Predicates = [HasNEON, HasRDM] in { 10855 10856class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 10857 RegisterOperand regtype, string asm, 10858 string kind, list<dag> pattern> 10859 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 10860 pattern> { 10861} 10862multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 10863 SDPatternOperator op> { 10864 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 10865 [(set (v4i16 V64:$dst), 10866 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 10867 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 10868 [(set (v8i16 V128:$dst), 10869 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 10870 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 10871 [(set (v2i32 V64:$dst), 10872 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 10873 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 10874 [(set (v4i32 V128:$dst), 10875 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 10876} 10877 10878multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 10879 SDPatternOperator op> { 10880 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 10881 V64, V64, V128_lo, VectorIndexH, 10882 asm, ".4h", ".4h", ".4h", ".h", 10883 [(set (v4i16 V64:$dst), 10884 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10885 (dup_v8i16 (v8i16 V128_lo:$Rm), 10886 VectorIndexH:$idx))))]> { 10887 bits<3> idx; 10888 let Inst{11} = idx{2}; 10889 let Inst{21} = idx{1}; 10890 let Inst{20} = idx{0}; 10891 } 10892 10893 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 10894 V128, V128, V128_lo, VectorIndexH, 10895 asm, ".8h", ".8h", ".8h", ".h", 10896 [(set (v8i16 V128:$dst), 10897 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10898 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 10899 VectorIndexH:$idx)))))]> { 10900 bits<3> idx; 10901 let Inst{11} = idx{2}; 10902 let Inst{21} = idx{1}; 10903 let Inst{20} = idx{0}; 10904 } 10905 10906 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 10907 V64, V64, V128, VectorIndexS, 10908 asm, ".2s", ".2s", ".2s", ".s", 10909 [(set (v2i32 V64:$dst), 10910 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10911 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 10912 bits<2> idx; 10913 let Inst{11} = idx{1}; 10914 let Inst{21} = idx{0}; 10915 } 10916 10917 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 10918 V128, V128, V128, VectorIndexS, 10919 asm, ".4s", ".4s", ".4s", ".s", 10920 [(set (v4i32 V128:$dst), 10921 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10922 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 10923 VectorIndexS:$idx)))))]> { 10924 bits<2> idx; 10925 let Inst{11} = idx{1}; 10926 let Inst{21} = idx{0}; 10927 } 10928 10929 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10930 FPR16Op, FPR16Op, V128_lo, 10931 VectorIndexH, asm, ".h", "", "", ".h", 10932 []> { 10933 bits<3> idx; 10934 let Inst{11} = idx{2}; 10935 let Inst{21} = idx{1}; 10936 let Inst{20} = idx{0}; 10937 } 10938 10939 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10940 FPR32Op, FPR32Op, V128, VectorIndexS, 10941 asm, ".s", "", "", ".s", 10942 [(set (i32 FPR32Op:$dst), 10943 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 10944 (i32 (vector_extract (v4i32 V128:$Rm), 10945 VectorIndexS:$idx)))))]> { 10946 bits<2> idx; 10947 let Inst{11} = idx{1}; 10948 let Inst{21} = idx{0}; 10949 } 10950} 10951} // let Predicates = [HasNeon, HasRDM] 10952 10953//---------------------------------------------------------------------------- 10954// ARMv8.3 Complex ADD/MLA instructions 10955//---------------------------------------------------------------------------- 10956 10957class ComplexRotationOperand<int Angle, int Remainder, string Type> 10958 : AsmOperandClass { 10959 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10960 let DiagnosticType = "InvalidComplexRotation" # Type; 10961 let Name = "ComplexRotation" # Type; 10962} 10963def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10964 SDNodeXForm<imm, [{ 10965 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 10966}]>> { 10967 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10968 let PrintMethod = "printComplexRotationOp<90, 0>"; 10969} 10970def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 10971 SDNodeXForm<imm, [{ 10972 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 10973}]>> { 10974 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10975 let PrintMethod = "printComplexRotationOp<180, 90>"; 10976} 10977let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 10978class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10979 RegisterOperand regtype, Operand rottype, 10980 string asm, string kind, list<dag> pattern> 10981 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10982 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10983 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10984 Sched<[!if(Q, WriteVq, WriteVd)]> { 10985 bits<5> Rd; 10986 bits<5> Rn; 10987 bits<5> Rm; 10988 bits<1> rot; 10989 let Inst{31} = 0; 10990 let Inst{30} = Q; 10991 let Inst{29} = U; 10992 let Inst{28-24} = 0b01110; 10993 let Inst{23-22} = size; 10994 let Inst{21} = 0; 10995 let Inst{20-16} = Rm; 10996 let Inst{15-13} = opcode; 10997 // Non-tied version (FCADD) only has one rotation bit 10998 let Inst{12} = rot; 10999 let Inst{11} = 0; 11000 let Inst{10} = 1; 11001 let Inst{9-5} = Rn; 11002 let Inst{4-0} = Rd; 11003} 11004 11005//8.3 CompNum - Floating-point complex number support 11006multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 11007 string asm, SDPatternOperator OpNode>{ 11008 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11009 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 11010 asm, ".4h", 11011 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11012 (v4f16 V64:$Rn), 11013 (v4f16 V64:$Rm), 11014 (i32 rottype:$rot)))]>; 11015 11016 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 11017 asm, ".8h", 11018 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11019 (v8f16 V128:$Rn), 11020 (v8f16 V128:$Rm), 11021 (i32 rottype:$rot)))]>; 11022 } 11023 11024 let Predicates = [HasComplxNum, HasNEON] in { 11025 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 11026 asm, ".2s", 11027 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11028 (v2f32 V64:$Rn), 11029 (v2f32 V64:$Rm), 11030 (i32 rottype:$rot)))]>; 11031 11032 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 11033 asm, ".4s", 11034 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11035 (v4f32 V128:$Rn), 11036 (v4f32 V128:$Rm), 11037 (i32 rottype:$rot)))]>; 11038 11039 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 11040 asm, ".2d", 11041 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11042 (v2f64 V128:$Rn), 11043 (v2f64 V128:$Rm), 11044 (i32 rottype:$rot)))]>; 11045 } 11046} 11047 11048let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11049class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 11050 bits<3> opcode, 11051 RegisterOperand regtype, 11052 Operand rottype, string asm, 11053 string kind, list<dag> pattern> 11054 : I<(outs regtype:$dst), 11055 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11056 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11057 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 11058 Sched<[!if(Q, WriteVq, WriteVd)]> { 11059 bits<5> Rd; 11060 bits<5> Rn; 11061 bits<5> Rm; 11062 bits<2> rot; 11063 let Inst{31} = 0; 11064 let Inst{30} = Q; 11065 let Inst{29} = U; 11066 let Inst{28-24} = 0b01110; 11067 let Inst{23-22} = size; 11068 let Inst{21} = 0; 11069 let Inst{20-16} = Rm; 11070 let Inst{15-13} = opcode; 11071 let Inst{12-11} = rot; 11072 let Inst{10} = 1; 11073 let Inst{9-5} = Rn; 11074 let Inst{4-0} = Rd; 11075} 11076 11077multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 11078 Operand rottype, string asm, 11079 SDPatternOperator OpNode> { 11080 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11081 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 11082 rottype, asm, ".4h", 11083 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11084 (v4f16 V64:$Rn), 11085 (v4f16 V64:$Rm), 11086 (i32 rottype:$rot)))]>; 11087 11088 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 11089 rottype, asm, ".8h", 11090 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11091 (v8f16 V128:$Rn), 11092 (v8f16 V128:$Rm), 11093 (i32 rottype:$rot)))]>; 11094 } 11095 11096 let Predicates = [HasComplxNum, HasNEON] in { 11097 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 11098 rottype, asm, ".2s", 11099 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11100 (v2f32 V64:$Rn), 11101 (v2f32 V64:$Rm), 11102 (i32 rottype:$rot)))]>; 11103 11104 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 11105 rottype, asm, ".4s", 11106 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11107 (v4f32 V128:$Rn), 11108 (v4f32 V128:$Rm), 11109 (i32 rottype:$rot)))]>; 11110 11111 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 11112 rottype, asm, ".2d", 11113 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11114 (v2f64 V128:$Rn), 11115 (v2f64 V128:$Rm), 11116 (i32 rottype:$rot)))]>; 11117 } 11118} 11119 11120let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11121class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 11122 bit opc1, bit opc2, RegisterOperand dst_reg, 11123 RegisterOperand lhs_reg, 11124 RegisterOperand rhs_reg, Operand vec_idx, 11125 Operand rottype, string asm, string apple_kind, 11126 string dst_kind, string lhs_kind, 11127 string rhs_kind, list<dag> pattern> 11128 : I<(outs dst_reg:$dst), 11129 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 11130 asm, 11131 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 11132 "$idx, $rot" # "|" # apple_kind # 11133 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 11134 Sched<[!if(Q, WriteVq, WriteVd)]> { 11135 bits<5> Rd; 11136 bits<5> Rn; 11137 bits<5> Rm; 11138 bits<2> rot; 11139 11140 let Inst{31} = 0; 11141 let Inst{30} = Q; 11142 let Inst{29} = U; 11143 let Inst{28} = Scalar; 11144 let Inst{27-24} = 0b1111; 11145 let Inst{23-22} = size; 11146 // Bit 21 must be set by the derived class. 11147 let Inst{20-16} = Rm; 11148 let Inst{15} = opc1; 11149 let Inst{14-13} = rot; 11150 let Inst{12} = opc2; 11151 // Bit 11 must be set by the derived class. 11152 let Inst{10} = 0; 11153 let Inst{9-5} = Rn; 11154 let Inst{4-0} = Rd; 11155} 11156 11157// The complex instructions index by pairs of elements, so the VectorIndexes 11158// don't match the lane types, and the index bits are different to the other 11159// classes. 11160multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 11161 string asm> { 11162 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11163 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 11164 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 11165 ".4h", ".h", []> { 11166 bits<1> idx; 11167 let Inst{11} = 0; 11168 let Inst{21} = idx{0}; 11169 } 11170 11171 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 11172 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 11173 ".8h", ".8h", ".h", []> { 11174 bits<2> idx; 11175 let Inst{11} = idx{1}; 11176 let Inst{21} = idx{0}; 11177 } 11178 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 11179 11180 let Predicates = [HasComplxNum, HasNEON] in { 11181 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 11182 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 11183 ".4s", ".4s", ".s", []> { 11184 bits<1> idx; 11185 let Inst{11} = idx{0}; 11186 let Inst{21} = 0; 11187 } 11188 } // Predicates = [HasComplxNum, HasNEON] 11189} 11190 11191//---------------------------------------------------------------------------- 11192// Crypto extensions 11193//---------------------------------------------------------------------------- 11194 11195let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11196class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 11197 list<dag> pat> 11198 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 11199 Sched<[WriteVq]>{ 11200 bits<5> Rd; 11201 bits<5> Rn; 11202 let Inst{31-16} = 0b0100111000101000; 11203 let Inst{15-12} = opc; 11204 let Inst{11-10} = 0b10; 11205 let Inst{9-5} = Rn; 11206 let Inst{4-0} = Rd; 11207} 11208 11209class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 11210 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 11211 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 11212 11213class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 11214 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 11215 "$Rd = $dst", 11216 [(set (v16i8 V128:$dst), 11217 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 11218 11219let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11220class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 11221 dag oops, dag iops, list<dag> pat> 11222 : I<oops, iops, asm, 11223 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 11224 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 11225 Sched<[WriteVq]>{ 11226 bits<5> Rd; 11227 bits<5> Rn; 11228 bits<5> Rm; 11229 let Inst{31-21} = 0b01011110000; 11230 let Inst{20-16} = Rm; 11231 let Inst{15} = 0; 11232 let Inst{14-12} = opc; 11233 let Inst{11-10} = 0b00; 11234 let Inst{9-5} = Rn; 11235 let Inst{4-0} = Rd; 11236} 11237 11238class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11239 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11240 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11241 [(set (v4i32 FPR128:$dst), 11242 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11243 (v4i32 V128:$Rm)))]>; 11244 11245class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11246 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11247 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11248 [(set (v4i32 V128:$dst), 11249 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11250 (v4i32 V128:$Rm)))]>; 11251 11252class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11253 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11254 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11255 [(set (v4i32 FPR128:$dst), 11256 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11257 (v4i32 V128:$Rm)))]>; 11258 11259let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11260class SHA2OpInst<bits<4> opc, string asm, string kind, 11261 string cstr, dag oops, dag iops, 11262 list<dag> pat> 11263 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11264 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11265 Sched<[WriteVq]>{ 11266 bits<5> Rd; 11267 bits<5> Rn; 11268 let Inst{31-16} = 0b0101111000101000; 11269 let Inst{15-12} = opc; 11270 let Inst{11-10} = 0b10; 11271 let Inst{9-5} = Rn; 11272 let Inst{4-0} = Rd; 11273} 11274 11275class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11276 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11277 (ins V128:$Rd, V128:$Rn), 11278 [(set (v4i32 V128:$dst), 11279 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11280 11281class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11282 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11283 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11284 11285// Armv8.2-A Crypto extensions 11286class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11287 list<dag> pattern> 11288 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11289 bits<5> Vd; 11290 bits<5> Vn; 11291 let Inst{31-25} = 0b1100111; 11292 let Inst{9-5} = Vn; 11293 let Inst{4-0} = Vd; 11294} 11295 11296class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11297 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11298 "$Vd = $Vdst", []> { 11299 let Inst{31-25} = 0b1100111; 11300 let Inst{24-21} = 0b0110; 11301 let Inst{20-15} = 0b000001; 11302 let Inst{14} = op0; 11303 let Inst{13-12} = 0b00; 11304 let Inst{11-10} = op1; 11305} 11306class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11307 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11308class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11309 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11310 11311class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11312 string asmops, string cst> 11313 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11314 bits<5> Vm; 11315 let Inst{24-21} = 0b0011; 11316 let Inst{20-16} = Vm; 11317 let Inst{15} = 0b1; 11318 let Inst{14} = op0; 11319 let Inst{13-12} = 0b00; 11320 let Inst{11-10} = op1; 11321} 11322class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11323 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11324 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11325class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11326 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11327 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11328class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11329 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11330 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11331class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11332 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11333 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11334class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11335 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11336 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11337 11338class CryptoRRRR<bits<2>op0, string asm, string asmops> 11339 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11340 asmops, "", []> { 11341 bits<5> Vm; 11342 bits<5> Va; 11343 let Inst{24-23} = 0b00; 11344 let Inst{22-21} = op0; 11345 let Inst{20-16} = Vm; 11346 let Inst{15} = 0b0; 11347 let Inst{14-10} = Va; 11348} 11349class CryptoRRRR_16B<bits<2>op0, string asm> 11350 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11351 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11352} 11353class CryptoRRRR_4S<bits<2>op0, string asm> 11354 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11355 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11356} 11357 11358class CryptoRRRi6<string asm> 11359 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11360 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11361 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11362 bits<6> imm; 11363 bits<5> Vm; 11364 let Inst{24-21} = 0b0100; 11365 let Inst{20-16} = Vm; 11366 let Inst{15-10} = imm; 11367 let Inst{9-5} = Vn; 11368 let Inst{4-0} = Vd; 11369} 11370 11371class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11372 : BaseCryptoV82<(outs V128:$Vdst), 11373 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11374 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11375 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11376 bits<2> imm; 11377 bits<5> Vm; 11378 let Inst{24-21} = 0b0010; 11379 let Inst{20-16} = Vm; 11380 let Inst{15} = 0b1; 11381 let Inst{14} = op0; 11382 let Inst{13-12} = imm; 11383 let Inst{11-10} = op1; 11384} 11385 11386//---------------------------------------------------------------------------- 11387// v8.1 atomic instructions extension: 11388// * CAS 11389// * CASP 11390// * SWP 11391// * LDOPregister<OP>, and aliases STOPregister<OP> 11392 11393// Instruction encodings: 11394// 11395// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11396// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11397// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11398// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11399// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11400// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11401 11402// Instruction syntax: 11403// 11404// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11405// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11406// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11407// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11408// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11409// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11410// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11411// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11412// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11413// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11414 11415let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11416class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11417 string cstr, list<dag> pattern> 11418 : I<oops, iops, asm, operands, cstr, pattern> { 11419 bits<2> Sz; 11420 bit NP; 11421 bit Acq; 11422 bit Rel; 11423 bits<5> Rs; 11424 bits<5> Rn; 11425 bits<5> Rt; 11426 let Inst{31-30} = Sz; 11427 let Inst{29-24} = 0b001000; 11428 let Inst{23} = NP; 11429 let Inst{22} = Acq; 11430 let Inst{21} = 0b1; 11431 let Inst{20-16} = Rs; 11432 let Inst{15} = Rel; 11433 let Inst{14-10} = 0b11111; 11434 let Inst{9-5} = Rn; 11435 let Inst{4-0} = Rt; 11436 let Predicates = [HasLSE]; 11437} 11438 11439class BaseCAS<string order, string size, RegisterClass RC> 11440 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11441 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11442 "$out = $Rs",[]>, 11443 Sched<[WriteAtomic]> { 11444 let NP = 1; 11445} 11446 11447multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11448 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11449 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11450 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11451 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11452} 11453 11454class BaseCASP<string order, string size, RegisterOperand RC> 11455 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11456 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11457 "$out = $Rs",[]>, 11458 Sched<[WriteAtomic]> { 11459 let NP = 0; 11460} 11461 11462multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11463 let Sz = 0b00, Acq = Acq, Rel = Rel in 11464 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11465 let Sz = 0b01, Acq = Acq, Rel = Rel in 11466 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11467} 11468 11469let Predicates = [HasLSE] in 11470class BaseSWP<string order, string size, RegisterClass RC> 11471 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11472 "\t$Rs, $Rt, [$Rn]","",[]>, 11473 Sched<[WriteAtomic]> { 11474 bits<2> Sz; 11475 bit Acq; 11476 bit Rel; 11477 bits<5> Rs; 11478 bits<3> opc = 0b000; 11479 bits<5> Rn; 11480 bits<5> Rt; 11481 let Inst{31-30} = Sz; 11482 let Inst{29-24} = 0b111000; 11483 let Inst{23} = Acq; 11484 let Inst{22} = Rel; 11485 let Inst{21} = 0b1; 11486 let Inst{20-16} = Rs; 11487 let Inst{15} = 0b1; 11488 let Inst{14-12} = opc; 11489 let Inst{11-10} = 0b00; 11490 let Inst{9-5} = Rn; 11491 let Inst{4-0} = Rt; 11492 let Predicates = [HasLSE]; 11493} 11494 11495multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11496 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11497 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11498 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11499 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11500} 11501 11502let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11503class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11504 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11505 "\t$Rs, $Rt, [$Rn]","",[]>, 11506 Sched<[WriteAtomic]> { 11507 bits<2> Sz; 11508 bit Acq; 11509 bit Rel; 11510 bits<5> Rs; 11511 bits<3> opc; 11512 bits<5> Rn; 11513 bits<5> Rt; 11514 let Inst{31-30} = Sz; 11515 let Inst{29-24} = 0b111000; 11516 let Inst{23} = Acq; 11517 let Inst{22} = Rel; 11518 let Inst{21} = 0b1; 11519 let Inst{20-16} = Rs; 11520 let Inst{15} = 0b0; 11521 let Inst{14-12} = opc; 11522 let Inst{11-10} = 0b00; 11523 let Inst{9-5} = Rn; 11524 let Inst{4-0} = Rt; 11525 let Predicates = [HasLSE]; 11526} 11527 11528multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11529 string order> { 11530 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11531 def B : BaseLDOPregister<op, order, "b", GPR32>; 11532 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11533 def H : BaseLDOPregister<op, order, "h", GPR32>; 11534 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11535 def W : BaseLDOPregister<op, order, "", GPR32>; 11536 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11537 def X : BaseLDOPregister<op, order, "", GPR64>; 11538} 11539 11540// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11541// complex DAG for DstRHS. 11542let Predicates = [HasLSE] in 11543multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11544 string size, dag SrcRHS, dag DstRHS> { 11545 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11546 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11547 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11548 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11549 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11550 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11551 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11552 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11553 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11554 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11555} 11556 11557multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11558 string size, dag RHS> { 11559 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11560} 11561 11562multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11563 string size, dag LHS, dag RHS> { 11564 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11565} 11566 11567multiclass LDOPregister_patterns<string inst, string op> { 11568 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11569 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11570 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11571 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11572} 11573 11574multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11575 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11576 (i64 GPR64:$Rm), 11577 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11578 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11579 (i32 GPR32:$Rm), 11580 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11581 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11582 (i32 GPR32:$Rm), 11583 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11584 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11585 (i32 GPR32:$Rm), 11586 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11587} 11588 11589let Predicates = [HasLSE] in 11590multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11591 string size, dag OLD, dag NEW> { 11592 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11593 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11594 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11595 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11596 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11597 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11598 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11599 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11600 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11601 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11602} 11603 11604multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11605 string size, dag OLD, dag NEW> { 11606 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11607} 11608 11609multiclass CASregister_patterns<string inst, string op> { 11610 defm : CASregister_patterns_ord<inst, "X", op, "64", 11611 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11612 defm : CASregister_patterns_ord<inst, "W", op, "32", 11613 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11614 defm : CASregister_patterns_ord<inst, "H", op, "16", 11615 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11616 defm : CASregister_patterns_ord<inst, "B", op, "8", 11617 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11618} 11619 11620let Predicates = [HasLSE] in 11621class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11622 Instruction inst> : 11623 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11624 11625multiclass STOPregister<string asm, string instr> { 11626 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11627 !cast<Instruction>(instr # "LB")>; 11628 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11629 !cast<Instruction>(instr # "LH")>; 11630 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11631 !cast<Instruction>(instr # "LW")>; 11632 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11633 !cast<Instruction>(instr # "LX")>; 11634 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11635 !cast<Instruction>(instr # "B")>; 11636 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11637 !cast<Instruction>(instr # "H")>; 11638 def : BaseSTOPregister<asm, GPR32, WZR, 11639 !cast<Instruction>(instr # "W")>; 11640 def : BaseSTOPregister<asm, GPR64, XZR, 11641 !cast<Instruction>(instr # "X")>; 11642} 11643 11644class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11645 dag iops, dag oops, list<dag> pat> 11646 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11647 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11648 bits<5> Rt; 11649 bits<5> Rn; 11650 let Inst{31-21} = 0b11111000001; 11651 let Inst{15} = 1; 11652 let Inst{14-12} = opc; 11653 let Inst{11-10} = 0b00; 11654 let Inst{9-5} = Rn; 11655 let Inst{4-0} = Rt; 11656 11657 let Predicates = [HasV8_7a]; 11658} 11659 11660class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11661 list<dag> pat = []> 11662 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11663 let Inst{20-16} = 0b11111; 11664} 11665 11666class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11667 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11668 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11669 bits<5> Rs; 11670 let Inst{20-16} = Rs; 11671} 11672 11673class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11674 bits<2> op2, string asm> 11675 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11676 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11677 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11678 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11679 Sched<[]> { 11680 bits<5> Rd; 11681 bits<5> Rs; 11682 bits<5> Rn; 11683 let Inst{31-27} = 0b00011; 11684 let Inst{26} = isMove; 11685 let Inst{25-24} = 0b01; 11686 let Inst{23-22} = opcode; 11687 let Inst{21} = 0b0; 11688 let Inst{20-16} = Rs; 11689 let Inst{15-14} = op2; 11690 let Inst{13-12} = op1; 11691 let Inst{11-10} = 0b01; 11692 let Inst{9-5} = Rn; 11693 let Inst{4-0} = Rd; 11694 11695 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11696 let mayLoad = 1; 11697 let mayStore = 1; 11698} 11699 11700class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11701 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11702 11703class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11704 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11705 11706class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11707 string asm> 11708 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11709 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11710 asm, "\t[$Rd]!, $Rn!, $Rm", 11711 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11712 Sched<[]> { 11713 bits<5> Rd; 11714 bits<5> Rn; 11715 bits<5> Rm; 11716 let Inst{31-27} = 0b00011; 11717 let Inst{26} = isTagging; 11718 let Inst{25-21} = 0b01110; 11719 let Inst{20-16} = Rm; 11720 let Inst{15-14} = opcode; 11721 let Inst{13} = op2; 11722 let Inst{12} = op1; 11723 let Inst{11-10} = 0b01; 11724 let Inst{9-5} = Rn; 11725 let Inst{4-0} = Rd; 11726 11727 let DecoderMethod = "DecodeSETMemOpInstruction"; 11728 let mayLoad = 0; 11729 let mayStore = 1; 11730} 11731 11732class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 11733 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 11734 11735class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 11736 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 11737 11738multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 11739 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 11740 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 11741 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 11742 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 11743 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 11744 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 11745 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 11746 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 11747 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 11748 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 11749 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 11750 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 11751 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 11752 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 11753 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 11754 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 11755} 11756 11757multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 11758 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 11759 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 11760 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 11761 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 11762 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 11763 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 11764 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 11765 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 11766 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 11767 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 11768 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 11769 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 11770 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 11771 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 11772 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 11773 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 11774} 11775 11776multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 11777 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 11778 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 11779 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 11780 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 11781} 11782 11783multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 11784 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 11785 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 11786 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 11787 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 11788} 11789 11790//---------------------------------------------------------------------------- 11791// 2022 Armv8.9/Armv9.4 Extensions 11792//---------------------------------------------------------------------------- 11793 11794//--- 11795// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC) 11796//--- 11797 11798class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc, 11799 RegisterClass regtype, ImmLeaf immtype, string asm, 11800 SDPatternOperator OpNode> 11801 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm), 11802 asm, "\t$Rd, $Rn, $imm", "", 11803 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> { 11804 bits<5> Rd; 11805 bits<5> Rn; 11806 bits<8> imm; 11807 11808 let Inst{31} = sf; 11809 let Inst{30} = Op; 11810 let Inst{29} = S; 11811 let Inst{28-22} = 0b1000111; 11812 let Inst{21-18} = opc; 11813 let Inst{17-10} = imm; 11814 let Inst{9-5} = Rn; 11815 let Inst{4-0} = Rd; 11816} 11817 11818class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin, 11819 RegisterClass regtype, string asm, 11820 SDPatternOperator OpNode> 11821 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>, 11822 Sched<[WriteI]> { 11823 let Inst{11} = isMin; 11824 let Inst{10} = isUnsigned; 11825 let mayLoad = 0; 11826 let mayStore = 0; 11827 let hasSideEffects = 0; 11828} 11829 11830class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin, 11831 RegisterClass regtype, ImmLeaf immtype, string asm, 11832 SDPatternOperator OpNode> 11833 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm, 11834 OpNode>, 11835 Sched<[]> { 11836 let Inst{19} = isMin; 11837 let Inst{18} = isUnsigned; 11838 let mayLoad = 0; 11839 let mayStore = 0; 11840 let hasSideEffects = 0; 11841} 11842 11843multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm, 11844 SDPatternOperator OpNode = null_frag> { 11845 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>; 11846 11847 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32, 11848 !cond(isUnsigned : uimm8_32b, 11849 !not(isUnsigned) : simm8_32b), asm, OpNode>; 11850 11851 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>; 11852 11853 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64, 11854 !cond(isUnsigned : uimm8_64b, 11855 !not(isUnsigned) : simm8_64b), asm, OpNode>; 11856} 11857 11858//--- 11859// RCPC instructions (FEAT_LRCPC3) 11860//--- 11861 11862class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops, 11863 string asm, string operands, string cstr = ""> 11864 : I<oops, iops, asm, operands, cstr, []>, 11865 Sched<[WriteAtomic]> { 11866 bits<5> Rt; 11867 bits<5> Rn; 11868 let Inst{31-30} = size; 11869 let Inst{29-24} = {0,1,1,V,0,1}; 11870 let Inst{23-22} = opc; 11871 let Inst{21} = 0b0; 11872 // Inst{20-12} 11873 let Inst{11-10} = 0b10; 11874 let Inst{9-5} = Rn; 11875 let Inst{4-0} = Rt; 11876 11877 let mayLoad = Inst{22}; 11878 let mayStore = !not(Inst{22}); 11879 let hasSideEffects = 0; 11880} 11881 11882class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2, 11883 dag oops, dag iops, string asm, 11884 string operands, string cstr> 11885 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 11886 bits<5> Rt2; 11887 let Inst{20-16} = Rt2; 11888 let Inst{15-12} = opc2; 11889} 11890 11891class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops, 11892 string asm, string operands, string cstr> 11893 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 11894 let Inst{20-12} = 0b000000000; // imm9 11895} 11896 11897multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype, 11898 dag oops, dag iops, string asm> { 11899 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> { 11900 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 11901 let Inst{20-12} = simm; 11902 } 11903 11904 def a : InstAlias<asm # "\t$Rt, [$Rn]", 11905 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 11906} 11907 11908class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst> 11909 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm, 11910 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>, 11911 Sched<[]> { 11912 bit Q; 11913 let Inst{31} = 0; 11914 let Inst{30} = Q; 11915 let Inst{23} = 0; 11916 let Inst{20-16} = 0b00001; 11917 let Inst{12} = 0; // S 11918 let Inst{11-10} = 0b01; // size 11919 11920 let mayLoad = L; 11921 let mayStore = !not(L); 11922 let hasSideEffects = 1; 11923} 11924 11925//--- 11926// Instrumentation Extension (FEAT_ITE) 11927//--- 11928 11929let Predicates = [HasITE] in 11930def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> { 11931 let Inst{20-19} = 0b01; 11932 let Inst{18-16} = 0b011; 11933 let Inst{15-12} = 0b0111; 11934 let Inst{11-8} = 0b0010; 11935 let Inst{7-5} = 0b111; 11936} 11937 11938// * RCWCAS family 11939// * RCW<OP> family 11940 11941//-------------------------------------------------------------------- 11942// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?) 11943 11944// Instruction encoding: 11945// 11946// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0 11947// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 11948// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 11949// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 11950// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 11951 11952// Instruction syntax: 11953// 11954// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11955// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>] 11956 11957class BaseRCWCASEncoding<dag oops, dag iops, string asm> 11958 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>, 11959 Sched<[]> { 11960 bit Acq; 11961 bit Rel; 11962 bit SC; 11963 bit Pair; 11964 bits<5> Rs; 11965 bits<5> Rn; 11966 bits<5> Rt; 11967 let Inst{31} = 0b0; 11968 let Inst{30} = SC; 11969 let Inst{29-24} = 0b011001; 11970 let Inst{23} = Acq; 11971 let Inst{22} = Rel; 11972 let Inst{21} = 0b1; 11973 let Inst{20-16} = Rs; 11974 let Inst{15-13} = 0b000; 11975 let Inst{12-11} = 0b01; 11976 let Inst{10} = Pair; 11977 let Inst{9-5} = Rn; 11978 let Inst{4-0} = Rt; 11979 let mayLoad = 1; 11980 let mayStore = 1; 11981 let hasSideEffects = 1; 11982 let Defs = [NZCV]; 11983} 11984 11985multiclass BaseRCWCAS<dag oops, dag iops, string prefix> { 11986 let Acq = 0b0, Rel = 0b0 in 11987 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">; 11988 let Acq = 0b1, Rel = 0b0 in 11989 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">; 11990 let Acq = 0b0, Rel = 0b1 in 11991 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">; 11992 let Acq = 0b1, Rel = 0b1 in 11993 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">; 11994} 11995 11996multiclass ReadCheckWriteCompareAndSwap { 11997 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in 11998 defm CAS : BaseRCWCAS<(outs GPR64:$out), 11999 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >; 12000 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in 12001 defm SCAS : BaseRCWCAS<(outs GPR64:$out), 12002 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">; 12003 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12004 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12005 (ins XSeqPairClassOperand:$Rs, 12006 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12007 "rcwcasp">; 12008 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12009 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12010 (ins XSeqPairClassOperand:$Rs, 12011 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12012 "rcwscasp">; 12013} 12014 12015//------------------------------------------------------------------ 12016// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?) 12017 12018// Instruction encoding: 12019// 12020// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12021// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12022// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12023// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12024// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12025// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12026// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12027 12028// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12029// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12030// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12031// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12032// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12033// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12034// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12035 12036// Instruction syntax: 12037// 12038// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 12039// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>] 12040 12041class BaseRCWOPEncoding<string asm> 12042 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm, 12043 "\t$Rs, $Rt, [$Rn]", "", []>, 12044 Sched<[]> { 12045 bit Acq; 12046 bit Rel; 12047 bit SC; 12048 bits<3> opc; 12049 bits<5> Rs; 12050 bits<5> Rn; 12051 bits<5> Rt; 12052 let Inst{31} = 0b0; 12053 let Inst{30} = SC; 12054 let Inst{29-24} = 0b111000; 12055 let Inst{23} = Acq; 12056 let Inst{22} = Rel; 12057 let Inst{21} = 0b1; 12058 let Inst{20-16} = Rs; 12059 let Inst{15} = 0b1; 12060 let Inst{14-12} = opc; 12061 let Inst{11-10} = 0b00; 12062 let Inst{9-5} = Rn; 12063 let Inst{4-0} = Rt; 12064 let mayLoad = 1; 12065 let mayStore = 1; 12066 let hasSideEffects = 1; 12067 let Defs = [NZCV]; 12068 let Predicates = [HasTHE]; 12069} 12070 12071class BaseRCWOPPEncoding<string asm> 12072 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12073 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm, 12074 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12075 Sched<[]> { 12076 bit Acq; 12077 bit Rel; 12078 bit SC; 12079 bits<3> opc; 12080 bits<5> Rt2; 12081 bits<5> Rn; 12082 bits<5> Rt; 12083 let Inst{31} = 0b0; 12084 let Inst{30} = SC; 12085 let Inst{29-24} = 0b011001; 12086 let Inst{23} = Acq; 12087 let Inst{22} = Rel; 12088 let Inst{21} = 0b1; 12089 let Inst{20-16} = Rt2; 12090 let Inst{15} = 0b1; 12091 let Inst{14-12} = opc; 12092 let Inst{11-10} = 0b00; 12093 let Inst{9-5} = Rn; 12094 let Inst{4-0} = Rt; 12095 let mayLoad = 1; 12096 let mayStore = 1; 12097 let hasSideEffects = 1; 12098 let Defs = [NZCV]; 12099 let Predicates = [HasTHE, HasD128]; 12100} 12101 12102multiclass BaseRCWOP<string prefix> { 12103 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">; 12104 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">; 12105 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">; 12106 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">; 12107 12108 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">; 12109 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">; 12110 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">; 12111 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">; 12112} 12113 12114multiclass ReadCheckWriteOperation<bits<3> opc, string op> { 12115 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>; 12116 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >; 12117} 12118 12119//--- 12120// 128-bit atomic instructions (FEAT_LSE128) 12121//--- 12122 12123let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in 12124class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm> 12125: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12126 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), 12127 asm, "\t$Rt, $Rt2, [$Rn]", 12128 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12129 Sched<[]> { 12130 bits<5> Rt; 12131 bits<5> Rt2; 12132 bits<5> Rn; 12133 let Inst{31-24} = 0b00011001; 12134 let Inst{23-22} = AR; 12135 let Inst{21} = 0b1; 12136 let Inst{20-16} = Rt2; 12137 let Inst{15} = o3; 12138 let Inst{14-12} = op0; 12139 let Inst{11-10} = 0b00; 12140 let Inst{9-5} = Rn; 12141 let Inst{4-0} = Rt; 12142} 12143 12144//--- 12145// 128-bit System Instructions (FEAT_SYSINSTR128) 12146//--- 12147 12148// Instruction encoding: 12149// 12150// 31 19|18 16|15 12|11 8|7 5|4 0 12151// SYSP 1101010101001| op1| Cn| Cm|op2| Rt 12152 12153// Instruction syntax: 12154// 12155// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>} 12156 12157class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> : 12158 RtSystemI<L, oops, iops, asm, operands, pattern> { 12159 let Inst{22} = 0b1; // override BaseSystemI 12160} 12161 12162class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs> 12163 : RtSystemI128<L, outputs, inputs, asm, operands> { 12164 bits<3> op1; 12165 bits<4> Cn; 12166 bits<4> Cm; 12167 bits<3> op2; 12168 let Inst{20-19} = 0b01; 12169 let Inst{18-16} = op1; 12170 let Inst{15-12} = Cn; 12171 let Inst{11-8} = Cm; 12172 let Inst{7-5} = op2; 12173} 12174class SystemPXtI<bit L, string asm> : 12175 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs), 12176 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>; 12177 12178 12179//---------------------------------------------------------------------------- 12180// Allow the size specifier tokens to be upper case, not just lower. 12181def : TokenAlias<".4B", ".4b">; // Add dot product 12182def : TokenAlias<".8B", ".8b">; 12183def : TokenAlias<".4H", ".4h">; 12184def : TokenAlias<".2S", ".2s">; 12185def : TokenAlias<".1D", ".1d">; 12186def : TokenAlias<".16B", ".16b">; 12187def : TokenAlias<".8H", ".8h">; 12188def : TokenAlias<".4S", ".4s">; 12189def : TokenAlias<".2D", ".2d">; 12190def : TokenAlias<".1Q", ".1q">; 12191def : TokenAlias<".2H", ".2h">; 12192def : TokenAlias<".B", ".b">; 12193def : TokenAlias<".H", ".h">; 12194def : TokenAlias<".S", ".s">; 12195def : TokenAlias<".D", ".d">; 12196def : TokenAlias<".Q", ".q">; 12197