1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// Describe AArch64 instructions format here 11// 12 13// Format specifies the encoding used by the instruction. This is part of the 14// ad-hoc solution used to emit machine instruction encodings by our machine 15// code emitter. 16class Format<bits<2> val> { 17 bits<2> Value = val; 18} 19 20def PseudoFrm : Format<0>; 21def NormalFrm : Format<1>; // Do we need any others? 22 23// Enum describing whether an instruction is 24// destructive in its first source operand. 25class DestructiveInstTypeEnum<bits<4> val> { 26 bits<4> Value = val; 27} 28def NotDestructive : DestructiveInstTypeEnum<0>; 29// Destructive in its first operand and can be MOVPRFX'd, but has no other 30// special properties. 31def DestructiveOther : DestructiveInstTypeEnum<1>; 32def DestructiveUnary : DestructiveInstTypeEnum<2>; 33def DestructiveBinaryImm : DestructiveInstTypeEnum<3>; 34def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>; 35def DestructiveBinary : DestructiveInstTypeEnum<5>; 36def DestructiveBinaryComm : DestructiveInstTypeEnum<6>; 37def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>; 38def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>; 39def DestructiveUnaryPassthru : DestructiveInstTypeEnum<9>; 40 41class FalseLanesEnum<bits<2> val> { 42 bits<2> Value = val; 43} 44def FalseLanesNone : FalseLanesEnum<0>; 45def FalseLanesZero : FalseLanesEnum<1>; 46def FalseLanesUndef : FalseLanesEnum<2>; 47 48class SMEMatrixTypeEnum<bits<3> val> { 49 bits<3> Value = val; 50} 51def SMEMatrixNone : SMEMatrixTypeEnum<0>; 52def SMEMatrixTileB : SMEMatrixTypeEnum<1>; 53def SMEMatrixTileH : SMEMatrixTypeEnum<2>; 54def SMEMatrixTileS : SMEMatrixTypeEnum<3>; 55def SMEMatrixTileD : SMEMatrixTypeEnum<4>; 56def SMEMatrixTileQ : SMEMatrixTypeEnum<5>; 57def SMEMatrixArray : SMEMatrixTypeEnum<6>; 58 59// AArch64 Instruction Format 60class AArch64Inst<Format f, string cstr> : Instruction { 61 field bits<32> Inst; // Instruction encoding. 62 // Mask of bits that cause an encoding to be UNPREDICTABLE. 63 // If a bit is set, then if the corresponding bit in the 64 // target encoding differs from its value in the "Inst" field, 65 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 66 field bits<32> Unpredictable = 0; 67 // SoftFail is the generic name for this field, but we alias it so 68 // as to make it more obvious what it means in ARM-land. 69 field bits<32> SoftFail = Unpredictable; 70 let Namespace = "AArch64"; 71 Format F = f; 72 bits<2> Form = F.Value; 73 74 // Defaults 75 bit isWhile = 0; 76 bit isPTestLike = 0; 77 FalseLanesEnum FalseLanes = FalseLanesNone; 78 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 79 SMEMatrixTypeEnum SMEMatrixType = SMEMatrixNone; 80 ElementSizeEnum ElementSize = ElementSizeNone; 81 82 let TSFlags{13-11} = SMEMatrixType.Value; 83 let TSFlags{10} = isPTestLike; 84 let TSFlags{9} = isWhile; 85 let TSFlags{8-7} = FalseLanes.Value; 86 let TSFlags{6-3} = DestructiveInstType.Value; 87 let TSFlags{2-0} = ElementSize.Value; 88 89 let Pattern = []; 90 let Constraints = cstr; 91} 92 93class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 94 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 95 96// Pseudo instructions (don't have encoding information) 97class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 98 : AArch64Inst<PseudoFrm, cstr> { 99 dag OutOperandList = oops; 100 dag InOperandList = iops; 101 let Pattern = pattern; 102 let isCodeGenOnly = 1; 103 let isPseudo = 1; 104} 105 106// Real instructions (have encoding information) 107class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 108 let Pattern = pattern; 109 let Size = 4; 110} 111 112// Normal instructions 113class I<dag oops, dag iops, string asm, string operands, string cstr, 114 list<dag> pattern> 115 : EncodedI<cstr, pattern> { 116 dag OutOperandList = oops; 117 dag InOperandList = iops; 118 let AsmString = !strconcat(asm, operands); 119} 120 121class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 122class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 123class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 124 125// Helper fragment for an extract of the high portion of a 128-bit vector. The 126// ComplexPattern match both extract_subvector and bitcast(extract_subvector(..)). 127def extract_high_v16i8 : 128 ComplexPattern<v8i8, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 129def extract_high_v8i16 : 130 ComplexPattern<v4i16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 131def extract_high_v4i32 : 132 ComplexPattern<v2i32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 133def extract_high_v2i64 : 134 ComplexPattern<v1i64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 135 136def gi_extract_high_v16i8 : 137 GIComplexOperandMatcher<v8s8, "selectExtractHigh">, 138 GIComplexPatternEquiv<extract_high_v16i8>; 139def gi_extract_high_v8i16 : 140 GIComplexOperandMatcher<v4s16, "selectExtractHigh">, 141 GIComplexPatternEquiv<extract_high_v8i16>; 142def gi_extract_high_v4i32 : 143 GIComplexOperandMatcher<v2s32, "selectExtractHigh">, 144 GIComplexPatternEquiv<extract_high_v4i32>; 145 146def extract_high_v8f16 : 147 ComplexPattern<v4f16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 148def extract_high_v4f32 : 149 ComplexPattern<v2f32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>; 150 151def gi_extract_high_v8f16 : 152 GIComplexOperandMatcher<v4s16, "selectExtractHigh">, 153 GIComplexPatternEquiv<extract_high_v8f16>; 154def gi_extract_high_v4f32 : 155 GIComplexOperandMatcher<v2s32, "selectExtractHigh">, 156 GIComplexPatternEquiv<extract_high_v4f32>; 157 158def extract_high_dup_v8i16 : 159 BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>; 160def extract_high_dup_v4i32 : 161 BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>; 162 163def dup_v8i16 : 164 PatFrags<(ops node:$LHS, node:$RHS), 165 [(v4i16 (extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 0))), 166 (v4i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS))]>; 167def dup_v4i32 : 168 PatFrags<(ops node:$LHS, node:$RHS), 169 [(v2i32 (extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 0))), 170 (v2i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS))]>; 171def dup_v8f16 : 172 PatFrags<(ops node:$LHS, node:$RHS), 173 [(v4f16 (extract_subvector (v8f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS)), (i64 0))), 174 (v4f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS))]>; 175def dup_v4f32 : 176 PatFrags<(ops node:$LHS, node:$RHS), 177 [(v2f32 (extract_subvector (v4f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS)), (i64 0))), 178 (v2f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS))]>; 179 180//===----------------------------------------------------------------------===// 181// Asm Operand Classes. 182// 183 184// Shifter operand for arithmetic shifted encodings. 185def ShifterOperand : AsmOperandClass { 186 let Name = "Shifter"; 187} 188 189// Shifter operand for mov immediate encodings. 190def MovImm32ShifterOperand : AsmOperandClass { 191 let SuperClasses = [ShifterOperand]; 192 let Name = "MovImm32Shifter"; 193 let RenderMethod = "addShifterOperands"; 194 let DiagnosticType = "InvalidMovImm32Shift"; 195} 196def MovImm64ShifterOperand : AsmOperandClass { 197 let SuperClasses = [ShifterOperand]; 198 let Name = "MovImm64Shifter"; 199 let RenderMethod = "addShifterOperands"; 200 let DiagnosticType = "InvalidMovImm64Shift"; 201} 202 203// Shifter operand for arithmetic register shifted encodings. 204class ArithmeticShifterOperand<int width> : AsmOperandClass { 205 let SuperClasses = [ShifterOperand]; 206 let Name = "ArithmeticShifter" # width; 207 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 208 let RenderMethod = "addShifterOperands"; 209 let DiagnosticType = "AddSubRegShift" # width; 210} 211 212def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 213def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 214 215// Shifter operand for logical register shifted encodings. 216class LogicalShifterOperand<int width> : AsmOperandClass { 217 let SuperClasses = [ShifterOperand]; 218 let Name = "LogicalShifter" # width; 219 let PredicateMethod = "isLogicalShifter<" # width # ">"; 220 let RenderMethod = "addShifterOperands"; 221 let DiagnosticType = "AddSubRegShift" # width; 222} 223 224def LogicalShifterOperand32 : LogicalShifterOperand<32>; 225def LogicalShifterOperand64 : LogicalShifterOperand<64>; 226 227// Shifter operand for logical vector 128/64-bit shifted encodings. 228def LogicalVecShifterOperand : AsmOperandClass { 229 let SuperClasses = [ShifterOperand]; 230 let Name = "LogicalVecShifter"; 231 let RenderMethod = "addShifterOperands"; 232} 233def LogicalVecHalfWordShifterOperand : AsmOperandClass { 234 let SuperClasses = [LogicalVecShifterOperand]; 235 let Name = "LogicalVecHalfWordShifter"; 236 let RenderMethod = "addShifterOperands"; 237} 238 239// The "MSL" shifter on the vector MOVI instruction. 240def MoveVecShifterOperand : AsmOperandClass { 241 let SuperClasses = [ShifterOperand]; 242 let Name = "MoveVecShifter"; 243 let RenderMethod = "addShifterOperands"; 244} 245 246// Extend operand for arithmetic encodings. 247def ExtendOperand : AsmOperandClass { 248 let Name = "Extend"; 249 let DiagnosticType = "AddSubRegExtendLarge"; 250} 251def ExtendOperand64 : AsmOperandClass { 252 let SuperClasses = [ExtendOperand]; 253 let Name = "Extend64"; 254 let DiagnosticType = "AddSubRegExtendSmall"; 255} 256// 'extend' that's a lsl of a 64-bit register. 257def ExtendOperandLSL64 : AsmOperandClass { 258 let SuperClasses = [ExtendOperand]; 259 let Name = "ExtendLSL64"; 260 let RenderMethod = "addExtend64Operands"; 261 let DiagnosticType = "AddSubRegExtendLarge"; 262} 263 264// 8-bit floating-point immediate encodings. 265def FPImmOperand : AsmOperandClass { 266 let Name = "FPImm"; 267 let ParserMethod = "tryParseFPImm<true>"; 268 let DiagnosticType = "InvalidFPImm"; 269} 270 271def CondCode : AsmOperandClass { 272 let Name = "CondCode"; 273 let DiagnosticType = "InvalidCondCode"; 274} 275 276// A 32-bit register pasrsed as 64-bit 277def GPR32as64Operand : AsmOperandClass { 278 let Name = "GPR32as64"; 279 let ParserMethod = 280 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 281} 282def GPR32as64 : RegisterOperand<GPR32> { 283 let ParserMatchClass = GPR32as64Operand; 284} 285 286// A 64-bit register pasrsed as 32-bit 287def GPR64as32Operand : AsmOperandClass { 288 let Name = "GPR64as32"; 289 let ParserMethod = 290 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 291} 292def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 293 let ParserMatchClass = GPR64as32Operand; 294} 295 296// 8-bit immediate for AdvSIMD where 64-bit values of the form: 297// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 298// are encoded as the eight bit value 'abcdefgh'. 299def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 300 301class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 302 let Name = "UImm" # Width # "s" # Scale; 303 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 304 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 305 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 306} 307 308class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 309 let Name = "SImm" # Width # "s" # Scale; 310 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 311 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 312 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 313} 314 315//===----------------------------------------------------------------------===// 316// Operand Definitions. 317// 318 319// ADR[P] instruction labels. 320def AdrpOperand : AsmOperandClass { 321 let Name = "AdrpLabel"; 322 let ParserMethod = "tryParseAdrpLabel"; 323 let DiagnosticType = "InvalidLabel"; 324} 325def adrplabel : Operand<i64> { 326 let EncoderMethod = "getAdrLabelOpValue"; 327 let PrintMethod = "printAdrAdrpLabel"; 328 let ParserMatchClass = AdrpOperand; 329 let OperandType = "OPERAND_PCREL"; 330} 331 332def AdrOperand : AsmOperandClass { 333 let Name = "AdrLabel"; 334 let ParserMethod = "tryParseAdrLabel"; 335 let DiagnosticType = "InvalidLabel"; 336} 337def adrlabel : Operand<i64> { 338 let EncoderMethod = "getAdrLabelOpValue"; 339 let PrintMethod = "printAdrAdrpLabel"; 340 let ParserMatchClass = AdrOperand; 341 let OperandType = "OPERAND_PCREL"; 342} 343 344class SImmOperand<int width> : AsmOperandClass { 345 let Name = "SImm" # width; 346 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 347 let RenderMethod = "addImmOperands"; 348 let PredicateMethod = "isSImm<" # width # ">"; 349} 350 351class AsmImmRange<int Low, int High> : AsmOperandClass { 352 let Name = "Imm" # Low # "_" # High; 353 let DiagnosticType = "InvalidImm" # Low # "_" # High; 354 let RenderMethod = "addImmOperands"; 355 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 356} 357 358// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 359def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 360def simm10Scaled : Operand<i64> { 361 let ParserMatchClass = SImm10s8Operand; 362 let DecoderMethod = "DecodeSImm<10>"; 363 let PrintMethod = "printImmScale<8>"; 364} 365 366def simm9s16 : Operand<i64> { 367 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 368 let DecoderMethod = "DecodeSImm<9>"; 369 let PrintMethod = "printImmScale<16>"; 370} 371 372// uimm6 predicate - True if the immediate is in the range [0, 63]. 373def UImm6Operand : AsmOperandClass { 374 let Name = "UImm6"; 375 let DiagnosticType = "InvalidImm0_63"; 376} 377 378def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 379 let ParserMatchClass = UImm6Operand; 380} 381 382def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 383 let ParserMatchClass = AsmImmRange<0, 65535>; 384} 385 386def SImm9Operand : SImmOperand<9>; 387def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 388 let ParserMatchClass = SImm9Operand; 389 let DecoderMethod = "DecodeSImm<9>"; 390} 391 392// imm0_255 predicate - True if the immediate is in the range [0,255]. 393def Imm0_255Operand : AsmImmRange<0,255>; 394 395def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> { 396 let ParserMatchClass = Imm0_255Operand; 397} 398def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> { 399 let ParserMatchClass = Imm0_255Operand; 400} 401 402def SImm8Operand : SImmOperand<8>; 403def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> { 404 let ParserMatchClass = SImm8Operand; 405 let DecoderMethod = "DecodeSImm<8>"; 406} 407def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> { 408 let ParserMatchClass = SImm8Operand; 409 let DecoderMethod = "DecodeSImm<8>"; 410} 411 412def SImm6Operand : SImmOperand<6>; 413def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 414 let ParserMatchClass = SImm6Operand; 415 let DecoderMethod = "DecodeSImm<6>"; 416} 417 418def SImm5Operand : SImmOperand<5>; 419def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 420 let ParserMatchClass = SImm5Operand; 421 let DecoderMethod = "DecodeSImm<5>"; 422} 423 424def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 425 let ParserMatchClass = SImm5Operand; 426 let DecoderMethod = "DecodeSImm<5>"; 427} 428 429def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> { 430 let ParserMatchClass = SImm5Operand; 431 let DecoderMethod = "DecodeSImm<5>"; 432 let PrintMethod = "printSImm<8>"; 433} 434 435def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> { 436 let ParserMatchClass = SImm5Operand; 437 let DecoderMethod = "DecodeSImm<5>"; 438 let PrintMethod = "printSImm<16>"; 439} 440 441// simm7sN predicate - True if the immediate is a multiple of N in the range 442// [-64 * N, 63 * N]. 443 444def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 445def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 446def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 447 448def simm7s4 : Operand<i32> { 449 let ParserMatchClass = SImm7s4Operand; 450 let PrintMethod = "printImmScale<4>"; 451} 452 453def simm7s8 : Operand<i32> { 454 let ParserMatchClass = SImm7s8Operand; 455 let PrintMethod = "printImmScale<8>"; 456} 457 458def simm7s16 : Operand<i32> { 459 let ParserMatchClass = SImm7s16Operand; 460 let PrintMethod = "printImmScale<16>"; 461} 462 463def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>; 464 465def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>; 466def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>; 467def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>; 468def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>; 469def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>; 470 471def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>; 472def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>; 473 474def UImmS1XForm : SDNodeXForm<imm, [{ 475 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64); 476}]>; 477def UImmS2XForm : SDNodeXForm<imm, [{ 478 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64); 479}]>; 480def UImmS4XForm : SDNodeXForm<imm, [{ 481 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64); 482}]>; 483def UImmS8XForm : SDNodeXForm<imm, [{ 484 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64); 485}]>; 486 487// uimm5sN predicate - True if the immediate is a multiple of N in the range 488// [0 * N, 32 * N]. 489def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 490def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 491def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 492 493def uimm5s2 : Operand<i64>, ImmLeaf<i64, 494 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 495 UImmS2XForm> { 496 let ParserMatchClass = UImm5s2Operand; 497 let PrintMethod = "printImmScale<2>"; 498} 499def uimm5s4 : Operand<i64>, ImmLeaf<i64, 500 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 501 UImmS4XForm> { 502 let ParserMatchClass = UImm5s4Operand; 503 let PrintMethod = "printImmScale<4>"; 504} 505def uimm5s8 : Operand<i64>, ImmLeaf<i64, 506 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 507 UImmS8XForm> { 508 let ParserMatchClass = UImm5s8Operand; 509 let PrintMethod = "printImmScale<8>"; 510} 511 512// tuimm5sN predicate - similiar to uimm5sN, but use TImmLeaf (TargetConstant) 513// instead of ImmLeaf (Constant) 514def tuimm5s2 : Operand<i64>, TImmLeaf<i64, 515 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }], 516 UImmS2XForm> { 517 let ParserMatchClass = UImm5s2Operand; 518 let PrintMethod = "printImmScale<2>"; 519} 520def tuimm5s4 : Operand<i64>, TImmLeaf<i64, 521 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }], 522 UImmS4XForm> { 523 let ParserMatchClass = UImm5s4Operand; 524 let PrintMethod = "printImmScale<4>"; 525} 526def tuimm5s8 : Operand<i64>, TImmLeaf<i64, 527 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }], 528 UImmS8XForm> { 529 let ParserMatchClass = UImm5s8Operand; 530 let PrintMethod = "printImmScale<8>"; 531} 532 533// uimm6sN predicate - True if the immediate is a multiple of N in the range 534// [0 * N, 64 * N]. 535def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 536def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 537def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 538def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 539def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 540 541def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 542 let ParserMatchClass = UImm6s1Operand; 543} 544def uimm6s2 : Operand<i64>, ImmLeaf<i64, 545[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 546 let PrintMethod = "printImmScale<2>"; 547 let ParserMatchClass = UImm6s2Operand; 548} 549def uimm6s4 : Operand<i64>, ImmLeaf<i64, 550[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 551 let PrintMethod = "printImmScale<4>"; 552 let ParserMatchClass = UImm6s4Operand; 553} 554def uimm6s8 : Operand<i64>, ImmLeaf<i64, 555[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 556 let PrintMethod = "printImmScale<8>"; 557 let ParserMatchClass = UImm6s8Operand; 558} 559def uimm6s16 : Operand<i64>, ImmLeaf<i64, 560[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 561 let PrintMethod = "printImmScale<16>"; 562 let ParserMatchClass = UImm6s16Operand; 563} 564 565def SImmS2XForm : SDNodeXForm<imm, [{ 566 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64); 567}]>; 568def SImmS3XForm : SDNodeXForm<imm, [{ 569 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64); 570}]>; 571def SImmS4XForm : SDNodeXForm<imm, [{ 572 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64); 573}]>; 574def SImmS16XForm : SDNodeXForm<imm, [{ 575 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); 576}]>; 577def SImmS32XForm : SDNodeXForm<imm, [{ 578 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64); 579}]>; 580 581// simm6sN predicate - True if the immediate is a multiple of N in the range 582// [-32 * N, 31 * N]. 583def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 584def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 585 let ParserMatchClass = SImm6s1Operand; 586 let DecoderMethod = "DecodeSImm<6>"; 587} 588 589// simm4sN predicate - True if the immediate is a multiple of N in the range 590// [ -8* N, 7 * N]. 591def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 592def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 593def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 594def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 595def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 596def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>; 597 598def simm4s1 : Operand<i64>, ImmLeaf<i64, 599[{ return Imm >=-8 && Imm <= 7; }]> { 600 let ParserMatchClass = SImm4s1Operand; 601 let DecoderMethod = "DecodeSImm<4>"; 602} 603 604def simm4s2 : Operand<i64>, ImmLeaf<i64, 605[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> { 606 let PrintMethod = "printImmScale<2>"; 607 let ParserMatchClass = SImm4s2Operand; 608 let DecoderMethod = "DecodeSImm<4>"; 609} 610 611def simm4s3 : Operand<i64>, ImmLeaf<i64, 612[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> { 613 let PrintMethod = "printImmScale<3>"; 614 let ParserMatchClass = SImm4s3Operand; 615 let DecoderMethod = "DecodeSImm<4>"; 616} 617 618def simm4s4 : Operand<i64>, ImmLeaf<i64, 619[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> { 620 let PrintMethod = "printImmScale<4>"; 621 let ParserMatchClass = SImm4s4Operand; 622 let DecoderMethod = "DecodeSImm<4>"; 623} 624def simm4s16 : Operand<i64>, ImmLeaf<i64, 625[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> { 626 let PrintMethod = "printImmScale<16>"; 627 let ParserMatchClass = SImm4s16Operand; 628 let DecoderMethod = "DecodeSImm<4>"; 629} 630def simm4s32 : Operand<i64>, ImmLeaf<i64, 631[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> { 632 let PrintMethod = "printImmScale<32>"; 633 let ParserMatchClass = SImm4s32Operand; 634 let DecoderMethod = "DecodeSImm<4>"; 635} 636 637def Imm1_8Operand : AsmImmRange<1, 8>; 638def Imm1_16Operand : AsmImmRange<1, 16>; 639def Imm1_32Operand : AsmImmRange<1, 32>; 640def Imm1_64Operand : AsmImmRange<1, 64>; 641 642class BranchTarget<int N> : AsmOperandClass { 643 let Name = "BranchTarget" # N; 644 let DiagnosticType = "InvalidLabel"; 645 let PredicateMethod = "isBranchTarget<" # N # ">"; 646} 647 648class PCRelLabel<int N> : BranchTarget<N> { 649 let Name = "PCRelLabel" # N; 650} 651 652def BranchTarget14Operand : BranchTarget<14>; 653def BranchTarget26Operand : BranchTarget<26>; 654def PCRelLabel19Operand : PCRelLabel<19>; 655 656def MovWSymbolG3AsmOperand : AsmOperandClass { 657 let Name = "MovWSymbolG3"; 658 let RenderMethod = "addImmOperands"; 659} 660 661def movw_symbol_g3 : Operand<i32> { 662 let ParserMatchClass = MovWSymbolG3AsmOperand; 663} 664 665def MovWSymbolG2AsmOperand : AsmOperandClass { 666 let Name = "MovWSymbolG2"; 667 let RenderMethod = "addImmOperands"; 668} 669 670def movw_symbol_g2 : Operand<i32> { 671 let ParserMatchClass = MovWSymbolG2AsmOperand; 672} 673 674def MovWSymbolG1AsmOperand : AsmOperandClass { 675 let Name = "MovWSymbolG1"; 676 let RenderMethod = "addImmOperands"; 677} 678 679def movw_symbol_g1 : Operand<i32> { 680 let ParserMatchClass = MovWSymbolG1AsmOperand; 681} 682 683def MovWSymbolG0AsmOperand : AsmOperandClass { 684 let Name = "MovWSymbolG0"; 685 let RenderMethod = "addImmOperands"; 686} 687 688def movw_symbol_g0 : Operand<i32> { 689 let ParserMatchClass = MovWSymbolG0AsmOperand; 690} 691 692class fixedpoint_i32<ValueType FloatVT> 693 : Operand<FloatVT>, 694 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 695 let EncoderMethod = "getFixedPointScaleOpValue"; 696 let DecoderMethod = "DecodeFixedPointScaleImm32"; 697 let ParserMatchClass = Imm1_32Operand; 698} 699 700class fixedpoint_i64<ValueType FloatVT> 701 : Operand<FloatVT>, 702 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 703 let EncoderMethod = "getFixedPointScaleOpValue"; 704 let DecoderMethod = "DecodeFixedPointScaleImm64"; 705 let ParserMatchClass = Imm1_64Operand; 706} 707 708def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 709def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 710def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 711 712def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 713def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 714def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 715 716class fixedpoint_recip_i32<ValueType FloatVT> 717 : Operand<FloatVT>, 718 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> { 719 let EncoderMethod = "getFixedPointScaleOpValue"; 720 let DecoderMethod = "DecodeFixedPointScaleImm32"; 721} 722 723class fixedpoint_recip_i64<ValueType FloatVT> 724 : Operand<FloatVT>, 725 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<64>", [fpimm, ld]> { 726 let EncoderMethod = "getFixedPointScaleOpValue"; 727 let DecoderMethod = "DecodeFixedPointScaleImm64"; 728} 729 730def fixedpoint_recip_f16_i32 : fixedpoint_recip_i32<f16>; 731def fixedpoint_recip_f32_i32 : fixedpoint_recip_i32<f32>; 732def fixedpoint_recip_f64_i32 : fixedpoint_recip_i32<f64>; 733 734def fixedpoint_recip_f16_i64 : fixedpoint_recip_i64<f16>; 735def fixedpoint_recip_f32_i64 : fixedpoint_recip_i64<f32>; 736def fixedpoint_recip_f64_i64 : fixedpoint_recip_i64<f64>; 737 738def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 739 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 740}]> { 741 let EncoderMethod = "getVecShiftR8OpValue"; 742 let DecoderMethod = "DecodeVecShiftR8Imm"; 743 let ParserMatchClass = Imm1_8Operand; 744} 745def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 746 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 747}]> { 748 let EncoderMethod = "getVecShiftR16OpValue"; 749 let DecoderMethod = "DecodeVecShiftR16Imm"; 750 let ParserMatchClass = Imm1_16Operand; 751} 752def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 753 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 754}]> { 755 let EncoderMethod = "getVecShiftR16OpValue"; 756 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 757 let ParserMatchClass = Imm1_8Operand; 758} 759def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 760 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 761}]> { 762 let EncoderMethod = "getVecShiftR32OpValue"; 763 let DecoderMethod = "DecodeVecShiftR32Imm"; 764 let ParserMatchClass = Imm1_32Operand; 765} 766def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 767 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 768}]> { 769 let EncoderMethod = "getVecShiftR32OpValue"; 770 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 771 let ParserMatchClass = Imm1_16Operand; 772} 773def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 774 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 775}]> { 776 let EncoderMethod = "getVecShiftR64OpValue"; 777 let DecoderMethod = "DecodeVecShiftR64Imm"; 778 let ParserMatchClass = Imm1_64Operand; 779} 780def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 781 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 782}]> { 783 let EncoderMethod = "getVecShiftR64OpValue"; 784 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 785 let ParserMatchClass = Imm1_32Operand; 786} 787 788// Same as vecshiftR#N, but use TargetConstant (TimmLeaf) instead of Constant 789// (ImmLeaf) 790def tvecshiftR8 : Operand<i32>, TImmLeaf<i32, [{ 791 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 792}]> { 793 let EncoderMethod = "getVecShiftR8OpValue"; 794 let DecoderMethod = "DecodeVecShiftR8Imm"; 795 let ParserMatchClass = Imm1_8Operand; 796} 797def tvecshiftR16 : Operand<i32>, TImmLeaf<i32, [{ 798 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 799}]> { 800 let EncoderMethod = "getVecShiftR16OpValue"; 801 let DecoderMethod = "DecodeVecShiftR16Imm"; 802 let ParserMatchClass = Imm1_16Operand; 803} 804def tvecshiftR32 : Operand<i32>, TImmLeaf<i32, [{ 805 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 806}]> { 807 let EncoderMethod = "getVecShiftR32OpValue"; 808 let DecoderMethod = "DecodeVecShiftR32Imm"; 809 let ParserMatchClass = Imm1_32Operand; 810} 811def tvecshiftR64 : Operand<i32>, TImmLeaf<i32, [{ 812 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 813}]> { 814 let EncoderMethod = "getVecShiftR64OpValue"; 815 let DecoderMethod = "DecodeVecShiftR64Imm"; 816 let ParserMatchClass = Imm1_64Operand; 817} 818 819def Imm0_0Operand : AsmImmRange<0, 0>; 820def Imm0_1Operand : AsmImmRange<0, 1>; 821def Imm1_1Operand : AsmImmRange<1, 1>; 822def Imm0_3Operand : AsmImmRange<0, 3>; 823def Imm1_3Operand : AsmImmRange<1, 3>; 824def Imm0_7Operand : AsmImmRange<0, 7>; 825def Imm1_7Operand : AsmImmRange<1, 7>; 826def Imm0_15Operand : AsmImmRange<0, 15>; 827def Imm0_31Operand : AsmImmRange<0, 31>; 828def Imm0_63Operand : AsmImmRange<0, 63>; 829 830def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 831 return (((uint32_t)Imm) < 8); 832}]> { 833 let EncoderMethod = "getVecShiftL8OpValue"; 834 let DecoderMethod = "DecodeVecShiftL8Imm"; 835 let ParserMatchClass = Imm0_7Operand; 836} 837def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 838 return (((uint32_t)Imm) < 16); 839}]> { 840 let EncoderMethod = "getVecShiftL16OpValue"; 841 let DecoderMethod = "DecodeVecShiftL16Imm"; 842 let ParserMatchClass = Imm0_15Operand; 843} 844def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 845 return (((uint32_t)Imm) < 32); 846}]> { 847 let EncoderMethod = "getVecShiftL32OpValue"; 848 let DecoderMethod = "DecodeVecShiftL32Imm"; 849 let ParserMatchClass = Imm0_31Operand; 850} 851def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 852 return (((uint32_t)Imm) < 64); 853}]> { 854 let EncoderMethod = "getVecShiftL64OpValue"; 855 let DecoderMethod = "DecodeVecShiftL64Imm"; 856 let ParserMatchClass = Imm0_63Operand; 857} 858 859// Same as vecshiftL#N, but use TargetConstant (TimmLeaf) instead of Constant 860// (ImmLeaf) 861def tvecshiftL8 : Operand<i32>, TImmLeaf<i32, [{ 862 return (((uint32_t)Imm) < 8); 863}]> { 864 let EncoderMethod = "getVecShiftL8OpValue"; 865 let DecoderMethod = "DecodeVecShiftL8Imm"; 866 let ParserMatchClass = Imm0_7Operand; 867} 868def tvecshiftL16 : Operand<i32>, TImmLeaf<i32, [{ 869 return (((uint32_t)Imm) < 16); 870}]> { 871 let EncoderMethod = "getVecShiftL16OpValue"; 872 let DecoderMethod = "DecodeVecShiftL16Imm"; 873 let ParserMatchClass = Imm0_15Operand; 874} 875def tvecshiftL32 : Operand<i32>, TImmLeaf<i32, [{ 876 return (((uint32_t)Imm) < 32); 877}]> { 878 let EncoderMethod = "getVecShiftL32OpValue"; 879 let DecoderMethod = "DecodeVecShiftL32Imm"; 880 let ParserMatchClass = Imm0_31Operand; 881} 882def tvecshiftL64 : Operand<i32>, TImmLeaf<i32, [{ 883 return (((uint32_t)Imm) < 64); 884}]> { 885 let EncoderMethod = "getVecShiftL64OpValue"; 886 let DecoderMethod = "DecodeVecShiftL64Imm"; 887 let ParserMatchClass = Imm0_63Operand; 888} 889 890// Crazy immediate formats used by 32-bit and 64-bit logical immediate 891// instructions for splatting repeating bit patterns across the immediate. 892def logical_imm32_XFORM : SDNodeXForm<imm, [{ 893 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 894 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 895}]>; 896def logical_imm64_XFORM : SDNodeXForm<imm, [{ 897 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 898 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 899}]>; 900 901def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 902 GISDNodeXFormEquiv<logical_imm32_XFORM>; 903def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 904 GISDNodeXFormEquiv<logical_imm64_XFORM>; 905 906let DiagnosticType = "LogicalSecondSource" in { 907 def LogicalImm32Operand : AsmOperandClass { 908 let Name = "LogicalImm32"; 909 let PredicateMethod = "isLogicalImm<int32_t>"; 910 let RenderMethod = "addLogicalImmOperands<int32_t>"; 911 } 912 def LogicalImm64Operand : AsmOperandClass { 913 let Name = "LogicalImm64"; 914 let PredicateMethod = "isLogicalImm<int64_t>"; 915 let RenderMethod = "addLogicalImmOperands<int64_t>"; 916 } 917 def LogicalImm32NotOperand : AsmOperandClass { 918 let Name = "LogicalImm32Not"; 919 let PredicateMethod = "isLogicalImm<int32_t>"; 920 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 921 } 922 def LogicalImm64NotOperand : AsmOperandClass { 923 let Name = "LogicalImm64Not"; 924 let PredicateMethod = "isLogicalImm<int64_t>"; 925 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 926 } 927} 928 929def Imm0_127Operand : AsmImmRange<0, 127>; 930 931let OperandType = "OPERAND_IMMEDIATE" in { 932 933def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 934 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 935}], logical_imm32_XFORM> { 936 let PrintMethod = "printLogicalImm<int32_t>"; 937 let ParserMatchClass = LogicalImm32Operand; 938} 939def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 940 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 941}], logical_imm64_XFORM> { 942 let PrintMethod = "printLogicalImm<int64_t>"; 943 let ParserMatchClass = LogicalImm64Operand; 944} 945def logical_imm32_not : Operand<i32> { 946 let ParserMatchClass = LogicalImm32NotOperand; 947} 948def logical_imm64_not : Operand<i64> { 949 let ParserMatchClass = LogicalImm64NotOperand; 950} 951 952// immXX_0_65535 predicates - True if the immediate is in the range [0,65535]. 953let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 954def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{ 955 return ((uint32_t)Imm) < 65536; 956}]>; 957 958def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{ 959 return ((uint64_t)Imm) < 65536; 960}]>; 961 962def imm64_0_65535 : Operand<i64>, ImmLeaf<i64, [{ 963 return ((uint64_t)Imm) < 65536; 964}]>; 965} // ParserMatchClass 966 967def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 968 return ((uint32_t)Imm) < 256; 969}]> { 970 let ParserMatchClass = Imm0_255Operand; 971 let PrintMethod = "printImm"; 972} 973 974// imm0_127 predicate - True if the immediate is in the range [0,127] 975def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 976 return ((uint32_t)Imm) < 128; 977}]> { 978 let ParserMatchClass = Imm0_127Operand; 979 let PrintMethod = "printImm"; 980} 981 982def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{ 983 return ((uint64_t)Imm) < 128; 984}]> { 985 let ParserMatchClass = Imm0_127Operand; 986 let PrintMethod = "printImm"; 987} 988 989// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 990// for all shift-amounts. 991 992// imm0_63 predicate - True if the immediate is in the range [0,63] 993def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 994 return ((uint64_t)Imm) < 64; 995}]> { 996 let ParserMatchClass = Imm0_63Operand; 997} 998 999def timm0_63 : Operand<i64>, TImmLeaf<i64, [{ 1000 return ((uint64_t)Imm) < 64; 1001}]> { 1002 let ParserMatchClass = Imm0_63Operand; 1003} 1004 1005// imm0_31 predicate - True if the immediate is in the range [0,31] 1006def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 1007 return ((uint64_t)Imm) < 32; 1008}]> { 1009 let ParserMatchClass = Imm0_31Operand; 1010} 1011 1012// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf) 1013// instead of Constant (ImmLeaf) 1014def timm0_31 : Operand<i64>, TImmLeaf<i64, [{ 1015 return ((uint64_t)Imm) < 32; 1016}]> { 1017 let ParserMatchClass = Imm0_31Operand; 1018} 1019 1020// True if the 32-bit immediate is in the range [0,31] 1021def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 1022 return ((uint64_t)Imm) < 32; 1023}]> { 1024 let ParserMatchClass = Imm0_31Operand; 1025} 1026 1027// imm0_1 predicate - True if the immediate is in the range [0,1] 1028def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 1029 return ((uint64_t)Imm) < 2; 1030}]> { 1031 let ParserMatchClass = Imm0_1Operand; 1032} 1033 1034// timm0_1 - as above, but use TargetConstant (TImmLeaf) 1035def timm0_1 : Operand<i64>, TImmLeaf<i64, [{ 1036 return ((uint64_t)Imm) < 2; 1037}]> { 1038 let ParserMatchClass = Imm0_1Operand; 1039} 1040 1041// timm32_0_0 predicate - True if the 32-bit immediate is in the range [0,0] 1042def timm32_0_0 : Operand<i32>, TImmLeaf<i32, [{ 1043 return ((uint32_t)Imm) == 0; 1044}]> { 1045 let ParserMatchClass = Imm0_0Operand; 1046} 1047 1048// timm32_0_1 predicate - True if the 32-bit immediate is in the range [0,1] 1049def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{ 1050 return ((uint32_t)Imm) < 2; 1051}]> { 1052 let ParserMatchClass = Imm0_1Operand; 1053} 1054 1055// timm32_1_1 - True if the 32-bit immediate is in the range [1,1] 1056def timm32_1_1 : Operand<i32>, TImmLeaf<i32, [{ 1057 return ((uint32_t)Imm) == 1; 1058}]> { 1059 let ParserMatchClass = Imm1_1Operand; 1060} 1061 1062// timm32_1_3 predicate - True if the 32-bit immediate is in the range [1,3] 1063def timm32_1_3 : Operand<i32>, TImmLeaf<i32, [{ 1064 return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 4; 1065}]> { 1066 let ParserMatchClass = Imm1_3Operand; 1067} 1068 1069// imm0_15 predicate - True if the immediate is in the range [0,15] 1070def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 1071 return ((uint64_t)Imm) < 16; 1072}]> { 1073 let ParserMatchClass = Imm0_15Operand; 1074} 1075 1076// imm0_7 predicate - True if the immediate is in the range [0,7] 1077def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 1078 return ((uint64_t)Imm) < 8; 1079}]> { 1080 let ParserMatchClass = Imm0_7Operand; 1081} 1082 1083// imm0_3 predicate - True if the immediate is in the range [0,3] 1084def imm0_3 : Operand<i64>, ImmLeaf<i64, [{ 1085 return ((uint64_t)Imm) < 4; 1086}]> { 1087 let ParserMatchClass = Imm0_3Operand; 1088} 1089 1090// timm32_0_3 predicate - True if the 32-bit immediate is in the range [0,3] 1091def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{ 1092 return ((uint32_t)Imm) < 4; 1093}]> { 1094 let ParserMatchClass = Imm0_3Operand; 1095} 1096 1097// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7] 1098def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{ 1099 return ((uint32_t)Imm) < 8; 1100}]> { 1101 let ParserMatchClass = Imm0_7Operand; 1102} 1103 1104// timm32_1_7 predicate - True if the 32-bit immediate is in the range [1,7] 1105def timm32_1_7 : Operand<i32>, TImmLeaf<i32, [{ 1106 return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 8; 1107}]> { 1108 let ParserMatchClass = Imm1_7Operand; 1109} 1110 1111// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1112def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 1113 return ((uint32_t)Imm) < 16; 1114}]> { 1115 let ParserMatchClass = Imm0_15Operand; 1116} 1117 1118// timm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 1119def timm32_0_15 : Operand<i32>, TImmLeaf<i32, [{ 1120 return ((uint32_t)Imm) < 16; 1121}]> { 1122 let ParserMatchClass = Imm0_15Operand; 1123} 1124 1125// timm32_0_31 predicate - True if the 32-bit immediate is in the range [0,31] 1126def timm32_0_31 : Operand<i32>, TImmLeaf<i32, [{ 1127 return ((uint32_t)Imm) < 32; 1128}]> { 1129 let ParserMatchClass = Imm0_31Operand; 1130} 1131 1132// timm32_0_255 predicate - True if the 32-bit immediate is in the range [0,255] 1133def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{ 1134 return ((uint32_t)Imm) < 256; 1135}]> { 1136 let ParserMatchClass = Imm0_255Operand; 1137} 1138 1139} // let OperandType = "OPERAND_IMMEDIATE" 1140 1141// An arithmetic shifter operand: 1142// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 1143// {5-0} - imm6 1144class arith_shift<ValueType Ty, int width> : Operand<Ty> { 1145 let PrintMethod = "printShifter"; 1146 let ParserMatchClass = !cast<AsmOperandClass>( 1147 "ArithmeticShifterOperand" # width); 1148} 1149 1150def arith_shift32 : arith_shift<i32, 32>; 1151def arith_shift64 : arith_shift<i64, 64>; 1152 1153class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 1154 : Operand<Ty>, 1155 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 1156 let PrintMethod = "printShiftedRegister"; 1157 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 1158} 1159 1160def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 1161def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 1162 1163def gi_arith_shifted_reg32 : 1164 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 1165 GIComplexPatternEquiv<arith_shifted_reg32>; 1166 1167def gi_arith_shifted_reg64 : 1168 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 1169 GIComplexPatternEquiv<arith_shifted_reg64>; 1170 1171// An arithmetic shifter operand: 1172// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 1173// {5-0} - imm6 1174class logical_shift<int width> : Operand<i32> { 1175 let PrintMethod = "printShifter"; 1176 let ParserMatchClass = !cast<AsmOperandClass>( 1177 "LogicalShifterOperand" # width); 1178} 1179 1180def logical_shift32 : logical_shift<32>; 1181def logical_shift64 : logical_shift<64>; 1182 1183class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 1184 : Operand<Ty>, 1185 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 1186 let PrintMethod = "printShiftedRegister"; 1187 let MIOperandInfo = (ops regclass, shiftop); 1188} 1189 1190def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 1191def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 1192 1193def gi_logical_shifted_reg32 : 1194 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 1195 GIComplexPatternEquiv<logical_shifted_reg32>; 1196 1197def gi_logical_shifted_reg64 : 1198 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 1199 GIComplexPatternEquiv<logical_shifted_reg64>; 1200 1201// A logical vector shifter operand: 1202// {7-6} - shift type: 00 = lsl 1203// {5-0} - imm6: #0, #8, #16, or #24 1204def logical_vec_shift : Operand<i32> { 1205 let PrintMethod = "printShifter"; 1206 let EncoderMethod = "getVecShifterOpValue"; 1207 let ParserMatchClass = LogicalVecShifterOperand; 1208} 1209 1210// A logical vector half-word shifter operand: 1211// {7-6} - shift type: 00 = lsl 1212// {5-0} - imm6: #0 or #8 1213def logical_vec_hw_shift : Operand<i32> { 1214 let PrintMethod = "printShifter"; 1215 let EncoderMethod = "getVecShifterOpValue"; 1216 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 1217} 1218 1219// A vector move shifter operand: 1220// {0} - imm1: #8 or #16 1221def move_vec_shift : Operand<i32> { 1222 let PrintMethod = "printShifter"; 1223 let EncoderMethod = "getMoveVecShifterOpValue"; 1224 let ParserMatchClass = MoveVecShifterOperand; 1225} 1226 1227let DiagnosticType = "AddSubSecondSource" in { 1228 def AddSubImmOperand : AsmOperandClass { 1229 let Name = "AddSubImm"; 1230 let ParserMethod = "tryParseImmWithOptionalShift"; 1231 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 1232 } 1233 def AddSubImmNegOperand : AsmOperandClass { 1234 let Name = "AddSubImmNeg"; 1235 let ParserMethod = "tryParseImmWithOptionalShift"; 1236 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 1237 } 1238} 1239// An ADD/SUB immediate shifter operand: 1240// second operand: 1241// {7-6} - shift type: 00 = lsl 1242// {5-0} - imm6: #0 or #12 1243class addsub_shifted_imm<ValueType Ty> 1244 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 1245 let PrintMethod = "printAddSubImm"; 1246 let EncoderMethod = "getAddSubImmOpValue"; 1247 let ParserMatchClass = AddSubImmOperand; 1248 let MIOperandInfo = (ops i32imm, i32imm); 1249} 1250 1251class addsub_shifted_imm_neg<ValueType Ty> 1252 : Operand<Ty> { 1253 let EncoderMethod = "getAddSubImmOpValue"; 1254 let ParserMatchClass = AddSubImmNegOperand; 1255 let MIOperandInfo = (ops i32imm, i32imm); 1256} 1257 1258def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 1259def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 1260def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 1261def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 1262 1263def gi_addsub_shifted_imm32 : 1264 GIComplexOperandMatcher<s32, "selectArithImmed">, 1265 GIComplexPatternEquiv<addsub_shifted_imm32>; 1266 1267def gi_addsub_shifted_imm64 : 1268 GIComplexOperandMatcher<s64, "selectArithImmed">, 1269 GIComplexPatternEquiv<addsub_shifted_imm64>; 1270 1271class neg_addsub_shifted_imm<ValueType Ty> 1272 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 1273 let PrintMethod = "printAddSubImm"; 1274 let EncoderMethod = "getAddSubImmOpValue"; 1275 let ParserMatchClass = AddSubImmOperand; 1276 let MIOperandInfo = (ops i32imm, i32imm); 1277} 1278 1279def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 1280def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 1281 1282def gi_neg_addsub_shifted_imm32 : 1283 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 1284 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 1285 1286def gi_neg_addsub_shifted_imm64 : 1287 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 1288 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 1289 1290// An extend operand: 1291// {5-3} - extend type 1292// {2-0} - imm3 1293def arith_extend : Operand<i32> { 1294 let PrintMethod = "printArithExtend"; 1295 let ParserMatchClass = ExtendOperand; 1296} 1297def arith_extend64 : Operand<i32> { 1298 let PrintMethod = "printArithExtend"; 1299 let ParserMatchClass = ExtendOperand64; 1300} 1301 1302// 'extend' that's a lsl of a 64-bit register. 1303def arith_extendlsl64 : Operand<i32> { 1304 let PrintMethod = "printArithExtend"; 1305 let ParserMatchClass = ExtendOperandLSL64; 1306} 1307 1308class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 1309 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1310 let PrintMethod = "printExtendedRegister"; 1311 let MIOperandInfo = (ops GPR32, arith_extend); 1312} 1313 1314class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 1315 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 1316 let PrintMethod = "printExtendedRegister"; 1317 let MIOperandInfo = (ops GPR32, arith_extend64); 1318} 1319 1320def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 1321def gi_arith_extended_reg32_i32 : 1322 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 1323 GIComplexPatternEquiv<arith_extended_reg32_i32>; 1324 1325def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 1326def gi_arith_extended_reg32_i64 : 1327 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1328 GIComplexPatternEquiv<arith_extended_reg32_i64>; 1329 1330def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 1331def gi_arith_extended_reg32to64_i64 : 1332 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 1333 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 1334 1335def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>; 1336 1337// Floating-point immediate. 1338 1339def fpimm16XForm : SDNodeXForm<fpimm, [{ 1340 APFloat InVal = N->getValueAPF(); 1341 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 1342 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1343 }]>; 1344 1345def fpimm32XForm : SDNodeXForm<fpimm, [{ 1346 APFloat InVal = N->getValueAPF(); 1347 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 1348 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1349 }]>; 1350 1351def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{ 1352 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF() 1353 .bitcastToAPInt() 1354 .getZExtValue()); 1355 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1356 }]>; 1357 1358def fpimm64XForm : SDNodeXForm<fpimm, [{ 1359 APFloat InVal = N->getValueAPF(); 1360 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 1361 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1362 }]>; 1363 1364def fpimm16 : Operand<f16>, 1365 FPImmLeaf<f16, [{ 1366 return AArch64_AM::getFP16Imm(Imm) != -1; 1367 }], fpimm16XForm> { 1368 let ParserMatchClass = FPImmOperand; 1369 let PrintMethod = "printFPImmOperand"; 1370} 1371 1372def fpimmbf16 : Operand<bf16>, 1373 FPImmLeaf<bf16, [{ 1374 return AArch64_AM::getFP16Imm(Imm) != -1; 1375 }], fpimm16XForm>; 1376 1377def fpimm32 : Operand<f32>, 1378 FPImmLeaf<f32, [{ 1379 return AArch64_AM::getFP32Imm(Imm) != -1; 1380 }], fpimm32XForm> { 1381 let ParserMatchClass = FPImmOperand; 1382 let PrintMethod = "printFPImmOperand"; 1383} 1384 1385def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{ 1386 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue(); 1387 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc); 1388 }], fpimm32SIMDModImmType4XForm> { 1389} 1390 1391def fpimm64 : Operand<f64>, 1392 FPImmLeaf<f64, [{ 1393 return AArch64_AM::getFP64Imm(Imm) != -1; 1394 }], fpimm64XForm> { 1395 let ParserMatchClass = FPImmOperand; 1396 let PrintMethod = "printFPImmOperand"; 1397} 1398 1399def fpimm8 : Operand<i32> { 1400 let ParserMatchClass = FPImmOperand; 1401 let PrintMethod = "printFPImmOperand"; 1402} 1403 1404def fpimm0 : FPImmLeaf<fAny, [{ 1405 return Imm.isExactlyValue(+0.0); 1406}]>; 1407 1408def fpimm_minus0 : FPImmLeaf<fAny, [{ 1409 return Imm.isExactlyValue(-0.0); 1410}]>; 1411 1412def fpimm_half : FPImmLeaf<fAny, [{ 1413 return Imm.isExactlyValue(+0.5); 1414}]>; 1415 1416def fpimm_one : FPImmLeaf<fAny, [{ 1417 return Imm.isExactlyValue(+1.0); 1418}]>; 1419 1420def fpimm_two : FPImmLeaf<fAny, [{ 1421 return Imm.isExactlyValue(+2.0); 1422}]>; 1423 1424def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">, 1425 GISDNodeXFormEquiv<fpimm16XForm>; 1426def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 1427 GISDNodeXFormEquiv<fpimm32XForm>; 1428def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, 1429 GISDNodeXFormEquiv<fpimm64XForm>; 1430def gi_fpimm32SIMDModImmType4 : 1431 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, 1432 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>; 1433 1434// Vector lane operands 1435class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1436 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1437 let DiagnosticType = "Invalid" # Name; 1438 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1439 let RenderMethod = "addVectorIndexOperands"; 1440} 1441 1442class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc> 1443 : Operand<ty> { 1444 let ParserMatchClass = mc; 1445 let PrintMethod = "printVectorIndex"; 1446} 1447 1448multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> { 1449 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>; 1450 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>; 1451} 1452 1453def VectorIndex0Operand : AsmVectorIndex<0, 0>; 1454def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1455def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1456def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1457def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1458def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1459 1460let OperandNamespace = "AArch64" in { 1461 let OperandType = "OPERAND_IMPLICIT_IMM_0" in { 1462 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand, 1463 [{ return ((uint64_t)Imm) == 0; }]>; 1464 defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand, 1465 [{ return ((uint32_t)Imm) == 0; }]>; 1466 } 1467} 1468defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand, 1469 [{ return ((uint64_t)Imm) == 1; }]>; 1470defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand, 1471 [{ return ((uint64_t)Imm) < 16; }]>; 1472defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand, 1473 [{ return ((uint64_t)Imm) < 8; }]>; 1474defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand, 1475 [{ return ((uint64_t)Imm) < 4; }]>; 1476defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand, 1477 [{ return ((uint64_t)Imm) < 2; }]>; 1478 1479defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand, 1480 [{ return ((uint64_t)Imm) == 1; }]>; 1481defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand, 1482 [{ return ((uint64_t)Imm) < 16; }]>; 1483defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand, 1484 [{ return ((uint64_t)Imm) < 8; }]>; 1485defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand, 1486 [{ return ((uint64_t)Imm) < 4; }]>; 1487defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand, 1488 [{ return ((uint64_t)Imm) < 2; }]>; 1489 1490def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1491def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1492def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1493def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1494def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1495 1496defm sve_elm_idx_extdup_b 1497 : VectorIndex<i64, SVEVectorIndexExtDupBOperand, 1498 [{ return ((uint64_t)Imm) < 64; }]>; 1499defm sve_elm_idx_extdup_h 1500 : VectorIndex<i64, SVEVectorIndexExtDupHOperand, 1501 [{ return ((uint64_t)Imm) < 32; }]>; 1502defm sve_elm_idx_extdup_s 1503 : VectorIndex<i64, SVEVectorIndexExtDupSOperand, 1504 [{ return ((uint64_t)Imm) < 16; }]>; 1505defm sve_elm_idx_extdup_d 1506 : VectorIndex<i64, SVEVectorIndexExtDupDOperand, 1507 [{ return ((uint64_t)Imm) < 8; }]>; 1508defm sve_elm_idx_extdup_q 1509 : VectorIndex<i64, SVEVectorIndexExtDupQOperand, 1510 [{ return ((uint64_t)Imm) < 4; }]>; 1511 1512def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{ 1513 return ((uint32_t)Imm) == 0; 1514}]> { 1515 let ParserMatchClass = Imm0_0Operand; 1516 let PrintMethod = "printMatrixIndex"; 1517 let OperandNamespace = "AArch64"; 1518 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1519} 1520def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{ 1521 return ((uint32_t)Imm) <= 1; 1522}]> { 1523 let ParserMatchClass = Imm0_1Operand; 1524 let PrintMethod = "printMatrixIndex"; 1525} 1526def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{ 1527 return ((uint32_t)Imm) <= 3; 1528}]> { 1529 let ParserMatchClass = Imm0_3Operand; 1530 let PrintMethod = "printMatrixIndex"; 1531} 1532def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{ 1533 return ((uint32_t)Imm) <= 7; 1534}]> { 1535 let ParserMatchClass = Imm0_7Operand; 1536 let PrintMethod = "printMatrixIndex"; 1537} 1538def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{ 1539 return ((uint32_t)Imm) <= 15; 1540}]> { 1541 let ParserMatchClass = Imm0_15Operand; 1542 let PrintMethod = "printMatrixIndex"; 1543} 1544 1545// SME2 vector select offset operands 1546 1547// uimm3s8 predicate 1548// True if the immediate is a multiple of 8 in the range [0,56]. 1549def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>; 1550 1551def uimm3s8 : Operand<i64>, ImmLeaf<i64, 1552[{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> { 1553 let PrintMethod = "printMatrixIndex<8>"; 1554 let ParserMatchClass = UImm3s8Operand; 1555} 1556 1557class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass { 1558 let Name = "UImm" # Width # "s" # Scale # "Range"; 1559 let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width; 1560 let RenderMethod = "addImmScaledRangeOperands<" # Scale # ">"; 1561 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ", " # OffsetVal # ", /*IsRange=*/true>"; 1562 let ParserMethod = "tryParseImmRange"; 1563} 1564 1565// Implicit immediate ranges 0:1 and 0:3, scale has no meaning 1566// since the immediate is zero 1567def UImm0s2RangeOperand : UImmScaledMemoryIndexedRange<0, 2, 1>; 1568def UImm0s4RangeOperand : UImmScaledMemoryIndexedRange<0, 4, 3>; 1569 1570def UImm1s2RangeOperand : UImmScaledMemoryIndexedRange<1, 2, 1>; 1571def UImm1s4RangeOperand : UImmScaledMemoryIndexedRange<1, 4, 3>; 1572def UImm2s2RangeOperand : UImmScaledMemoryIndexedRange<2, 2, 1>; 1573def UImm2s4RangeOperand : UImmScaledMemoryIndexedRange<2, 4, 3>; 1574def UImm3s2RangeOperand : UImmScaledMemoryIndexedRange<3, 2, 1>; 1575 1576def uimm0s2range : Operand<i64>, ImmLeaf<i64, 1577[{ return Imm == 0; }], UImmS1XForm> { 1578 let PrintMethod = "printImmRangeScale<2, 1>"; 1579 let ParserMatchClass = UImm0s2RangeOperand; 1580 let OperandNamespace = "AArch64"; 1581 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1582} 1583 1584def uimm0s4range : Operand<i64>, ImmLeaf<i64, 1585[{ return Imm == 0; }], UImmS1XForm> { 1586 let PrintMethod = "printImmRangeScale<4, 3>"; 1587 let ParserMatchClass = UImm0s4RangeOperand; 1588 let OperandNamespace = "AArch64"; 1589 let OperandType = "OPERAND_IMPLICIT_IMM_0"; 1590} 1591 1592def uimm1s2range : Operand<i64>, ImmLeaf<i64, 1593[{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> { 1594 let PrintMethod = "printImmRangeScale<2, 1>"; 1595 let ParserMatchClass = UImm1s2RangeOperand; 1596} 1597 1598def uimm1s4range : Operand<i64>, ImmLeaf<i64, 1599[{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> { 1600 let PrintMethod = "printImmRangeScale<4, 3>"; 1601 let ParserMatchClass = UImm1s4RangeOperand; 1602} 1603 1604def uimm2s2range : Operand<i64>, ImmLeaf<i64, 1605[{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> { 1606 let PrintMethod = "printImmRangeScale<2, 1>"; 1607 let ParserMatchClass = UImm2s2RangeOperand; 1608} 1609 1610def uimm2s4range : Operand<i64>, ImmLeaf<i64, 1611[{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> { 1612 let PrintMethod = "printImmRangeScale<4, 3>"; 1613 let ParserMatchClass = UImm2s4RangeOperand; 1614} 1615 1616def uimm3s2range : Operand<i64>, ImmLeaf<i64, 1617[{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> { 1618 let PrintMethod = "printImmRangeScale<2, 1>"; 1619 let ParserMatchClass = UImm3s2RangeOperand; 1620} 1621 1622 1623// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1624// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1625// are encoded as the eight bit value 'abcdefgh'. 1626def simdimmtype10 : Operand<i32>, 1627 FPImmLeaf<f64, [{ 1628 return AArch64_AM::isAdvSIMDModImmType10( 1629 Imm.bitcastToAPInt().getZExtValue()); 1630 }], SDNodeXForm<fpimm, [{ 1631 APFloat InVal = N->getValueAPF(); 1632 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1633 .bitcastToAPInt() 1634 .getZExtValue()); 1635 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1636 }]>> { 1637 let ParserMatchClass = SIMDImmType10Operand; 1638 let PrintMethod = "printSIMDType10Operand"; 1639} 1640 1641 1642//--- 1643// System management 1644//--- 1645 1646// Base encoding for system instruction operands. 1647let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1648class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1649 list<dag> pattern = []> 1650 : I<oops, iops, asm, operands, "", pattern> { 1651 let Inst{31-22} = 0b1101010100; 1652 let Inst{21} = L; 1653} 1654 1655// System instructions which do not have an Rt register. 1656class SimpleSystemI<bit L, dag iops, string asm, string operands, 1657 list<dag> pattern = []> 1658 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1659 let Inst{4-0} = 0b11111; 1660} 1661 1662// System instructions which have an Rt register. 1663class RtSystemI<bit L, dag oops, dag iops, string asm, string operands, 1664 list<dag> pattern = []> 1665 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1666 Sched<[WriteSys]> { 1667 bits<5> Rt; 1668 let Inst{4-0} = Rt; 1669} 1670 1671// System instructions for transactional memory extension 1672class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1673 string asm, string operands, list<dag> pattern> 1674 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1675 Sched<[WriteSys]> { 1676 let Inst{20-12} = 0b000110011; 1677 let Inst{11-8} = CRm; 1678 let Inst{7-5} = op2; 1679 let DecoderMethod = ""; 1680 1681 let mayLoad = 1; 1682 let mayStore = 1; 1683} 1684 1685// System instructions for transactional memory - single input operand 1686class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1687 : TMBaseSystemI<0b1, CRm, 0b011, 1688 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1689 bits<5> Rt; 1690 let Inst{4-0} = Rt; 1691} 1692 1693// System instructions that pass a register argument 1694// This class assumes the register is for input rather than output. 1695class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm, 1696 list<dag> pattern = []> 1697 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> { 1698 let Inst{20-12} = 0b000110001; 1699 let Inst{11-8} = CRm; 1700 let Inst{7-5} = Op2; 1701} 1702 1703// System instructions for transactional memory - no operand 1704class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1705 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1706 let Inst{4-0} = 0b11111; 1707} 1708 1709// System instructions for exit from transactions 1710class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1711 : I<(outs), (ins timm64_0_65535:$imm), asm, "\t$imm", "", pattern>, 1712 Sched<[WriteSys]> { 1713 bits<16> imm; 1714 let Inst{31-24} = 0b11010100; 1715 let Inst{23-21} = op1; 1716 let Inst{20-5} = imm; 1717 let Inst{4-0} = 0b00000; 1718} 1719 1720// Hint instructions that take both a CRm and a 3-bit immediate. 1721// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1722// model patterns with sufficiently fine granularity 1723let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1724 class HintI<string mnemonic> 1725 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1726 [(int_aarch64_hint imm0_127:$imm)]>, 1727 Sched<[WriteHint]> { 1728 bits <7> imm; 1729 let Inst{20-12} = 0b000110010; 1730 let Inst{11-5} = imm; 1731 } 1732 1733// System instructions taking a single literal operand which encodes into 1734// CRm. op2 differentiates the opcodes. 1735def BarrierAsmOperand : AsmOperandClass { 1736 let Name = "Barrier"; 1737 let ParserMethod = "tryParseBarrierOperand"; 1738} 1739def barrier_op : Operand<i32> { 1740 let PrintMethod = "printBarrierOption"; 1741 let ParserMatchClass = BarrierAsmOperand; 1742} 1743def BarriernXSAsmOperand : AsmOperandClass { 1744 let Name = "BarriernXS"; 1745 let ParserMethod = "tryParseBarriernXSOperand"; 1746} 1747def barrier_nxs_op : Operand<i32> { 1748 let PrintMethod = "printBarriernXSOption"; 1749 let ParserMatchClass = BarriernXSAsmOperand; 1750} 1751class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1752 list<dag> pattern = []> 1753 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1754 Sched<[WriteBarrier]> { 1755 bits<4> CRm; 1756 let Inst{20-12} = 0b000110011; 1757 let Inst{11-8} = CRm; 1758 let Inst{7-5} = opc; 1759} 1760 1761class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1762 : SimpleSystemI<0, (ins), asm, "", pattern>, 1763 Sched<[WriteHint]> { 1764 bits<4> CRm; 1765 let CRm = 0b0011; 1766 let Inst{31-12} = 0b11010101000000110010; 1767 let Inst{11-8} = CRm; 1768 let Inst{7-5} = op2; 1769 let Inst{4-0} = 0b11111; 1770} 1771 1772// MRS/MSR system instructions. These have different operand classes because 1773// a different subset of registers can be accessed through each instruction. 1774def MRSSystemRegisterOperand : AsmOperandClass { 1775 let Name = "MRSSystemRegister"; 1776 let ParserMethod = "tryParseSysReg"; 1777 let DiagnosticType = "MRS"; 1778} 1779// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1780def mrs_sysreg_op : Operand<i32> { 1781 let ParserMatchClass = MRSSystemRegisterOperand; 1782 let DecoderMethod = "DecodeMRSSystemRegister"; 1783 let PrintMethod = "printMRSSystemRegister"; 1784} 1785 1786def MSRSystemRegisterOperand : AsmOperandClass { 1787 let Name = "MSRSystemRegister"; 1788 let ParserMethod = "tryParseSysReg"; 1789 let DiagnosticType = "MSR"; 1790} 1791def msr_sysreg_op : Operand<i32> { 1792 let ParserMatchClass = MSRSystemRegisterOperand; 1793 let DecoderMethod = "DecodeMSRSystemRegister"; 1794 let PrintMethod = "printMSRSystemRegister"; 1795} 1796 1797def PSBHintOperand : AsmOperandClass { 1798 let Name = "PSBHint"; 1799 let ParserMethod = "tryParsePSBHint"; 1800} 1801def psbhint_op : Operand<i32> { 1802 let ParserMatchClass = PSBHintOperand; 1803 let PrintMethod = "printPSBHintOp"; 1804 let MCOperandPredicate = [{ 1805 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1806 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1807 if (!MCOp.isImm()) 1808 return false; 1809 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1810 }]; 1811} 1812 1813def BTIHintOperand : AsmOperandClass { 1814 let Name = "BTIHint"; 1815 let ParserMethod = "tryParseBTIHint"; 1816} 1817def btihint_op : Operand<i32> { 1818 let ParserMatchClass = BTIHintOperand; 1819 let PrintMethod = "printBTIHintOp"; 1820 let MCOperandPredicate = [{ 1821 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1822 if (!MCOp.isImm()) 1823 return false; 1824 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr; 1825 }]; 1826} 1827 1828class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1829 "mrs", "\t$Rt, $systemreg"> { 1830 bits<16> systemreg; 1831 let Inst{20-5} = systemreg; 1832 let DecoderNamespace = "Fallback"; 1833 // The MRS is set as a NZCV setting instruction. Not all MRS instructions 1834 // require doing this. The alternative was to explicitly model each one, but 1835 // it feels like it is unnecessary because it seems there are no negative 1836 // consequences setting these flags for all. 1837 let Defs = [NZCV]; 1838} 1839 1840// FIXME: Some of these def NZCV, others don't. Best way to model that? 1841// Explicitly modeling each of the system register as a register class 1842// would do it, but feels like overkill at this point. 1843class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1844 "msr", "\t$systemreg, $Rt"> { 1845 bits<16> systemreg; 1846 let Inst{20-5} = systemreg; 1847 let DecoderNamespace = "Fallback"; 1848} 1849 1850def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1851 let Name = "SystemPStateFieldWithImm0_15"; 1852 let ParserMethod = "tryParseSysReg"; 1853} 1854def pstatefield4_op : Operand<i32> { 1855 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1856 let PrintMethod = "printSystemPStateField"; 1857 let MCOperandPredicate = [{ 1858 if (!MCOp.isImm()) 1859 return false; 1860 return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr; 1861 }]; 1862} 1863 1864// Instructions to modify PSTATE, no input reg 1865let Defs = [NZCV] in 1866class PstateWriteSimple<dag iops, string asm, string operands> 1867 : SimpleSystemI<0, iops, asm, operands> { 1868 1869 let Inst{20-19} = 0b00; 1870 let Inst{15-12} = 0b0100; 1871} 1872 1873class MSRpstateImm0_15 1874 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1875 "\t$pstatefield, $imm">, 1876 Sched<[WriteSys]> { 1877 1878 bits<6> pstatefield; 1879 bits<4> imm; 1880 let Inst{18-16} = pstatefield{5-3}; 1881 let Inst{11-8} = imm; 1882 let Inst{7-5} = pstatefield{2-0}; 1883 1884 let DecoderMethod = "DecodeSystemPStateImm0_15Instruction"; 1885 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1886 // Fail the decoder should attempt to decode the instruction as MSRI. 1887 let hasCompleteDecoder = false; 1888} 1889 1890def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1891 let Name = "SystemPStateFieldWithImm0_1"; 1892 let ParserMethod = "tryParseSysReg"; 1893} 1894def pstatefield1_op : Operand<i32> { 1895 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1896 let PrintMethod = "printSystemPStateField"; 1897 let MCOperandPredicate = [{ 1898 if (!MCOp.isImm()) 1899 return false; 1900 return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr; 1901 }]; 1902} 1903 1904class MSRpstateImm0_1 1905 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1906 "\t$pstatefield, $imm">, 1907 Sched<[WriteSys]> { 1908 1909 bits<9> pstatefield; 1910 bit imm; 1911 let Inst{18-16} = pstatefield{5-3}; 1912 let Inst{11-9} = pstatefield{8-6}; 1913 let Inst{8} = imm; 1914 let Inst{7-5} = pstatefield{2-0}; 1915 1916 let DecoderMethod = "DecodeSystemPStateImm0_1Instruction"; 1917 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1918 // Fail the decoder should attempt to decode the instruction as MSRI. 1919 let hasCompleteDecoder = false; 1920 let DecoderNamespace = "Fallback"; 1921} 1922 1923// SYS and SYSL generic system instructions. 1924def SysCRAsmOperand : AsmOperandClass { 1925 let Name = "SysCR"; 1926 let ParserMethod = "tryParseSysCROperand"; 1927} 1928 1929def sys_cr_op : Operand<i32> { 1930 let PrintMethod = "printSysCROperand"; 1931 let ParserMatchClass = SysCRAsmOperand; 1932} 1933 1934class SystemXtI<bit L, string asm> 1935 : RtSystemI<L, (outs), 1936 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1937 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1938 bits<3> op1; 1939 bits<4> Cn; 1940 bits<4> Cm; 1941 bits<3> op2; 1942 let Inst{20-19} = 0b01; 1943 let Inst{18-16} = op1; 1944 let Inst{15-12} = Cn; 1945 let Inst{11-8} = Cm; 1946 let Inst{7-5} = op2; 1947} 1948 1949class SystemLXtI<bit L, string asm> 1950 : RtSystemI<L, (outs), 1951 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1952 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1953 bits<3> op1; 1954 bits<4> Cn; 1955 bits<4> Cm; 1956 bits<3> op2; 1957 let Inst{20-19} = 0b01; 1958 let Inst{18-16} = op1; 1959 let Inst{15-12} = Cn; 1960 let Inst{11-8} = Cm; 1961 let Inst{7-5} = op2; 1962} 1963 1964def RangePrefetchOperand : AsmOperandClass { 1965 let Name = "RangePrefetch"; 1966 let ParserMethod = "tryParseRPRFMOperand"; 1967 let PredicateMethod = "isPrefetch"; 1968 let RenderMethod = "addPrefetchOperands"; 1969} 1970 1971def rprfop : Operand<i32>, TImmLeaf<i32, [{ 1972 return (((uint32_t)Imm) <= 63); 1973 }]> { 1974 let PrintMethod = "printRPRFMOperand"; 1975 let ParserMatchClass = RangePrefetchOperand; 1976} 1977 1978// Branch (register) instructions: 1979// 1980// case opc of 1981// 0001 blr 1982// 0000 br 1983// 0101 dret 1984// 0100 eret 1985// 0010 ret 1986// otherwise UNDEFINED 1987class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1988 string operands, list<dag> pattern> 1989 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1990 let Inst{31-25} = 0b1101011; 1991 let Inst{24-21} = opc; 1992 let Inst{20-16} = 0b11111; 1993 let Inst{15-10} = 0b000000; 1994 let Inst{4-0} = 0b00000; 1995} 1996 1997class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1998 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1999 bits<5> Rn; 2000 let Inst{9-5} = Rn; 2001} 2002 2003let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 2004class SpecialReturn<bits<4> opc, string asm> 2005 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 2006 let Inst{9-5} = 0b11111; 2007} 2008 2009let mayLoad = 1 in 2010class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 2011 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 2012 Sched<[]> { 2013 bits<5> Rn; 2014 bits<5> Rt; 2015 let Inst{31-30} = sz; 2016 let Inst{29-10} = 0b11100010111111110000; 2017 let Inst{9-5} = Rn; 2018 let Inst{4-0} = Rt; 2019} 2020 2021class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 2022 list<dag> pattern> 2023 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 2024 let isAuthenticated = 1; 2025 let Inst{31-25} = 0b1101011; 2026 let Inst{20-11} = 0b1111100001; 2027 let Inst{10} = M; 2028 let Inst{4-0} = 0b11111; 2029} 2030 2031class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 2032 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 2033 bits<5> Rn; 2034 bits<5> Rm; 2035 let Inst{24-22} = 0b100; 2036 let Inst{21} = op; 2037 let Inst{9-5} = Rn; 2038 let Inst{4-0} = Rm; 2039} 2040 2041class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 2042 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 2043 bits<5> Rn; 2044 let Inst{24} = 0; 2045 let Inst{23-21} = opc; 2046 let Inst{9-5} = Rn; 2047} 2048 2049let Uses = [LR,SP] in 2050class AuthReturn<bits<3> op, bits<1> M, string asm> 2051 : AuthBase<M, (outs), (ins), asm, "", []> { 2052 let Inst{24} = 0; 2053 let Inst{23-21} = op; 2054 let Inst{9-0} = 0b1111111111; 2055} 2056 2057let mayLoad = 1 in 2058class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 2059 string operands, string cstr> 2060 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 2061 bits<10> offset; 2062 bits<5> Rn; 2063 bits<5> Rt; 2064 let isAuthenticated = 1; 2065 let Inst{31-24} = 0b11111000; 2066 let Inst{23} = M; 2067 let Inst{22} = offset{9}; 2068 let Inst{21} = 1; 2069 let Inst{20-12} = offset{8-0}; 2070 let Inst{11} = W; 2071 let Inst{10} = 1; 2072 let Inst{9-5} = Rn; 2073 let Inst{4-0} = Rt; 2074 2075 let DecoderMethod = "DecodeAuthLoadInstruction"; 2076} 2077 2078multiclass AuthLoad<bit M, string asm, Operand opr> { 2079 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 2080 (ins GPR64sp:$Rn, opr:$offset), 2081 asm, "\t$Rt, [$Rn, $offset]", "">; 2082 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 2083 (ins GPR64sp:$Rn, opr:$offset), 2084 asm, "\t$Rt, [$Rn, $offset]!", 2085 "$Rn = $wback,@earlyclobber $wback">; 2086 2087 def : InstAlias<asm # "\t$Rt, [$Rn]", 2088 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 2089 2090 def : InstAlias<asm # "\t$Rt, [$wback]!", 2091 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>; 2092} 2093 2094//--- 2095// Conditional branch instruction. 2096//--- 2097 2098// Condition code. 2099// 4-bit immediate. Pretty-printed as <cc> 2100def ccode : Operand<i32> { 2101 let PrintMethod = "printCondCode"; 2102 let ParserMatchClass = CondCode; 2103} 2104def inv_ccode : Operand<i32> { 2105 // AL and NV are invalid in the aliases which use inv_ccode 2106 let PrintMethod = "printInverseCondCode"; 2107 let ParserMatchClass = CondCode; 2108 let MCOperandPredicate = [{ 2109 return MCOp.isImm() && 2110 MCOp.getImm() != AArch64CC::AL && 2111 MCOp.getImm() != AArch64CC::NV; 2112 }]; 2113} 2114 2115// Conditional branch target. 19-bit immediate. The low two bits of the target 2116// offset are implied zero and so are not part of the immediate. 2117def am_brcond : Operand<OtherVT> { 2118 let EncoderMethod = "getCondBranchTargetOpValue"; 2119 let DecoderMethod = "DecodePCRelLabel19"; 2120 let PrintMethod = "printAlignedLabel"; 2121 let ParserMatchClass = PCRelLabel19Operand; 2122 let OperandType = "OPERAND_PCREL"; 2123} 2124 2125class BranchCond<bit bit4, string mnemonic> 2126 : I<(outs), (ins ccode:$cond, am_brcond:$target), 2127 mnemonic, ".$cond\t$target", "", 2128 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { 2129 let isBranch = 1; 2130 let isTerminator = 1; 2131 let Uses = [NZCV]; 2132 2133 bits<4> cond; 2134 bits<19> target; 2135 let Inst{31-24} = 0b01010100; 2136 let Inst{23-5} = target; 2137 let Inst{4} = bit4; 2138 let Inst{3-0} = cond; 2139} 2140 2141//--- 2142// Compare-and-branch instructions. 2143//--- 2144class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 2145 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 2146 asm, "\t$Rt, $target", "", 2147 [(node regtype:$Rt, bb:$target)]>, 2148 Sched<[WriteBr]> { 2149 let isBranch = 1; 2150 let isTerminator = 1; 2151 2152 bits<5> Rt; 2153 bits<19> target; 2154 let Inst{30-25} = 0b011010; 2155 let Inst{24} = op; 2156 let Inst{23-5} = target; 2157 let Inst{4-0} = Rt; 2158} 2159 2160multiclass CmpBranch<bit op, string asm, SDNode node> { 2161 def W : BaseCmpBranch<GPR32, op, asm, node> { 2162 let Inst{31} = 0; 2163 } 2164 def X : BaseCmpBranch<GPR64, op, asm, node> { 2165 let Inst{31} = 1; 2166 } 2167} 2168 2169//--- 2170// Test-bit-and-branch instructions. 2171//--- 2172// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 2173// the target offset are implied zero and so are not part of the immediate. 2174def am_tbrcond : Operand<OtherVT> { 2175 let EncoderMethod = "getTestBranchTargetOpValue"; 2176 let PrintMethod = "printAlignedLabel"; 2177 let ParserMatchClass = BranchTarget14Operand; 2178 let OperandType = "OPERAND_PCREL"; 2179} 2180 2181// AsmOperand classes to emit (or not) special diagnostics 2182def TBZImm0_31Operand : AsmOperandClass { 2183 let Name = "TBZImm0_31"; 2184 let PredicateMethod = "isImmInRange<0,31>"; 2185 let RenderMethod = "addImmOperands"; 2186} 2187def TBZImm32_63Operand : AsmOperandClass { 2188 let Name = "Imm32_63"; 2189 let PredicateMethod = "isImmInRange<32,63>"; 2190 let DiagnosticType = "InvalidImm0_63"; 2191 let RenderMethod = "addImmOperands"; 2192} 2193 2194class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 2195 return (((uint32_t)Imm) < 32); 2196}]> { 2197 let ParserMatchClass = matcher; 2198} 2199 2200def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 2201def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 2202 2203def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 2204 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 2205}]> { 2206 let ParserMatchClass = TBZImm32_63Operand; 2207} 2208 2209class BaseTestBranch<RegisterClass regtype, Operand immtype, 2210 bit op, string asm, SDNode node> 2211 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 2212 asm, "\t$Rt, $bit_off, $target", "", 2213 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 2214 Sched<[WriteBr]> { 2215 let isBranch = 1; 2216 let isTerminator = 1; 2217 2218 bits<5> Rt; 2219 bits<6> bit_off; 2220 bits<14> target; 2221 2222 let Inst{30-25} = 0b011011; 2223 let Inst{24} = op; 2224 let Inst{23-19} = bit_off{4-0}; 2225 let Inst{18-5} = target; 2226 let Inst{4-0} = Rt; 2227 2228 let DecoderMethod = "DecodeTestAndBranch"; 2229} 2230 2231multiclass TestBranch<bit op, string asm, SDNode node> { 2232 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 2233 let Inst{31} = 0; 2234 } 2235 2236 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 2237 let Inst{31} = 1; 2238 } 2239 2240 // Alias X-reg with 0-31 imm to W-Reg. 2241 def : InstAlias<asm # "\t$Rd, $imm, $target", 2242 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 2243 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 2244 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 2245 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 2246 tbz_imm0_31_diag:$imm, bb:$target)>; 2247} 2248 2249//--- 2250// Unconditional branch (immediate) instructions. 2251//--- 2252def am_b_target : Operand<OtherVT> { 2253 let EncoderMethod = "getBranchTargetOpValue"; 2254 let PrintMethod = "printAlignedLabel"; 2255 let ParserMatchClass = BranchTarget26Operand; 2256 let OperandType = "OPERAND_PCREL"; 2257} 2258def am_bl_target : Operand<i64> { 2259 let EncoderMethod = "getBranchTargetOpValue"; 2260 let PrintMethod = "printAlignedLabel"; 2261 let ParserMatchClass = BranchTarget26Operand; 2262 let OperandType = "OPERAND_PCREL"; 2263} 2264 2265class BImm<bit op, dag iops, string asm, list<dag> pattern> 2266 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 2267 bits<26> addr; 2268 let Inst{31} = op; 2269 let Inst{30-26} = 0b00101; 2270 let Inst{25-0} = addr; 2271 2272 let DecoderMethod = "DecodeUnconditionalBranch"; 2273} 2274 2275class BranchImm<bit op, string asm, list<dag> pattern> 2276 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 2277class CallImm<bit op, string asm, list<dag> pattern> 2278 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 2279 2280//--- 2281// Basic one-operand data processing instructions. 2282//--- 2283 2284let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2285class BaseOneOperandData<bit sf, bit S, bits<5> opc2, bits<6> opc, 2286 RegisterClass regtype, string asm, 2287 SDPatternOperator node> 2288 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 2289 [(set regtype:$Rd, (node regtype:$Rn))]>, 2290 Sched<[WriteI, ReadI]> { 2291 bits<5> Rd; 2292 bits<5> Rn; 2293 2294 let Inst{31} = sf; 2295 let Inst{30} = 0b1; 2296 let Inst{29} = S; 2297 let Inst{28-21} = 0b11010110; 2298 let Inst{20-16} = opc2; 2299 let Inst{15-10} = opc; 2300 let Inst{9-5} = Rn; 2301 let Inst{4-0} = Rd; 2302} 2303 2304let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2305multiclass OneOperandData<bits<6> opc, string asm, 2306 SDPatternOperator node = null_frag> { 2307 def Wr : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2308 2309 def Xr : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2310} 2311 2312class OneWRegData<bits<6> opc, string asm, SDPatternOperator node> 2313 : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>; 2314 2315class OneXRegData<bits<6> opc, string asm, SDPatternOperator node> 2316 : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>; 2317 2318class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm, 2319 SDPatternOperator op> 2320 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn", 2321 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>, 2322 Sched<[WriteI, ReadI]> { 2323 bits<5> Rd; 2324 bits<5> Rn; 2325 let Inst{31-15} = 0b11011010110000010; 2326 let Inst{14-12} = opcode_prefix; 2327 let Inst{11-10} = opcode; 2328 let Inst{9-5} = Rn; 2329 let Inst{4-0} = Rd; 2330} 2331 2332class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm, 2333 SDPatternOperator op> 2334 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd", 2335 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>, 2336 Sched<[]> { 2337 bits<5> Rd; 2338 let Inst{31-15} = 0b11011010110000010; 2339 let Inst{14-12} = opcode_prefix; 2340 let Inst{11-10} = opcode; 2341 let Inst{9-5} = 0b11111; 2342 let Inst{4-0} = Rd; 2343} 2344 2345class SignAuthTwoOperand<bits<4> opc, string asm, 2346 SDPatternOperator OpNode> 2347 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 2348 asm, "\t$Rd, $Rn, $Rm", "", 2349 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 2350 Sched<[WriteI, ReadI, ReadI]> { 2351 bits<5> Rd; 2352 bits<5> Rn; 2353 bits<5> Rm; 2354 let Inst{31-21} = 0b10011010110; 2355 let Inst{20-16} = Rm; 2356 let Inst{15-14} = 0b00; 2357 let Inst{13-10} = opc; 2358 let Inst{9-5} = Rn; 2359 let Inst{4-0} = Rd; 2360} 2361 2362class ClearAuth<bits<1> data, string asm> 2363 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> { 2364 bits<5> Rd; 2365 let Inst{31-11} = 0b110110101100000101000; 2366 let Inst{10} = data; 2367 let Inst{9-5} = 0b11111; 2368 let Inst{4-0} = Rd; 2369} 2370 2371// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2372class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2373 : I<(outs), iops, asm, ops, "", []>, 2374 Sched<[WriteI, ReadI, ReadI]> { 2375 let Uses = [NZCV]; 2376 let Defs = [NZCV]; 2377 bits<5> Rn; 2378 let Inst{31} = sf; 2379 let Inst{30-15} = 0b0111010000000000; 2380 let Inst{14} = sz; 2381 let Inst{13-10} = 0b0010; 2382 let Inst{9-5} = Rn; 2383 let Inst{4-0} = 0b01101; 2384} 2385 2386class FlagRotate<dag iops, string asm, string ops> 2387 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2388 bits<6> imm; 2389 bits<4> mask; 2390 let Inst{20-15} = imm; 2391 let Inst{13-10} = 0b0001; 2392 let Inst{4} = 0b0; 2393 let Inst{3-0} = mask; 2394} 2395 2396//--- 2397// Basic two-operand data processing instructions. 2398//--- 2399class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2400 list<dag> pattern> 2401 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2402 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2403 Sched<[WriteI, ReadI, ReadI]> { 2404 let Uses = [NZCV]; 2405 bits<5> Rd; 2406 bits<5> Rn; 2407 bits<5> Rm; 2408 let Inst{30} = isSub; 2409 let Inst{28-21} = 0b11010000; 2410 let Inst{20-16} = Rm; 2411 let Inst{15-10} = 0; 2412 let Inst{9-5} = Rn; 2413 let Inst{4-0} = Rd; 2414} 2415 2416class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2417 SDNode OpNode> 2418 : BaseBaseAddSubCarry<isSub, regtype, asm, 2419 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2420 2421class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2422 SDNode OpNode> 2423 : BaseBaseAddSubCarry<isSub, regtype, asm, 2424 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2425 (implicit NZCV)]> { 2426 let Defs = [NZCV]; 2427} 2428 2429multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2430 SDNode OpNode, SDNode OpNode_setflags> { 2431 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2432 let Inst{31} = 0; 2433 let Inst{29} = 0; 2434 } 2435 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2436 let Inst{31} = 1; 2437 let Inst{29} = 0; 2438 } 2439 2440 // Sets flags. 2441 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2442 OpNode_setflags> { 2443 let Inst{31} = 0; 2444 let Inst{29} = 1; 2445 } 2446 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2447 OpNode_setflags> { 2448 let Inst{31} = 1; 2449 let Inst{29} = 1; 2450 } 2451} 2452 2453class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype, 2454 string asm, SDPatternOperator OpNode, 2455 RegisterClass in1regtype = regtype, 2456 RegisterClass in2regtype = regtype> 2457 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2458 asm, "\t$Rd, $Rn, $Rm", "", 2459 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2460 bits<5> Rd; 2461 bits<5> Rn; 2462 bits<5> Rm; 2463 let Inst{31} = sf; 2464 let Inst{30} = 0b0; 2465 let Inst{29} = S; 2466 let Inst{28-21} = 0b11010110; 2467 let Inst{20-16} = Rm; 2468 let Inst{15-10} = opc; 2469 let Inst{9-5} = Rn; 2470 let Inst{4-0} = Rd; 2471} 2472 2473class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm, 2474 SDPatternOperator OpNode> 2475 : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> { 2476 let Inst{10} = isSigned; 2477} 2478 2479multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2480 def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>, 2481 Sched<[WriteID32, ReadID, ReadID]>; 2482 2483 def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>, 2484 Sched<[WriteID64, ReadID, ReadID]>; 2485} 2486 2487class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm, 2488 SDPatternOperator OpNode = null_frag> 2489 : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>, 2490 Sched<[WriteIS, ReadI]> { 2491 let Inst{11-10} = shift_type; 2492} 2493 2494multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2495 def Wr : BaseShift<0b0, shift_type, GPR32, asm>; 2496 2497 def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>; 2498 2499 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2500 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2501 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2502 2503 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2504 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2505 2506 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2507 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2508 2509 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2510 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2511 2512 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2513 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2514 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2515 2516 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2517 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2518 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2519} 2520 2521class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2522 : InstAlias<asm#"\t$dst, $src1, $src2", 2523 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2524 2525class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2526 RegisterClass addtype, string asm, 2527 list<dag> pattern> 2528 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2529 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2530 bits<5> Rd; 2531 bits<5> Rn; 2532 bits<5> Rm; 2533 bits<5> Ra; 2534 let Inst{30-24} = 0b0011011; 2535 let Inst{23-21} = opc; 2536 let Inst{20-16} = Rm; 2537 let Inst{15} = isSub; 2538 let Inst{14-10} = Ra; 2539 let Inst{9-5} = Rn; 2540 let Inst{4-0} = Rd; 2541} 2542 2543multiclass MulAccum<bit isSub, string asm> { 2544 // MADD/MSUB generation is decided by MachineCombiner.cpp 2545 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2546 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2547 let Inst{31} = 0; 2548 } 2549 2550 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2551 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2552 let Inst{31} = 1; 2553 } 2554} 2555 2556class WideMulAccum<bit isSub, bits<3> opc, string asm, 2557 SDNode AccNode, SDNode ExtNode> 2558 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2559 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2560 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2561 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2562 let Inst{31} = 1; 2563} 2564 2565class MulHi<bits<3> opc, string asm, SDNode OpNode> 2566 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2567 asm, "\t$Rd, $Rn, $Rm", "", 2568 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2569 Sched<[WriteIM64, ReadIM, ReadIM]> { 2570 bits<5> Rd; 2571 bits<5> Rn; 2572 bits<5> Rm; 2573 let Inst{31-24} = 0b10011011; 2574 let Inst{23-21} = opc; 2575 let Inst{20-16} = Rm; 2576 let Inst{15} = 0; 2577 let Inst{9-5} = Rn; 2578 let Inst{4-0} = Rd; 2579 2580 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2581 // (i.e. all bits 1) but is ignored by the processor. 2582 let PostEncoderMethod = "fixMulHigh"; 2583} 2584 2585class MulAccumWAlias<string asm, Instruction inst> 2586 : InstAlias<asm#"\t$dst, $src1, $src2", 2587 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2588class MulAccumXAlias<string asm, Instruction inst> 2589 : InstAlias<asm#"\t$dst, $src1, $src2", 2590 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2591class WideMulAccumAlias<string asm, Instruction inst> 2592 : InstAlias<asm#"\t$dst, $src1, $src2", 2593 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2594 2595class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2596 SDPatternOperator OpNode, string asm> 2597 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2598 asm, "\t$Rd, $Rn, $Rm", "", 2599 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2600 Sched<[WriteISReg, ReadI, ReadISReg]> { 2601 bits<5> Rd; 2602 bits<5> Rn; 2603 bits<5> Rm; 2604 2605 let Inst{31} = sf; 2606 let Inst{30-21} = 0b0011010110; 2607 let Inst{20-16} = Rm; 2608 let Inst{15-13} = 0b010; 2609 let Inst{12} = C; 2610 let Inst{11-10} = sz; 2611 let Inst{9-5} = Rn; 2612 let Inst{4-0} = Rd; 2613 let Predicates = [HasCRC]; 2614} 2615 2616//--- 2617// Address generation. 2618//--- 2619 2620class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2621 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2622 pattern>, 2623 Sched<[WriteI]> { 2624 bits<5> Xd; 2625 bits<21> label; 2626 let Inst{31} = page; 2627 let Inst{30-29} = label{1-0}; 2628 let Inst{28-24} = 0b10000; 2629 let Inst{23-5} = label{20-2}; 2630 let Inst{4-0} = Xd; 2631 2632 let DecoderMethod = "DecodeAdrInstruction"; 2633} 2634 2635//--- 2636// Move immediate. 2637//--- 2638 2639def movimm32_imm : Operand<i32> { 2640 let ParserMatchClass = AsmImmRange<0, 65535>; 2641 let EncoderMethod = "getMoveWideImmOpValue"; 2642 let PrintMethod = "printImm"; 2643} 2644def movimm32_shift : Operand<i32> { 2645 let PrintMethod = "printShifter"; 2646 let ParserMatchClass = MovImm32ShifterOperand; 2647} 2648def movimm64_shift : Operand<i32> { 2649 let PrintMethod = "printShifter"; 2650 let ParserMatchClass = MovImm64ShifterOperand; 2651} 2652 2653let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2654class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2655 string asm> 2656 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2657 asm, "\t$Rd, $imm$shift", "", []>, 2658 Sched<[WriteImm]> { 2659 bits<5> Rd; 2660 bits<16> imm; 2661 bits<6> shift; 2662 let Inst{30-29} = opc; 2663 let Inst{28-23} = 0b100101; 2664 let Inst{22-21} = shift{5-4}; 2665 let Inst{20-5} = imm; 2666 let Inst{4-0} = Rd; 2667 2668 let DecoderMethod = "DecodeMoveImmInstruction"; 2669} 2670 2671multiclass MoveImmediate<bits<2> opc, string asm> { 2672 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2673 let Inst{31} = 0; 2674 } 2675 2676 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2677 let Inst{31} = 1; 2678 } 2679} 2680 2681let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2682class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2683 string asm> 2684 : I<(outs regtype:$Rd), 2685 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2686 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2687 Sched<[WriteI, ReadI]> { 2688 bits<5> Rd; 2689 bits<16> imm; 2690 bits<6> shift; 2691 let Inst{30-29} = opc; 2692 let Inst{28-23} = 0b100101; 2693 let Inst{22-21} = shift{5-4}; 2694 let Inst{20-5} = imm; 2695 let Inst{4-0} = Rd; 2696 2697 let DecoderMethod = "DecodeMoveImmInstruction"; 2698} 2699 2700multiclass InsertImmediate<bits<2> opc, string asm> { 2701 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2702 let Inst{31} = 0; 2703 } 2704 2705 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2706 let Inst{31} = 1; 2707 } 2708} 2709 2710//--- 2711// Add/Subtract 2712//--- 2713 2714class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2715 string asm_inst, string asm_ops, 2716 dag inputs, dag pattern> 2717 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2718 Sched<[WriteI, ReadI]> { 2719 bits<5> Rd; 2720 bits<5> Rn; 2721 let Inst{30} = isSub; 2722 let Inst{29} = setFlags; 2723 let Inst{28-24} = 0b10001; 2724 let Inst{9-5} = Rn; 2725 let Inst{4-0} = Rd; 2726} 2727 2728class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2729 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2730 string asm_inst, SDPatternOperator OpNode> 2731 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2732 (ins srcRegtype:$Rn, immtype:$imm), 2733 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2734 bits<14> imm; 2735 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2736 let Inst{21-10} = imm{11-0}; 2737 let DecoderMethod = "DecodeAddSubImmShift"; 2738} 2739 2740class BaseAddSubRegPseudo<RegisterClass regtype, 2741 SDPatternOperator OpNode> 2742 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2743 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2744 Sched<[WriteI, ReadI, ReadI]>; 2745 2746class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2747 arith_shifted_reg shifted_regtype, string asm, 2748 SDPatternOperator OpNode> 2749 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 2750 asm, "\t$Rd, $Rn, $Rm_and_shift", "", 2751 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>, 2752 Sched<[WriteISReg, ReadI, ReadISReg]> { 2753 bits<5> Rd; 2754 bits<5> Rn; 2755 bits<5> Rm; 2756 bits<8> shift; 2757 let Inst{30} = isSub; 2758 let Inst{29} = setFlags; 2759 let Inst{28-24} = 0b01011; 2760 let Inst{23-22} = shift{7-6}; 2761 let Inst{21} = 0; 2762 let Inst{20-16} = Rm; 2763 let Inst{15-10} = shift{5-0}; 2764 let Inst{9-5} = Rn; 2765 let Inst{4-0} = Rd; 2766 2767 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2768} 2769 2770class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2771 RegisterClass src1Regtype, Operand src2Regtype, 2772 string asm, SDPatternOperator OpNode> 2773 : I<(outs dstRegtype:$Rd), 2774 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend), 2775 asm, "\t$Rd, $Rn, $Rm_and_extend", "", 2776 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>, 2777 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2778 bits<5> Rd; 2779 bits<5> Rn; 2780 bits<5> Rm; 2781 bits<6> extend; 2782 let Inst{30} = isSub; 2783 let Inst{29} = setFlags; 2784 let Inst{28-24} = 0b01011; 2785 let Inst{23-21} = 0b001; 2786 let Inst{20-16} = Rm; 2787 let Inst{15-13} = extend{5-3}; 2788 let Inst{12-10} = extend{2-0}; 2789 let Inst{9-5} = Rn; 2790 let Inst{4-0} = Rd; 2791 2792 let DecoderMethod = "DecodeAddSubERegInstruction"; 2793} 2794 2795let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2796class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2797 RegisterClass src1Regtype, RegisterClass src2Regtype, 2798 Operand ext_op, string asm> 2799 : I<(outs dstRegtype:$Rd), 2800 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2801 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2802 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2803 bits<5> Rd; 2804 bits<5> Rn; 2805 bits<5> Rm; 2806 bits<6> ext; 2807 let Inst{30} = isSub; 2808 let Inst{29} = setFlags; 2809 let Inst{28-24} = 0b01011; 2810 let Inst{23-21} = 0b001; 2811 let Inst{20-16} = Rm; 2812 let Inst{15} = ext{5}; 2813 let Inst{12-10} = ext{2-0}; 2814 let Inst{9-5} = Rn; 2815 let Inst{4-0} = Rd; 2816 2817 let DecoderMethod = "DecodeAddSubERegInstruction"; 2818} 2819 2820// Aliases for register+register add/subtract. 2821class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2822 RegisterClass src1Regtype, RegisterClass src2Regtype, 2823 int shiftExt> 2824 : InstAlias<asm#"\t$dst, $src1, $src2", 2825 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2826 shiftExt)>; 2827 2828multiclass AddSub<bit isSub, string mnemonic, string alias, 2829 SDPatternOperator OpNode = null_frag> { 2830 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2831 // Add/Subtract immediate 2832 // Increase the weight of the immediate variant to try to match it before 2833 // the extended register variant. 2834 // We used to match the register variant before the immediate when the 2835 // register argument could be implicitly zero-extended. 2836 let AddedComplexity = 6 in 2837 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2838 mnemonic, OpNode> { 2839 let Inst{31} = 0; 2840 } 2841 let AddedComplexity = 6 in 2842 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2843 mnemonic, OpNode> { 2844 let Inst{31} = 1; 2845 } 2846 2847 // Add/Subtract register - Only used for CodeGen 2848 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2849 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2850 2851 // Add/Subtract shifted register 2852 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2853 OpNode> { 2854 let Inst{31} = 0; 2855 } 2856 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2857 OpNode> { 2858 let Inst{31} = 1; 2859 } 2860 } 2861 2862 // Add/Subtract extended register 2863 let AddedComplexity = 1, hasSideEffects = 0 in { 2864 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2865 arith_extended_reg32_i32, mnemonic, OpNode> { 2866 let Inst{31} = 0; 2867 } 2868 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2869 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2870 let Inst{31} = 1; 2871 } 2872 } 2873 2874 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2875 arith_extendlsl64, mnemonic> { 2876 // UXTX and SXTX only. 2877 let Inst{14-13} = 0b11; 2878 let Inst{31} = 1; 2879 } 2880 2881 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2882 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2883 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2884 addsub_shifted_imm32_neg:$imm), 0>; 2885 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2886 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2887 addsub_shifted_imm64_neg:$imm), 0>; 2888 2889 // Register/register aliases with no shift when SP is not used. 2890 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2891 GPR32, GPR32, GPR32, 0>; 2892 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2893 GPR64, GPR64, GPR64, 0>; 2894 2895 // Register/register aliases with no shift when either the destination or 2896 // first source register is SP. 2897 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2898 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2899 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2900 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2901 def : AddSubRegAlias<mnemonic, 2902 !cast<Instruction>(NAME#"Xrx64"), 2903 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2904 def : AddSubRegAlias<mnemonic, 2905 !cast<Instruction>(NAME#"Xrx64"), 2906 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2907} 2908 2909multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2910 string alias, string cmpAlias> { 2911 let isCompare = 1, Defs = [NZCV] in { 2912 // Add/Subtract immediate 2913 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2914 mnemonic, OpNode> { 2915 let Inst{31} = 0; 2916 } 2917 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2918 mnemonic, OpNode> { 2919 let Inst{31} = 1; 2920 } 2921 2922 // Add/Subtract register 2923 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2924 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2925 2926 // Add/Subtract shifted register 2927 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2928 OpNode> { 2929 let Inst{31} = 0; 2930 } 2931 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2932 OpNode> { 2933 let Inst{31} = 1; 2934 } 2935 2936 // Add/Subtract extended register 2937 let AddedComplexity = 1 in { 2938 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2939 arith_extended_reg32_i32, mnemonic, OpNode> { 2940 let Inst{31} = 0; 2941 } 2942 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2943 arith_extended_reg32_i64, mnemonic, OpNode> { 2944 let Inst{31} = 1; 2945 } 2946 } 2947 2948 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2949 arith_extendlsl64, mnemonic> { 2950 // UXTX and SXTX only. 2951 let Inst{14-13} = 0b11; 2952 let Inst{31} = 1; 2953 } 2954 } // Defs = [NZCV] 2955 2956 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2957 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2958 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2959 addsub_shifted_imm32_neg:$imm), 0>; 2960 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2961 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2962 addsub_shifted_imm64_neg:$imm), 0>; 2963 2964 // Compare aliases 2965 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2966 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2967 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2968 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2969 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2970 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2971 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2972 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2973 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2974 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2975 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2976 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2977 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2978 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2979 2980 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2981 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2982 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2983 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2984 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2985 2986 // Compare shorthands 2987 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2988 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2989 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2990 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2991 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2992 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2993 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2994 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2995 2996 // Register/register aliases with no shift when SP is not used. 2997 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2998 GPR32, GPR32, GPR32, 0>; 2999 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 3000 GPR64, GPR64, GPR64, 0>; 3001 3002 // Register/register aliases with no shift when the first source register 3003 // is SP. 3004 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 3005 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 3006 def : AddSubRegAlias<mnemonic, 3007 !cast<Instruction>(NAME#"Xrx64"), 3008 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 3009} 3010 3011class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 3012 : BaseAddSubImm< 3013 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 3014 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 3015 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 3016 bits<6> imm6; 3017 bits<4> imm4; 3018 let Inst{31} = 1; 3019 let Inst{23-22} = 0b10; 3020 let Inst{21-16} = imm6; 3021 let Inst{15-14} = 0b00; 3022 let Inst{13-10} = imm4; 3023 let Unpredictable{15-14} = 0b11; 3024} 3025 3026class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 3027 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode, 3028 GPR64sp, GPR64sp>; 3029 3030//--- 3031// Extract 3032//--- 3033def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 3034 SDTCisPtrTy<3>]>; 3035def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 3036 3037class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 3038 list<dag> patterns> 3039 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 3040 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 3041 Sched<[WriteExtr, ReadExtrHi]> { 3042 bits<5> Rd; 3043 bits<5> Rn; 3044 bits<5> Rm; 3045 bits<6> imm; 3046 3047 let Inst{30-23} = 0b00100111; 3048 let Inst{21} = 0; 3049 let Inst{20-16} = Rm; 3050 let Inst{15-10} = imm; 3051 let Inst{9-5} = Rn; 3052 let Inst{4-0} = Rd; 3053} 3054 3055multiclass ExtractImm<string asm> { 3056 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 3057 [(set GPR32:$Rd, 3058 (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 3059 let Inst{31} = 0; 3060 let Inst{22} = 0; 3061 // imm<5> must be zero. 3062 let imm{5} = 0; 3063 } 3064 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 3065 [(set GPR64:$Rd, 3066 (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 3067 3068 let Inst{31} = 1; 3069 let Inst{22} = 1; 3070 } 3071} 3072 3073//--- 3074// Bitfield 3075//--- 3076 3077let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3078class BaseBitfieldImm<bits<2> opc, 3079 RegisterClass regtype, Operand imm_type, string asm> 3080 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 3081 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 3082 Sched<[WriteIS, ReadI]> { 3083 bits<5> Rd; 3084 bits<5> Rn; 3085 bits<6> immr; 3086 bits<6> imms; 3087 3088 let Inst{30-29} = opc; 3089 let Inst{28-23} = 0b100110; 3090 let Inst{21-16} = immr; 3091 let Inst{15-10} = imms; 3092 let Inst{9-5} = Rn; 3093 let Inst{4-0} = Rd; 3094} 3095 3096multiclass BitfieldImm<bits<2> opc, string asm> { 3097 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 3098 let Inst{31} = 0; 3099 let Inst{22} = 0; 3100 // imms<5> and immr<5> must be zero, else ReservedValue(). 3101 let Inst{21} = 0; 3102 let Inst{15} = 0; 3103 } 3104 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 3105 let Inst{31} = 1; 3106 let Inst{22} = 1; 3107 } 3108} 3109 3110let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3111class BaseBitfieldImmWith2RegArgs<bits<2> opc, 3112 RegisterClass regtype, Operand imm_type, string asm> 3113 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 3114 imm_type:$imms), 3115 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 3116 Sched<[WriteIS, ReadI]> { 3117 bits<5> Rd; 3118 bits<5> Rn; 3119 bits<6> immr; 3120 bits<6> imms; 3121 3122 let Inst{30-29} = opc; 3123 let Inst{28-23} = 0b100110; 3124 let Inst{21-16} = immr; 3125 let Inst{15-10} = imms; 3126 let Inst{9-5} = Rn; 3127 let Inst{4-0} = Rd; 3128} 3129 3130multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 3131 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 3132 let Inst{31} = 0; 3133 let Inst{22} = 0; 3134 // imms<5> and immr<5> must be zero, else ReservedValue(). 3135 let Inst{21} = 0; 3136 let Inst{15} = 0; 3137 } 3138 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 3139 let Inst{31} = 1; 3140 let Inst{22} = 1; 3141 } 3142} 3143 3144//--- 3145// Logical 3146//--- 3147 3148// Logical (immediate) 3149class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 3150 RegisterClass sregtype, Operand imm_type, string asm, 3151 list<dag> pattern> 3152 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 3153 asm, "\t$Rd, $Rn, $imm", "", pattern>, 3154 Sched<[WriteI, ReadI]> { 3155 bits<5> Rd; 3156 bits<5> Rn; 3157 bits<13> imm; 3158 let Inst{30-29} = opc; 3159 let Inst{28-23} = 0b100100; 3160 let Inst{22} = imm{12}; 3161 let Inst{21-16} = imm{11-6}; 3162 let Inst{15-10} = imm{5-0}; 3163 let Inst{9-5} = Rn; 3164 let Inst{4-0} = Rd; 3165 3166 let DecoderMethod = "DecodeLogicalImmInstruction"; 3167} 3168 3169// Logical (shifted register) 3170class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 3171 logical_shifted_reg shifted_regtype, string asm, 3172 list<dag> pattern> 3173 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 3174 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>, 3175 Sched<[WriteISReg, ReadI, ReadISReg]> { 3176 bits<5> Rd; 3177 bits<5> Rn; 3178 bits<5> Rm; 3179 bits<8> shift; 3180 let Inst{30-29} = opc; 3181 let Inst{28-24} = 0b01010; 3182 let Inst{23-22} = shift{7-6}; 3183 let Inst{21} = N; 3184 let Inst{20-16} = Rm; 3185 let Inst{15-10} = shift{5-0}; 3186 let Inst{9-5} = Rn; 3187 let Inst{4-0} = Rd; 3188 3189 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 3190} 3191 3192// Aliases for register+register logical instructions. 3193class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 3194 : InstAlias<asm#"\t$dst, $src1, $src2", 3195 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 3196 3197multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 3198 string Alias> { 3199 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3200 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 3201 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 3202 logical_imm32:$imm))]> { 3203 let Inst{31} = 0; 3204 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3205 } 3206 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3207 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 3208 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 3209 logical_imm64:$imm))]> { 3210 let Inst{31} = 1; 3211 } 3212 3213 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3214 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 3215 logical_imm32_not:$imm), 0>; 3216 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3217 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 3218 logical_imm64_not:$imm), 0>; 3219} 3220 3221multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 3222 string Alias> { 3223 let isCompare = 1, Defs = [NZCV] in { 3224 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 3225 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 3226 let Inst{31} = 0; 3227 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3228 } 3229 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 3230 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 3231 let Inst{31} = 1; 3232 } 3233 } // end Defs = [NZCV] 3234 3235 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3236 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 3237 logical_imm32_not:$imm), 0>; 3238 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3239 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 3240 logical_imm64_not:$imm), 0>; 3241} 3242 3243class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 3244 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3245 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 3246 Sched<[WriteI, ReadI, ReadI]>; 3247 3248// Split from LogicalImm as not all instructions have both. 3249multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 3250 SDPatternOperator OpNode, int AddedComplexityVal = 0> { 3251 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in { 3252 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3253 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3254 } 3255 3256 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3257 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3258 logical_shifted_reg32:$Rm_and_shift))]> { 3259 let Inst{31} = 0; 3260 } 3261 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3262 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3263 logical_shifted_reg64:$Rm_and_shift))]> { 3264 let Inst{31} = 1; 3265 } 3266 3267 def : LogicalRegAlias<mnemonic, 3268 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3269 def : LogicalRegAlias<mnemonic, 3270 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3271} 3272 3273// Split from LogicalReg to allow setting NZCV Defs 3274multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3275 SDPatternOperator OpNode = null_frag> { 3276 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3277 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3278 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3279 3280 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3281 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> { 3282 let Inst{31} = 0; 3283 } 3284 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3285 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> { 3286 let Inst{31} = 1; 3287 } 3288 } // Defs = [NZCV] 3289 3290 def : LogicalRegAlias<mnemonic, 3291 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3292 def : LogicalRegAlias<mnemonic, 3293 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3294} 3295 3296//--- 3297// Conditionally set flags 3298//--- 3299 3300let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3301class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3302 string mnemonic, SDNode OpNode> 3303 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3304 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3305 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3306 (i32 imm:$cond), NZCV))]>, 3307 Sched<[WriteI, ReadI]> { 3308 let Uses = [NZCV]; 3309 let Defs = [NZCV]; 3310 3311 bits<5> Rn; 3312 bits<5> imm; 3313 bits<4> nzcv; 3314 bits<4> cond; 3315 3316 let Inst{30} = op; 3317 let Inst{29-21} = 0b111010010; 3318 let Inst{20-16} = imm; 3319 let Inst{15-12} = cond; 3320 let Inst{11-10} = 0b10; 3321 let Inst{9-5} = Rn; 3322 let Inst{4} = 0b0; 3323 let Inst{3-0} = nzcv; 3324} 3325 3326let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3327class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3328 SDNode OpNode> 3329 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3330 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3331 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3332 (i32 imm:$cond), NZCV))]>, 3333 Sched<[WriteI, ReadI, ReadI]> { 3334 let Uses = [NZCV]; 3335 let Defs = [NZCV]; 3336 3337 bits<5> Rn; 3338 bits<5> Rm; 3339 bits<4> nzcv; 3340 bits<4> cond; 3341 3342 let Inst{30} = op; 3343 let Inst{29-21} = 0b111010010; 3344 let Inst{20-16} = Rm; 3345 let Inst{15-12} = cond; 3346 let Inst{11-10} = 0b00; 3347 let Inst{9-5} = Rn; 3348 let Inst{4} = 0b0; 3349 let Inst{3-0} = nzcv; 3350} 3351 3352multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3353 // immediate operand variants 3354 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3355 let Inst{31} = 0; 3356 } 3357 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3358 let Inst{31} = 1; 3359 } 3360 // register operand variants 3361 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3362 let Inst{31} = 0; 3363 } 3364 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3365 let Inst{31} = 1; 3366 } 3367} 3368 3369//--- 3370// Conditional select 3371//--- 3372 3373class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3374 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3375 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3376 [(set regtype:$Rd, 3377 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3378 Sched<[WriteI, ReadI, ReadI]> { 3379 let Uses = [NZCV]; 3380 3381 bits<5> Rd; 3382 bits<5> Rn; 3383 bits<5> Rm; 3384 bits<4> cond; 3385 3386 let Inst{30} = op; 3387 let Inst{29-21} = 0b011010100; 3388 let Inst{20-16} = Rm; 3389 let Inst{15-12} = cond; 3390 let Inst{11-10} = op2; 3391 let Inst{9-5} = Rn; 3392 let Inst{4-0} = Rd; 3393} 3394 3395multiclass CondSelect<bit op, bits<2> op2, string asm> { 3396 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3397 let Inst{31} = 0; 3398 } 3399 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3400 let Inst{31} = 1; 3401 } 3402} 3403 3404class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3405 PatFrag frag> 3406 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3407 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3408 [(set regtype:$Rd, 3409 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3410 (i32 imm:$cond), NZCV))]>, 3411 Sched<[WriteI, ReadI, ReadI]> { 3412 let Uses = [NZCV]; 3413 3414 bits<5> Rd; 3415 bits<5> Rn; 3416 bits<5> Rm; 3417 bits<4> cond; 3418 3419 let Inst{30} = op; 3420 let Inst{29-21} = 0b011010100; 3421 let Inst{20-16} = Rm; 3422 let Inst{15-12} = cond; 3423 let Inst{11-10} = op2; 3424 let Inst{9-5} = Rn; 3425 let Inst{4-0} = Rd; 3426} 3427 3428def inv_cond_XFORM : SDNodeXForm<imm, [{ 3429 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3430 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3431 MVT::i32); 3432}]>; 3433 3434multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3435 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3436 let Inst{31} = 0; 3437 } 3438 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3439 let Inst{31} = 1; 3440 } 3441 3442 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3443 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3444 (inv_cond_XFORM imm:$cond))>; 3445 3446 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3447 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3448 (inv_cond_XFORM imm:$cond))>; 3449} 3450 3451//--- 3452// Special Mask Value 3453//--- 3454def maski8_or_more : Operand<i32>, 3455 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3456} 3457def maski16_or_more : Operand<i32>, 3458 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3459} 3460 3461 3462//--- 3463// Load/store 3464//--- 3465 3466// (unsigned immediate) 3467// Indexed for 8-bit registers. offset is in range [0,4095]. 3468def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3469def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3470def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3471def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3472def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3473 3474// (unsigned immediate) 3475// Indexed for 8-bit registers. offset is in range [0,63]. 3476def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3477def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3478def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3479def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3480 3481def gi_am_indexed8 : 3482 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3483 GIComplexPatternEquiv<am_indexed8>; 3484def gi_am_indexed16 : 3485 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3486 GIComplexPatternEquiv<am_indexed16>; 3487def gi_am_indexed32 : 3488 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3489 GIComplexPatternEquiv<am_indexed32>; 3490def gi_am_indexed64 : 3491 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3492 GIComplexPatternEquiv<am_indexed64>; 3493def gi_am_indexed128 : 3494 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3495 GIComplexPatternEquiv<am_indexed128>; 3496 3497class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3498 let Name = "UImm12Offset" # Scale; 3499 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3500 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3501 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3502} 3503 3504def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3505def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3506def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3507def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3508def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3509 3510class uimm12_scaled<int Scale> : Operand<i64> { 3511 let ParserMatchClass 3512 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3513 let EncoderMethod 3514 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3515 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3516} 3517 3518def uimm12s1 : uimm12_scaled<1>; 3519def uimm12s2 : uimm12_scaled<2>; 3520def uimm12s4 : uimm12_scaled<4>; 3521def uimm12s8 : uimm12_scaled<8>; 3522def uimm12s16 : uimm12_scaled<16>; 3523 3524class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3525 string asm, list<dag> pattern> 3526 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3527 bits<5> Rt; 3528 3529 bits<5> Rn; 3530 bits<12> offset; 3531 3532 let Inst{31-30} = sz; 3533 let Inst{29-27} = 0b111; 3534 let Inst{26} = V; 3535 let Inst{25-24} = 0b01; 3536 let Inst{23-22} = opc; 3537 let Inst{21-10} = offset; 3538 let Inst{9-5} = Rn; 3539 let Inst{4-0} = Rt; 3540 3541 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3542} 3543 3544multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3545 Operand indextype, string asm, list<dag> pattern> { 3546 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3547 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3548 (ins GPR64sp:$Rn, indextype:$offset), 3549 asm, pattern>, 3550 Sched<[WriteLD]>; 3551 3552 def : InstAlias<asm # "\t$Rt, [$Rn]", 3553 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3554} 3555 3556multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3557 Operand indextype, string asm, list<dag> pattern> { 3558 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3559 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3560 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3561 asm, pattern>, 3562 Sched<[WriteST]>; 3563 3564 def : InstAlias<asm # "\t$Rt, [$Rn]", 3565 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3566} 3567 3568// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3569// substitute zero-registers automatically. 3570// 3571// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3572// into StoreUI. 3573multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3574 Operand indextype, string asm, list<dag> pattern> { 3575 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3576 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3577 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3578 asm, pattern>, 3579 Sched<[WriteST]>; 3580 3581 def : InstAlias<asm # "\t$Rt, [$Rn]", 3582 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3583} 3584 3585def PrefetchOperand : AsmOperandClass { 3586 let Name = "Prefetch"; 3587 let ParserMethod = "tryParsePrefetch"; 3588} 3589def prfop : Operand<i32> { 3590 let PrintMethod = "printPrefetchOp"; 3591 let ParserMatchClass = PrefetchOperand; 3592} 3593 3594let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3595class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3596 : BaseLoadStoreUI<sz, V, opc, 3597 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3598 asm, pat>, 3599 Sched<[WriteLD]>; 3600 3601//--- 3602// Load literal 3603//--- 3604 3605// Load literal address: 19-bit immediate. The low two bits of the target 3606// offset are implied zero and so are not part of the immediate. 3607def am_ldrlit : Operand<iPTR> { 3608 let EncoderMethod = "getLoadLiteralOpValue"; 3609 let DecoderMethod = "DecodePCRelLabel19"; 3610 let PrintMethod = "printAlignedLabel"; 3611 let ParserMatchClass = PCRelLabel19Operand; 3612 let OperandType = "OPERAND_PCREL"; 3613} 3614 3615let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3616class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3617 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3618 asm, "\t$Rt, $label", "", pat>, 3619 Sched<[WriteLD]> { 3620 bits<5> Rt; 3621 bits<19> label; 3622 let Inst{31-30} = opc; 3623 let Inst{29-27} = 0b011; 3624 let Inst{26} = V; 3625 let Inst{25-24} = 0b00; 3626 let Inst{23-5} = label; 3627 let Inst{4-0} = Rt; 3628} 3629 3630let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3631class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3632 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3633 asm, "\t$Rt, $label", "", pat>, 3634 Sched<[WriteLD]> { 3635 bits<5> Rt; 3636 bits<19> label; 3637 let Inst{31-30} = opc; 3638 let Inst{29-27} = 0b011; 3639 let Inst{26} = V; 3640 let Inst{25-24} = 0b00; 3641 let Inst{23-5} = label; 3642 let Inst{4-0} = Rt; 3643} 3644 3645//--- 3646// Load/store register offset 3647//--- 3648 3649def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3650def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3651def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3652def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3653def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3654 3655def gi_ro_Xindexed8 : 3656 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3657 GIComplexPatternEquiv<ro_Xindexed8>; 3658def gi_ro_Xindexed16 : 3659 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3660 GIComplexPatternEquiv<ro_Xindexed16>; 3661def gi_ro_Xindexed32 : 3662 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3663 GIComplexPatternEquiv<ro_Xindexed32>; 3664def gi_ro_Xindexed64 : 3665 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3666 GIComplexPatternEquiv<ro_Xindexed64>; 3667def gi_ro_Xindexed128 : 3668 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3669 GIComplexPatternEquiv<ro_Xindexed128>; 3670 3671def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3672def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3673def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3674def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3675def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3676 3677def gi_ro_Windexed8 : 3678 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3679 GIComplexPatternEquiv<ro_Windexed8>; 3680def gi_ro_Windexed16 : 3681 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3682 GIComplexPatternEquiv<ro_Windexed16>; 3683def gi_ro_Windexed32 : 3684 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3685 GIComplexPatternEquiv<ro_Windexed32>; 3686def gi_ro_Windexed64 : 3687 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3688 GIComplexPatternEquiv<ro_Windexed64>; 3689def gi_ro_Windexed128 : 3690 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3691 GIComplexPatternEquiv<ro_Windexed128>; 3692 3693class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3694 let Name = "Mem" # Reg # "Extend" # Width; 3695 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3696 let RenderMethod = "addMemExtendOperands"; 3697 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3698} 3699 3700def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3701 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3702 // the trivial shift. 3703 let RenderMethod = "addMemExtend8Operands"; 3704} 3705def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3706def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3707def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3708def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3709 3710def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3711 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3712 // the trivial shift. 3713 let RenderMethod = "addMemExtend8Operands"; 3714} 3715def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3716def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3717def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3718def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3719 3720class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3721 : Operand<i32> { 3722 let ParserMatchClass = ParserClass; 3723 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3724 let DecoderMethod = "DecodeMemExtend"; 3725 let EncoderMethod = "getMemExtendOpValue"; 3726 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3727} 3728 3729def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3730def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3731def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3732def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3733def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3734 3735def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3736def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3737def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3738def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3739def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3740 3741class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3742 Operand wextend, Operand xextend> { 3743 // CodeGen-level pattern covering the entire addressing mode. 3744 ComplexPattern Wpat = windex; 3745 ComplexPattern Xpat = xindex; 3746 3747 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3748 Operand Wext = wextend; 3749 Operand Xext = xextend; 3750} 3751 3752def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3753def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3754def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3755def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3756def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3757 ro_Xextend128>; 3758 3759class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3760 dag outs, list<dag> pat> 3761 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3762 bits<5> Rt; 3763 bits<5> Rn; 3764 bits<5> Rm; 3765 bits<2> extend; 3766 let Inst{31-30} = sz; 3767 let Inst{29-27} = 0b111; 3768 let Inst{26} = V; 3769 let Inst{25-24} = 0b00; 3770 let Inst{23-22} = opc; 3771 let Inst{21} = 1; 3772 let Inst{20-16} = Rm; 3773 let Inst{15} = extend{1}; // sign extend Rm? 3774 let Inst{14} = 1; 3775 let Inst{12} = extend{0}; // do shift? 3776 let Inst{11-10} = 0b10; 3777 let Inst{9-5} = Rn; 3778 let Inst{4-0} = Rt; 3779} 3780 3781class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3782 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3783 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3784 3785multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3786 string asm, ValueType Ty, SDPatternOperator loadop> { 3787 let AddedComplexity = 10 in 3788 def roW : LoadStore8RO<sz, V, opc, asm, 3789 (outs regtype:$Rt), 3790 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3791 [(set (Ty regtype:$Rt), 3792 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3793 ro_Wextend8:$extend)))]>, 3794 Sched<[WriteLDIdx, ReadAdrBase]> { 3795 let Inst{13} = 0b0; 3796 } 3797 3798 let AddedComplexity = 10 in 3799 def roX : LoadStore8RO<sz, V, opc, asm, 3800 (outs regtype:$Rt), 3801 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3802 [(set (Ty regtype:$Rt), 3803 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3804 ro_Xextend8:$extend)))]>, 3805 Sched<[WriteLDIdx, ReadAdrBase]> { 3806 let Inst{13} = 0b1; 3807 } 3808 3809 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3810} 3811 3812multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3813 string asm, ValueType Ty, SDPatternOperator storeop> { 3814 let AddedComplexity = 10 in 3815 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3816 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3817 [(storeop (Ty regtype:$Rt), 3818 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3819 ro_Wextend8:$extend))]>, 3820 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3821 let Inst{13} = 0b0; 3822 } 3823 3824 let AddedComplexity = 10 in 3825 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3826 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3827 [(storeop (Ty regtype:$Rt), 3828 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3829 ro_Xextend8:$extend))]>, 3830 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3831 let Inst{13} = 0b1; 3832 } 3833 3834 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3835} 3836 3837class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3838 dag outs, list<dag> pat> 3839 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3840 bits<5> Rt; 3841 bits<5> Rn; 3842 bits<5> Rm; 3843 bits<2> extend; 3844 let Inst{31-30} = sz; 3845 let Inst{29-27} = 0b111; 3846 let Inst{26} = V; 3847 let Inst{25-24} = 0b00; 3848 let Inst{23-22} = opc; 3849 let Inst{21} = 1; 3850 let Inst{20-16} = Rm; 3851 let Inst{15} = extend{1}; // sign extend Rm? 3852 let Inst{14} = 1; 3853 let Inst{12} = extend{0}; // do shift? 3854 let Inst{11-10} = 0b10; 3855 let Inst{9-5} = Rn; 3856 let Inst{4-0} = Rt; 3857} 3858 3859multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3860 string asm, ValueType Ty, SDPatternOperator loadop> { 3861 let AddedComplexity = 10 in 3862 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3863 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3864 [(set (Ty regtype:$Rt), 3865 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3866 ro_Wextend16:$extend)))]>, 3867 Sched<[WriteLDIdx, ReadAdrBase]> { 3868 let Inst{13} = 0b0; 3869 } 3870 3871 let AddedComplexity = 10 in 3872 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3873 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3874 [(set (Ty regtype:$Rt), 3875 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3876 ro_Xextend16:$extend)))]>, 3877 Sched<[WriteLDIdx, ReadAdrBase]> { 3878 let Inst{13} = 0b1; 3879 } 3880 3881 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3882} 3883 3884multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3885 string asm, ValueType Ty, SDPatternOperator storeop> { 3886 let AddedComplexity = 10 in 3887 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3888 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3889 [(storeop (Ty regtype:$Rt), 3890 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3891 ro_Wextend16:$extend))]>, 3892 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3893 let Inst{13} = 0b0; 3894 } 3895 3896 let AddedComplexity = 10 in 3897 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3898 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3899 [(storeop (Ty regtype:$Rt), 3900 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3901 ro_Xextend16:$extend))]>, 3902 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3903 let Inst{13} = 0b1; 3904 } 3905 3906 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3907} 3908 3909class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3910 dag outs, list<dag> pat> 3911 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3912 bits<5> Rt; 3913 bits<5> Rn; 3914 bits<5> Rm; 3915 bits<2> extend; 3916 let Inst{31-30} = sz; 3917 let Inst{29-27} = 0b111; 3918 let Inst{26} = V; 3919 let Inst{25-24} = 0b00; 3920 let Inst{23-22} = opc; 3921 let Inst{21} = 1; 3922 let Inst{20-16} = Rm; 3923 let Inst{15} = extend{1}; // sign extend Rm? 3924 let Inst{14} = 1; 3925 let Inst{12} = extend{0}; // do shift? 3926 let Inst{11-10} = 0b10; 3927 let Inst{9-5} = Rn; 3928 let Inst{4-0} = Rt; 3929} 3930 3931multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3932 string asm, ValueType Ty, SDPatternOperator loadop> { 3933 let AddedComplexity = 10 in 3934 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3935 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3936 [(set (Ty regtype:$Rt), 3937 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3938 ro_Wextend32:$extend)))]>, 3939 Sched<[WriteLDIdx, ReadAdrBase]> { 3940 let Inst{13} = 0b0; 3941 } 3942 3943 let AddedComplexity = 10 in 3944 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 3945 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3946 [(set (Ty regtype:$Rt), 3947 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3948 ro_Xextend32:$extend)))]>, 3949 Sched<[WriteLDIdx, ReadAdrBase]> { 3950 let Inst{13} = 0b1; 3951 } 3952 3953 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3954} 3955 3956multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3957 string asm, ValueType Ty, SDPatternOperator storeop> { 3958 let AddedComplexity = 10 in 3959 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 3960 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3961 [(storeop (Ty regtype:$Rt), 3962 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3963 ro_Wextend32:$extend))]>, 3964 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3965 let Inst{13} = 0b0; 3966 } 3967 3968 let AddedComplexity = 10 in 3969 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 3970 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3971 [(storeop (Ty regtype:$Rt), 3972 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3973 ro_Xextend32:$extend))]>, 3974 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3975 let Inst{13} = 0b1; 3976 } 3977 3978 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3979} 3980 3981class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3982 dag outs, list<dag> pat> 3983 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3984 bits<5> Rt; 3985 bits<5> Rn; 3986 bits<5> Rm; 3987 bits<2> extend; 3988 let Inst{31-30} = sz; 3989 let Inst{29-27} = 0b111; 3990 let Inst{26} = V; 3991 let Inst{25-24} = 0b00; 3992 let Inst{23-22} = opc; 3993 let Inst{21} = 1; 3994 let Inst{20-16} = Rm; 3995 let Inst{15} = extend{1}; // sign extend Rm? 3996 let Inst{14} = 1; 3997 let Inst{12} = extend{0}; // do shift? 3998 let Inst{11-10} = 0b10; 3999 let Inst{9-5} = Rn; 4000 let Inst{4-0} = Rt; 4001} 4002 4003multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4004 string asm, ValueType Ty, SDPatternOperator loadop> { 4005 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4006 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4007 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4008 [(set (Ty regtype:$Rt), 4009 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4010 ro_Wextend64:$extend)))]>, 4011 Sched<[WriteLDIdx, ReadAdrBase]> { 4012 let Inst{13} = 0b0; 4013 } 4014 4015 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4016 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4017 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4018 [(set (Ty regtype:$Rt), 4019 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4020 ro_Xextend64:$extend)))]>, 4021 Sched<[WriteLDIdx, ReadAdrBase]> { 4022 let Inst{13} = 0b1; 4023 } 4024 4025 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4026} 4027 4028multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4029 string asm, ValueType Ty, SDPatternOperator storeop> { 4030 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4031 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 4032 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4033 [(storeop (Ty regtype:$Rt), 4034 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4035 ro_Wextend64:$extend))]>, 4036 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4037 let Inst{13} = 0b0; 4038 } 4039 4040 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4041 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 4042 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4043 [(storeop (Ty regtype:$Rt), 4044 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4045 ro_Xextend64:$extend))]>, 4046 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4047 let Inst{13} = 0b1; 4048 } 4049 4050 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4051} 4052 4053class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4054 dag outs, list<dag> pat> 4055 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4056 bits<5> Rt; 4057 bits<5> Rn; 4058 bits<5> Rm; 4059 bits<2> extend; 4060 let Inst{31-30} = sz; 4061 let Inst{29-27} = 0b111; 4062 let Inst{26} = V; 4063 let Inst{25-24} = 0b00; 4064 let Inst{23-22} = opc; 4065 let Inst{21} = 1; 4066 let Inst{20-16} = Rm; 4067 let Inst{15} = extend{1}; // sign extend Rm? 4068 let Inst{14} = 1; 4069 let Inst{12} = extend{0}; // do shift? 4070 let Inst{11-10} = 0b10; 4071 let Inst{9-5} = Rn; 4072 let Inst{4-0} = Rt; 4073} 4074 4075multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4076 string asm, ValueType Ty, SDPatternOperator loadop> { 4077 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4078 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4079 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4080 [(set (Ty regtype:$Rt), 4081 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 4082 ro_Wextend128:$extend)))]>, 4083 Sched<[WriteLDIdx, ReadAdrBase]> { 4084 let Inst{13} = 0b0; 4085 } 4086 4087 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4088 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4089 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4090 [(set (Ty regtype:$Rt), 4091 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 4092 ro_Xextend128:$extend)))]>, 4093 Sched<[WriteLDIdx, ReadAdrBase]> { 4094 let Inst{13} = 0b1; 4095 } 4096 4097 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4098} 4099 4100multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4101 string asm> { 4102 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4103 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 4104 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4105 []>, 4106 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4107 let Inst{13} = 0b0; 4108 } 4109 4110 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4111 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 4112 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4113 []>, 4114 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4115 let Inst{13} = 0b1; 4116 } 4117 4118 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4119} 4120 4121let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4122class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 4123 string asm, list<dag> pat> 4124 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 4125 Sched<[WriteLD]> { 4126 bits<5> Rt; 4127 bits<5> Rn; 4128 bits<5> Rm; 4129 bits<2> extend; 4130 let Inst{31-30} = sz; 4131 let Inst{29-27} = 0b111; 4132 let Inst{26} = V; 4133 let Inst{25-24} = 0b00; 4134 let Inst{23-22} = opc; 4135 let Inst{21} = 1; 4136 let Inst{20-16} = Rm; 4137 let Inst{15} = extend{1}; // sign extend Rm? 4138 let Inst{14} = 1; 4139 let Inst{12} = extend{0}; // do shift? 4140 let Inst{11-10} = 0b10; 4141 let Inst{9-5} = Rn; 4142 let Inst{4-0} = Rt; 4143 let DecoderMethod = "DecodePRFMRegInstruction"; 4144 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When 4145 // the decoder method returns Fail, the decoder should attempt to decode the 4146 // instruction as RPRFM. 4147 let hasCompleteDecoder = 0; 4148} 4149 4150multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 4151 def roW : BasePrefetchRO<sz, V, opc, (outs), 4152 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4153 asm, [(AArch64Prefetch timm:$Rt, 4154 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4155 ro_Wextend64:$extend))]> { 4156 let Inst{13} = 0b0; 4157 } 4158 4159 def roX : BasePrefetchRO<sz, V, opc, (outs), 4160 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4161 asm, [(AArch64Prefetch timm:$Rt, 4162 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4163 ro_Xextend64:$extend))]> { 4164 let Inst{13} = 0b1; 4165 } 4166 4167 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 4168 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 4169 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 4170} 4171 4172//--- 4173// Load/store unscaled immediate 4174//--- 4175 4176def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 4177def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 4178def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 4179def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 4180def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 4181 4182def gi_am_unscaled8 : 4183 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 4184 GIComplexPatternEquiv<am_unscaled8>; 4185def gi_am_unscaled16 : 4186 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 4187 GIComplexPatternEquiv<am_unscaled16>; 4188def gi_am_unscaled32 : 4189 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 4190 GIComplexPatternEquiv<am_unscaled32>; 4191def gi_am_unscaled64 : 4192 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 4193 GIComplexPatternEquiv<am_unscaled64>; 4194def gi_am_unscaled128 : 4195 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 4196 GIComplexPatternEquiv<am_unscaled128>; 4197 4198 4199class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4200 string asm, list<dag> pattern> 4201 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 4202 bits<5> Rt; 4203 bits<5> Rn; 4204 bits<9> offset; 4205 let Inst{31-30} = sz; 4206 let Inst{29-27} = 0b111; 4207 let Inst{26} = V; 4208 let Inst{25-24} = 0b00; 4209 let Inst{23-22} = opc; 4210 let Inst{21} = 0; 4211 let Inst{20-12} = offset; 4212 let Inst{11-10} = 0b00; 4213 let Inst{9-5} = Rn; 4214 let Inst{4-0} = Rt; 4215 4216 let DecoderMethod = "DecodeSignedLdStInstruction"; 4217} 4218 4219// Armv8.4 LDAPR & STLR with Immediate Offset instruction 4220multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4221 DAGOperand regtype > { 4222 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 4223 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 4224 Sched<[WriteST]> { 4225 let Inst{29} = 0; 4226 let Inst{24} = 1; 4227 } 4228 def : InstAlias<asm # "\t$Rt, [$Rn]", 4229 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4230} 4231 4232multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4233 DAGOperand regtype > { 4234 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 4235 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4236 asm, []>, 4237 Sched<[WriteST]> { 4238 let Inst{29} = 0; 4239 let Inst{24} = 1; 4240 } 4241 def : InstAlias<asm # "\t$Rt, [$Rn]", 4242 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4243} 4244 4245multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4246 string asm, list<dag> pattern> { 4247 let AddedComplexity = 1 in // try this before LoadUI 4248 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 4249 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 4250 Sched<[WriteLD]>; 4251 4252 def : InstAlias<asm # "\t$Rt, [$Rn]", 4253 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4254} 4255 4256multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4257 string asm, list<dag> pattern> { 4258 let AddedComplexity = 1 in // try this before StoreUI 4259 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4260 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4261 asm, pattern>, 4262 Sched<[WriteST]>; 4263 4264 def : InstAlias<asm # "\t$Rt, [$Rn]", 4265 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4266} 4267 4268multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4269 list<dag> pat> { 4270 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4271 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4272 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4273 asm, pat>, 4274 Sched<[WriteLD]>; 4275 4276 def : InstAlias<asm # "\t$Rt, [$Rn]", 4277 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4278} 4279 4280//--- 4281// Load/store unscaled immediate, unprivileged 4282//--- 4283 4284class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4285 dag oops, dag iops, string asm> 4286 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4287 bits<5> Rt; 4288 bits<5> Rn; 4289 bits<9> offset; 4290 let Inst{31-30} = sz; 4291 let Inst{29-27} = 0b111; 4292 let Inst{26} = V; 4293 let Inst{25-24} = 0b00; 4294 let Inst{23-22} = opc; 4295 let Inst{21} = 0; 4296 let Inst{20-12} = offset; 4297 let Inst{11-10} = 0b10; 4298 let Inst{9-5} = Rn; 4299 let Inst{4-0} = Rt; 4300 4301 let DecoderMethod = "DecodeSignedLdStInstruction"; 4302} 4303 4304multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4305 RegisterClass regtype, string asm> { 4306 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4307 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4308 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4309 Sched<[WriteLD]>; 4310 4311 def : InstAlias<asm # "\t$Rt, [$Rn]", 4312 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4313} 4314 4315multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4316 RegisterClass regtype, string asm> { 4317 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4318 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4319 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4320 asm>, 4321 Sched<[WriteST]>; 4322 4323 def : InstAlias<asm # "\t$Rt, [$Rn]", 4324 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4325} 4326 4327//--- 4328// Load/store pre-indexed 4329//--- 4330 4331class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4332 string asm, string cstr, list<dag> pat> 4333 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4334 bits<5> Rt; 4335 bits<5> Rn; 4336 bits<9> offset; 4337 let Inst{31-30} = sz; 4338 let Inst{29-27} = 0b111; 4339 let Inst{26} = V; 4340 let Inst{25-24} = 0; 4341 let Inst{23-22} = opc; 4342 let Inst{21} = 0; 4343 let Inst{20-12} = offset; 4344 let Inst{11-10} = 0b11; 4345 let Inst{9-5} = Rn; 4346 let Inst{4-0} = Rt; 4347 4348 let DecoderMethod = "DecodeSignedLdStInstruction"; 4349} 4350 4351let hasSideEffects = 0 in { 4352let mayStore = 0, mayLoad = 1 in 4353class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4354 string asm> 4355 : BaseLoadStorePreIdx<sz, V, opc, 4356 (outs GPR64sp:$wback, regtype:$Rt), 4357 (ins GPR64sp:$Rn, simm9:$offset), asm, 4358 "$Rn = $wback,@earlyclobber $wback", []>, 4359 Sched<[WriteAdr, WriteLD]>; 4360 4361let mayStore = 1, mayLoad = 0 in 4362class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4363 string asm, SDPatternOperator storeop, ValueType Ty> 4364 : BaseLoadStorePreIdx<sz, V, opc, 4365 (outs GPR64sp:$wback), 4366 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4367 asm, "$Rn = $wback,@earlyclobber $wback", 4368 [(set GPR64sp:$wback, 4369 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4370 Sched<[WriteAdr, WriteST]>; 4371} // hasSideEffects = 0 4372 4373//--- 4374// Load/store post-indexed 4375//--- 4376 4377class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4378 string asm, string cstr, list<dag> pat> 4379 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4380 bits<5> Rt; 4381 bits<5> Rn; 4382 bits<9> offset; 4383 let Inst{31-30} = sz; 4384 let Inst{29-27} = 0b111; 4385 let Inst{26} = V; 4386 let Inst{25-24} = 0b00; 4387 let Inst{23-22} = opc; 4388 let Inst{21} = 0b0; 4389 let Inst{20-12} = offset; 4390 let Inst{11-10} = 0b01; 4391 let Inst{9-5} = Rn; 4392 let Inst{4-0} = Rt; 4393 4394 let DecoderMethod = "DecodeSignedLdStInstruction"; 4395} 4396 4397let hasSideEffects = 0 in { 4398let mayStore = 0, mayLoad = 1 in 4399class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4400 string asm> 4401 : BaseLoadStorePostIdx<sz, V, opc, 4402 (outs GPR64sp:$wback, regtype:$Rt), 4403 (ins GPR64sp:$Rn, simm9:$offset), 4404 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4405 Sched<[WriteAdr, WriteLD]>; 4406 4407let mayStore = 1, mayLoad = 0 in 4408class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4409 string asm, SDPatternOperator storeop, ValueType Ty> 4410 : BaseLoadStorePostIdx<sz, V, opc, 4411 (outs GPR64sp:$wback), 4412 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4413 asm, "$Rn = $wback,@earlyclobber $wback", 4414 [(set GPR64sp:$wback, 4415 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4416 Sched<[WriteAdr, WriteST]>; 4417} // hasSideEffects = 0 4418 4419 4420//--- 4421// Load/store pair 4422//--- 4423 4424// (indexed, offset) 4425 4426class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4427 string asm> 4428 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4429 bits<5> Rt; 4430 bits<5> Rt2; 4431 bits<5> Rn; 4432 bits<7> offset; 4433 let Inst{31-30} = opc; 4434 let Inst{29-27} = 0b101; 4435 let Inst{26} = V; 4436 let Inst{25-23} = 0b010; 4437 let Inst{22} = L; 4438 let Inst{21-15} = offset; 4439 let Inst{14-10} = Rt2; 4440 let Inst{9-5} = Rn; 4441 let Inst{4-0} = Rt; 4442 4443 let DecoderMethod = "DecodePairLdStInstruction"; 4444} 4445 4446multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4447 Operand indextype, string asm> { 4448 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4449 def i : BaseLoadStorePairOffset<opc, V, 1, 4450 (outs regtype:$Rt, regtype:$Rt2), 4451 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4452 Sched<[WriteLD, WriteLDHi]>; 4453 4454 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4455 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4456 GPR64sp:$Rn, 0)>; 4457} 4458 4459 4460multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4461 Operand indextype, string asm> { 4462 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4463 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4464 (ins regtype:$Rt, regtype:$Rt2, 4465 GPR64sp:$Rn, indextype:$offset), 4466 asm>, 4467 Sched<[WriteSTP]>; 4468 4469 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4470 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4471 GPR64sp:$Rn, 0)>; 4472} 4473 4474// (pre-indexed) 4475class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4476 string asm> 4477 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4478 bits<5> Rt; 4479 bits<5> Rt2; 4480 bits<5> Rn; 4481 bits<7> offset; 4482 let Inst{31-30} = opc; 4483 let Inst{29-27} = 0b101; 4484 let Inst{26} = V; 4485 let Inst{25-23} = 0b011; 4486 let Inst{22} = L; 4487 let Inst{21-15} = offset; 4488 let Inst{14-10} = Rt2; 4489 let Inst{9-5} = Rn; 4490 let Inst{4-0} = Rt; 4491 4492 let DecoderMethod = "DecodePairLdStInstruction"; 4493} 4494 4495let hasSideEffects = 0 in { 4496let mayStore = 0, mayLoad = 1 in 4497class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4498 Operand indextype, string asm> 4499 : BaseLoadStorePairPreIdx<opc, V, 1, 4500 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4501 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4502 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4503 4504let mayStore = 1, mayLoad = 0 in 4505class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4506 Operand indextype, string asm> 4507 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4508 (ins regtype:$Rt, regtype:$Rt2, 4509 GPR64sp:$Rn, indextype:$offset), 4510 asm>, 4511 Sched<[WriteAdr, WriteSTP]>; 4512} // hasSideEffects = 0 4513 4514// (post-indexed) 4515 4516class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4517 string asm> 4518 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4519 bits<5> Rt; 4520 bits<5> Rt2; 4521 bits<5> Rn; 4522 bits<7> offset; 4523 let Inst{31-30} = opc; 4524 let Inst{29-27} = 0b101; 4525 let Inst{26} = V; 4526 let Inst{25-23} = 0b001; 4527 let Inst{22} = L; 4528 let Inst{21-15} = offset; 4529 let Inst{14-10} = Rt2; 4530 let Inst{9-5} = Rn; 4531 let Inst{4-0} = Rt; 4532 4533 let DecoderMethod = "DecodePairLdStInstruction"; 4534} 4535 4536let hasSideEffects = 0 in { 4537let mayStore = 0, mayLoad = 1 in 4538class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4539 Operand idxtype, string asm> 4540 : BaseLoadStorePairPostIdx<opc, V, 1, 4541 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4542 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4543 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4544 4545let mayStore = 1, mayLoad = 0 in 4546class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4547 Operand idxtype, string asm> 4548 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4549 (ins regtype:$Rt, regtype:$Rt2, 4550 GPR64sp:$Rn, idxtype:$offset), 4551 asm>, 4552 Sched<[WriteAdr, WriteSTP]>; 4553} // hasSideEffects = 0 4554 4555// (no-allocate) 4556 4557class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4558 string asm> 4559 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4560 bits<5> Rt; 4561 bits<5> Rt2; 4562 bits<5> Rn; 4563 bits<7> offset; 4564 let Inst{31-30} = opc; 4565 let Inst{29-27} = 0b101; 4566 let Inst{26} = V; 4567 let Inst{25-23} = 0b000; 4568 let Inst{22} = L; 4569 let Inst{21-15} = offset; 4570 let Inst{14-10} = Rt2; 4571 let Inst{9-5} = Rn; 4572 let Inst{4-0} = Rt; 4573 4574 let DecoderMethod = "DecodePairLdStInstruction"; 4575} 4576 4577multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4578 Operand indextype, string asm> { 4579 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4580 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4581 (outs regtype:$Rt, regtype:$Rt2), 4582 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4583 Sched<[WriteLD, WriteLDHi]>; 4584 4585 4586 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4587 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4588 GPR64sp:$Rn, 0)>; 4589} 4590 4591multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4592 Operand indextype, string asm> { 4593 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4594 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4595 (ins regtype:$Rt, regtype:$Rt2, 4596 GPR64sp:$Rn, indextype:$offset), 4597 asm>, 4598 Sched<[WriteSTP]>; 4599 4600 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4601 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4602 GPR64sp:$Rn, 0)>; 4603} 4604 4605//--- 4606// Load/store exclusive 4607//--- 4608 4609// True exclusive operations write to and/or read from the system's exclusive 4610// monitors, which as far as a compiler is concerned can be modelled as a 4611// random shared memory address. Hence LoadExclusive mayStore. 4612// 4613// Since these instructions have the undefined register bits set to 1 in 4614// their canonical form, we need a post encoder method to set those bits 4615// to 1 when encoding these instructions. We do this using the 4616// fixLoadStoreExclusive function. This function has template parameters: 4617// 4618// fixLoadStoreExclusive<int hasRs, int hasRt2> 4619// 4620// hasRs indicates that the instruction uses the Rs field, so we won't set 4621// it to 1 (and the same for Rt2). We don't need template parameters for 4622// the other register fields since Rt and Rn are always used. 4623// 4624let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4625class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4626 dag oops, dag iops, string asm, string operands> 4627 : I<oops, iops, asm, operands, "", []> { 4628 let Inst{31-30} = sz; 4629 let Inst{29-24} = 0b001000; 4630 let Inst{23} = o2; 4631 let Inst{22} = L; 4632 let Inst{21} = o1; 4633 let Inst{15} = o0; 4634 4635 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4636} 4637 4638// Neither Rs nor Rt2 operands. 4639class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4640 dag oops, dag iops, string asm, string operands> 4641 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4642 bits<5> Rt; 4643 bits<5> Rn; 4644 let Inst{20-16} = 0b11111; 4645 let Unpredictable{20-16} = 0b11111; 4646 let Inst{14-10} = 0b11111; 4647 let Unpredictable{14-10} = 0b11111; 4648 let Inst{9-5} = Rn; 4649 let Inst{4-0} = Rt; 4650 4651 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4652} 4653 4654// Simple load acquires don't set the exclusive monitor 4655let mayLoad = 1, mayStore = 0 in 4656class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4657 RegisterClass regtype, string asm> 4658 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4659 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4660 Sched<[WriteLD]>; 4661 4662class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4663 RegisterClass regtype, string asm> 4664 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4665 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4666 Sched<[WriteLD]>; 4667 4668class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4669 RegisterClass regtype, string asm> 4670 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4671 (outs regtype:$Rt, regtype:$Rt2), 4672 (ins GPR64sp0:$Rn), asm, 4673 "\t$Rt, $Rt2, [$Rn]">, 4674 Sched<[WriteLD, WriteLDHi]> { 4675 bits<5> Rt; 4676 bits<5> Rt2; 4677 bits<5> Rn; 4678 let Inst{14-10} = Rt2; 4679 let Inst{9-5} = Rn; 4680 let Inst{4-0} = Rt; 4681 4682 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4683} 4684 4685// Simple store release operations do not check the exclusive monitor. 4686let mayLoad = 0, mayStore = 1 in 4687class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4688 RegisterClass regtype, string asm> 4689 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4690 (ins regtype:$Rt, GPR64sp:$Rn), 4691 asm, "\t$Rt, [$Rn]">, 4692 Sched<[WriteST]>; 4693 4694let mayLoad = 1, mayStore = 1 in 4695class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4696 RegisterClass regtype, string asm> 4697 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4698 (ins regtype:$Rt, GPR64sp0:$Rn), 4699 asm, "\t$Ws, $Rt, [$Rn]">, 4700 Sched<[WriteSTX]> { 4701 bits<5> Ws; 4702 bits<5> Rt; 4703 bits<5> Rn; 4704 let Inst{20-16} = Ws; 4705 let Inst{9-5} = Rn; 4706 let Inst{4-0} = Rt; 4707 4708 let Constraints = "@earlyclobber $Ws"; 4709 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4710} 4711 4712class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4713 RegisterClass regtype, string asm> 4714 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4715 (outs GPR32:$Ws), 4716 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4717 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4718 Sched<[WriteSTX]> { 4719 bits<5> Ws; 4720 bits<5> Rt; 4721 bits<5> Rt2; 4722 bits<5> Rn; 4723 let Inst{20-16} = Ws; 4724 let Inst{14-10} = Rt2; 4725 let Inst{9-5} = Rn; 4726 let Inst{4-0} = Rt; 4727 4728 let Constraints = "@earlyclobber $Ws"; 4729} 4730 4731// Armv8.5-A Memory Tagging Extension 4732class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4733 string asm_opnds, string cstr, dag oops, dag iops> 4734 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4735 Sched<[]> { 4736 bits<5> Rn; 4737 4738 let Inst{31-24} = 0b11011001; 4739 let Inst{23-22} = opc1; 4740 let Inst{21} = 1; 4741 // Inst{20-12} defined by subclass 4742 let Inst{11-10} = opc2; 4743 let Inst{9-5} = Rn; 4744 // Inst{4-0} defined by subclass 4745} 4746 4747class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4748 dag oops, dag iops> 4749 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4750 "", oops, iops> { 4751 bits<5> Rt; 4752 4753 let Inst{20-12} = 0b000000000; 4754 let Inst{4-0} = Rt; 4755 4756 let mayLoad = Load; 4757} 4758 4759class MemTagLoad<string asm_insn, string asm_opnds> 4760 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4761 (outs GPR64:$wback), 4762 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4763 bits<5> Rt; 4764 bits<9> offset; 4765 4766 let Inst{20-12} = offset; 4767 let Inst{4-0} = Rt; 4768 4769 let mayLoad = 1; 4770} 4771 4772class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4773 string asm_opnds, string cstr, dag oops, dag iops> 4774 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4775 bits<5> Rt; 4776 bits<9> offset; 4777 4778 let Inst{20-12} = offset; 4779 let Inst{4-0} = Rt; 4780 4781 let mayStore = 1; 4782} 4783 4784multiclass MemTagStore<bits<2> opc1, string insn> { 4785 def i : 4786 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4787 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4788 def PreIndex : 4789 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4790 "$Rn = $wback", 4791 (outs GPR64sp:$wback), 4792 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4793 def PostIndex : 4794 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4795 "$Rn = $wback", 4796 (outs GPR64sp:$wback), 4797 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4798 4799 def : InstAlias<insn # "\t$Rt, [$Rn]", 4800 (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4801} 4802 4803//--- 4804// Exception generation 4805//--- 4806 4807let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4808class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4809 list<dag> pattern = []> 4810 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4811 Sched<[WriteSys]> { 4812 bits<16> imm; 4813 let Inst{31-24} = 0b11010100; 4814 let Inst{23-21} = op1; 4815 let Inst{20-5} = imm; 4816 let Inst{4-2} = 0b000; 4817 let Inst{1-0} = ll; 4818} 4819 4820//--- 4821// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4822//-- 4823let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4824class UDFType<bits<16> opc, string asm> 4825 : I<(outs), (ins uimm16:$imm), 4826 asm, "\t$imm", "", []>, 4827 Sched<[]> { 4828 bits<16> imm; 4829 let Inst{31-16} = opc; 4830 let Inst{15-0} = imm; 4831} 4832} 4833let Predicates = [HasFPARMv8] in { 4834 4835//--- 4836// Floating point to integer conversion 4837//--- 4838 4839let mayRaiseFPException = 1, Uses = [FPCR] in 4840class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4841 RegisterClass srcType, RegisterClass dstType, 4842 string asm, list<dag> pattern> 4843 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4844 asm, "\t$Rd, $Rn", "", pattern>, 4845 Sched<[WriteFCvt]> { 4846 bits<5> Rd; 4847 bits<5> Rn; 4848 let Inst{30-29} = 0b00; 4849 let Inst{28-24} = 0b11110; 4850 let Inst{23-22} = type; 4851 let Inst{21} = 1; 4852 let Inst{20-19} = rmode; 4853 let Inst{18-16} = opcode; 4854 let Inst{15-10} = 0; 4855 let Inst{9-5} = Rn; 4856 let Inst{4-0} = Rd; 4857} 4858 4859let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4860class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4861 RegisterClass srcType, RegisterClass dstType, 4862 Operand immType, string asm, list<dag> pattern> 4863 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4864 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4865 Sched<[WriteFCvt]> { 4866 bits<5> Rd; 4867 bits<5> Rn; 4868 bits<6> scale; 4869 let Inst{30-29} = 0b00; 4870 let Inst{28-24} = 0b11110; 4871 let Inst{23-22} = type; 4872 let Inst{21} = 0; 4873 let Inst{20-19} = rmode; 4874 let Inst{18-16} = opcode; 4875 let Inst{15-10} = scale; 4876 let Inst{9-5} = Rn; 4877 let Inst{4-0} = Rd; 4878} 4879 4880multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4881 SDPatternOperator OpN> { 4882 // Unscaled half-precision to 32-bit 4883 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4884 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4885 let Inst{31} = 0; // 32-bit GPR flag 4886 let Predicates = [HasFullFP16]; 4887 } 4888 4889 // Unscaled half-precision to 64-bit 4890 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4891 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4892 let Inst{31} = 1; // 64-bit GPR flag 4893 let Predicates = [HasFullFP16]; 4894 } 4895 4896 // Unscaled single-precision to 32-bit 4897 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4898 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4899 let Inst{31} = 0; // 32-bit GPR flag 4900 } 4901 4902 // Unscaled single-precision to 64-bit 4903 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4904 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4905 let Inst{31} = 1; // 64-bit GPR flag 4906 } 4907 4908 // Unscaled double-precision to 32-bit 4909 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4910 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4911 let Inst{31} = 0; // 32-bit GPR flag 4912 } 4913 4914 // Unscaled double-precision to 64-bit 4915 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4916 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4917 let Inst{31} = 1; // 64-bit GPR flag 4918 } 4919} 4920 4921multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4922 SDPatternOperator OpN> { 4923 // Scaled half-precision to 32-bit 4924 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4925 fixedpoint_f16_i32, asm, 4926 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4927 fixedpoint_f16_i32:$scale)))]> { 4928 let Inst{31} = 0; // 32-bit GPR flag 4929 let scale{5} = 1; 4930 let Predicates = [HasFullFP16]; 4931 } 4932 4933 // Scaled half-precision to 64-bit 4934 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4935 fixedpoint_f16_i64, asm, 4936 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 4937 fixedpoint_f16_i64:$scale)))]> { 4938 let Inst{31} = 1; // 64-bit GPR flag 4939 let Predicates = [HasFullFP16]; 4940 } 4941 4942 // Scaled single-precision to 32-bit 4943 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4944 fixedpoint_f32_i32, asm, 4945 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4946 fixedpoint_f32_i32:$scale)))]> { 4947 let Inst{31} = 0; // 32-bit GPR flag 4948 let scale{5} = 1; 4949 } 4950 4951 // Scaled single-precision to 64-bit 4952 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4953 fixedpoint_f32_i64, asm, 4954 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4955 fixedpoint_f32_i64:$scale)))]> { 4956 let Inst{31} = 1; // 64-bit GPR flag 4957 } 4958 4959 // Scaled double-precision to 32-bit 4960 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4961 fixedpoint_f64_i32, asm, 4962 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4963 fixedpoint_f64_i32:$scale)))]> { 4964 let Inst{31} = 0; // 32-bit GPR flag 4965 let scale{5} = 1; 4966 } 4967 4968 // Scaled double-precision to 64-bit 4969 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4970 fixedpoint_f64_i64, asm, 4971 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4972 fixedpoint_f64_i64:$scale)))]> { 4973 let Inst{31} = 1; // 64-bit GPR flag 4974 } 4975} 4976 4977//--- 4978// Integer to floating point conversion 4979//--- 4980 4981let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4982class BaseIntegerToFP<bit isUnsigned, 4983 RegisterClass srcType, RegisterClass dstType, 4984 Operand immType, string asm, list<dag> pattern> 4985 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4986 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4987 Sched<[WriteFCvt]> { 4988 bits<5> Rd; 4989 bits<5> Rn; 4990 bits<6> scale; 4991 let Inst{30-24} = 0b0011110; 4992 let Inst{21-17} = 0b00001; 4993 let Inst{16} = isUnsigned; 4994 let Inst{15-10} = scale; 4995 let Inst{9-5} = Rn; 4996 let Inst{4-0} = Rd; 4997} 4998 4999let mayRaiseFPException = 1, Uses = [FPCR] in 5000class BaseIntegerToFPUnscaled<bit isUnsigned, 5001 RegisterClass srcType, RegisterClass dstType, 5002 ValueType dvt, string asm, SDPatternOperator node> 5003 : I<(outs dstType:$Rd), (ins srcType:$Rn), 5004 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 5005 Sched<[WriteFCvt]> { 5006 bits<5> Rd; 5007 bits<5> Rn; 5008 bits<6> scale; 5009 let Inst{30-24} = 0b0011110; 5010 let Inst{21-17} = 0b10001; 5011 let Inst{16} = isUnsigned; 5012 let Inst{15-10} = 0b000000; 5013 let Inst{9-5} = Rn; 5014 let Inst{4-0} = Rd; 5015} 5016 5017multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 5018 // Unscaled 5019 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 5020 let Inst{31} = 0; // 32-bit GPR flag 5021 let Inst{23-22} = 0b11; // 16-bit FPR flag 5022 let Predicates = [HasFullFP16]; 5023 } 5024 5025 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 5026 let Inst{31} = 0; // 32-bit GPR flag 5027 let Inst{23-22} = 0b00; // 32-bit FPR flag 5028 } 5029 5030 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 5031 let Inst{31} = 0; // 32-bit GPR flag 5032 let Inst{23-22} = 0b01; // 64-bit FPR flag 5033 } 5034 5035 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 5036 let Inst{31} = 1; // 64-bit GPR flag 5037 let Inst{23-22} = 0b11; // 16-bit FPR flag 5038 let Predicates = [HasFullFP16]; 5039 } 5040 5041 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 5042 let Inst{31} = 1; // 64-bit GPR flag 5043 let Inst{23-22} = 0b00; // 32-bit FPR flag 5044 } 5045 5046 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 5047 let Inst{31} = 1; // 64-bit GPR flag 5048 let Inst{23-22} = 0b01; // 64-bit FPR flag 5049 } 5050 5051 // Scaled 5052 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_recip_f16_i32, asm, 5053 [(set (f16 FPR16:$Rd), 5054 (fmul (node GPR32:$Rn), 5055 fixedpoint_recip_f16_i32:$scale))]> { 5056 let Inst{31} = 0; // 32-bit GPR flag 5057 let Inst{23-22} = 0b11; // 16-bit FPR flag 5058 let scale{5} = 1; 5059 let Predicates = [HasFullFP16]; 5060 } 5061 5062 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_recip_f32_i32, asm, 5063 [(set FPR32:$Rd, 5064 (fmul (node GPR32:$Rn), 5065 fixedpoint_recip_f32_i32:$scale))]> { 5066 let Inst{31} = 0; // 32-bit GPR flag 5067 let Inst{23-22} = 0b00; // 32-bit FPR flag 5068 let scale{5} = 1; 5069 } 5070 5071 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_recip_f64_i32, asm, 5072 [(set FPR64:$Rd, 5073 (fmul (node GPR32:$Rn), 5074 fixedpoint_recip_f64_i32:$scale))]> { 5075 let Inst{31} = 0; // 32-bit GPR flag 5076 let Inst{23-22} = 0b01; // 64-bit FPR flag 5077 let scale{5} = 1; 5078 } 5079 5080 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_recip_f16_i64, asm, 5081 [(set (f16 FPR16:$Rd), 5082 (fmul (node GPR64:$Rn), 5083 fixedpoint_recip_f16_i64:$scale))]> { 5084 let Inst{31} = 1; // 64-bit GPR flag 5085 let Inst{23-22} = 0b11; // 16-bit FPR flag 5086 let Predicates = [HasFullFP16]; 5087 } 5088 5089 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_recip_f32_i64, asm, 5090 [(set FPR32:$Rd, 5091 (fmul (node GPR64:$Rn), 5092 fixedpoint_recip_f32_i64:$scale))]> { 5093 let Inst{31} = 1; // 64-bit GPR flag 5094 let Inst{23-22} = 0b00; // 32-bit FPR flag 5095 } 5096 5097 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_recip_f64_i64, asm, 5098 [(set FPR64:$Rd, 5099 (fmul (node GPR64:$Rn), 5100 fixedpoint_recip_f64_i64:$scale))]> { 5101 let Inst{31} = 1; // 64-bit GPR flag 5102 let Inst{23-22} = 0b01; // 64-bit FPR flag 5103 } 5104} 5105 5106//--- 5107// Unscaled integer <-> floating point conversion (i.e. FMOV) 5108//--- 5109 5110let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5111class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 5112 RegisterClass srcType, RegisterClass dstType, 5113 string asm> 5114 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 5115 // We use COPY_TO_REGCLASS for these bitconvert operations. 5116 // copyPhysReg() expands the resultant COPY instructions after 5117 // regalloc is done. This gives greater freedom for the allocator 5118 // and related passes (coalescing, copy propagation, et. al.) to 5119 // be more effective. 5120 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 5121 Sched<[WriteFCopy]> { 5122 bits<5> Rd; 5123 bits<5> Rn; 5124 let Inst{30-24} = 0b0011110; 5125 let Inst{21} = 1; 5126 let Inst{20-19} = rmode; 5127 let Inst{18-16} = opcode; 5128 let Inst{15-10} = 0b000000; 5129 let Inst{9-5} = Rn; 5130 let Inst{4-0} = Rd; 5131} 5132 5133let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5134class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 5135 RegisterClass srcType, RegisterOperand dstType, string asm, 5136 string kind> 5137 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5138 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 5139 Sched<[WriteFCopy]> { 5140 bits<5> Rd; 5141 bits<5> Rn; 5142 let Inst{30-23} = 0b00111101; 5143 let Inst{21} = 1; 5144 let Inst{20-19} = rmode; 5145 let Inst{18-16} = opcode; 5146 let Inst{15-10} = 0b000000; 5147 let Inst{9-5} = Rn; 5148 let Inst{4-0} = Rd; 5149 5150 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5151} 5152 5153let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5154class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 5155 RegisterOperand srcType, RegisterClass dstType, string asm, 5156 string kind> 5157 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5158 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 5159 Sched<[WriteFCopy]> { 5160 bits<5> Rd; 5161 bits<5> Rn; 5162 let Inst{30-23} = 0b00111101; 5163 let Inst{21} = 1; 5164 let Inst{20-19} = rmode; 5165 let Inst{18-16} = opcode; 5166 let Inst{15-10} = 0b000000; 5167 let Inst{9-5} = Rn; 5168 let Inst{4-0} = Rd; 5169 5170 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5171} 5172 5173 5174multiclass UnscaledConversion<string asm> { 5175 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 5176 let Inst{31} = 0; // 32-bit GPR flag 5177 let Inst{23-22} = 0b11; // 16-bit FPR flag 5178 let Predicates = [HasFullFP16]; 5179 } 5180 5181 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 5182 let Inst{31} = 1; // 64-bit GPR flag 5183 let Inst{23-22} = 0b11; // 16-bit FPR flag 5184 let Predicates = [HasFullFP16]; 5185 } 5186 5187 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 5188 let Inst{31} = 0; // 32-bit GPR flag 5189 let Inst{23-22} = 0b00; // 32-bit FPR flag 5190 } 5191 5192 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 5193 let Inst{31} = 1; // 64-bit GPR flag 5194 let Inst{23-22} = 0b01; // 64-bit FPR flag 5195 } 5196 5197 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 5198 let Inst{31} = 0; // 32-bit GPR flag 5199 let Inst{23-22} = 0b11; // 16-bit FPR flag 5200 let Predicates = [HasFullFP16]; 5201 } 5202 5203 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 5204 let Inst{31} = 1; // 64-bit GPR flag 5205 let Inst{23-22} = 0b11; // 16-bit FPR flag 5206 let Predicates = [HasFullFP16]; 5207 } 5208 5209 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 5210 let Inst{31} = 0; // 32-bit GPR flag 5211 let Inst{23-22} = 0b00; // 32-bit FPR flag 5212 } 5213 5214 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 5215 let Inst{31} = 1; // 64-bit GPR flag 5216 let Inst{23-22} = 0b01; // 64-bit FPR flag 5217 } 5218 5219 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 5220 asm, ".d"> { 5221 let Inst{31} = 1; 5222 let Inst{22} = 0; 5223 } 5224 5225 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 5226 asm, ".d"> { 5227 let Inst{31} = 1; 5228 let Inst{22} = 0; 5229 } 5230} 5231 5232//--- 5233// Floating point conversion 5234//--- 5235 5236let mayRaiseFPException = 1, Uses = [FPCR] in 5237class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 5238 RegisterClass srcType, string asm, list<dag> pattern> 5239 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 5240 Sched<[WriteFCvt]> { 5241 bits<5> Rd; 5242 bits<5> Rn; 5243 let Inst{31-24} = 0b00011110; 5244 let Inst{23-22} = type; 5245 let Inst{21-17} = 0b10001; 5246 let Inst{16-15} = opcode; 5247 let Inst{14-10} = 0b10000; 5248 let Inst{9-5} = Rn; 5249 let Inst{4-0} = Rd; 5250} 5251 5252multiclass FPConversion<string asm> { 5253 // Double-precision to Half-precision 5254 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 5255 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 5256 5257 // Double-precision to Single-precision 5258 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 5259 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5260 5261 // Half-precision to Double-precision 5262 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5263 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5264 5265 // Half-precision to Single-precision 5266 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5267 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5268 5269 // Single-precision to Double-precision 5270 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5271 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5272 5273 // Single-precision to Half-precision 5274 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5275 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5276} 5277 5278//--- 5279// Single operand floating point data processing 5280//--- 5281 5282let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5283class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5284 ValueType vt, string asm, SDPatternOperator node> 5285 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5286 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5287 Sched<[WriteF]> { 5288 bits<5> Rd; 5289 bits<5> Rn; 5290 let Inst{31-24} = 0b00011110; 5291 let Inst{21} = 0b1; 5292 let Inst{20-15} = opcode; 5293 let Inst{14-10} = 0b10000; 5294 let Inst{9-5} = Rn; 5295 let Inst{4-0} = Rd; 5296} 5297 5298multiclass SingleOperandFPData<bits<4> opcode, string asm, 5299 SDPatternOperator node = null_frag, 5300 int fpexceptions = 1> { 5301 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 5302 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5303 let Inst{23-22} = 0b11; // 16-bit size flag 5304 let Predicates = [HasFullFP16]; 5305 } 5306 5307 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5308 let Inst{23-22} = 0b00; // 32-bit size flag 5309 } 5310 5311 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5312 let Inst{23-22} = 0b01; // 64-bit size flag 5313 } 5314 } 5315} 5316 5317multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5318 SDPatternOperator node = null_frag> 5319 : SingleOperandFPData<opcode, asm, node, 0>; 5320 5321let mayRaiseFPException = 1, Uses = [FPCR] in 5322multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5323 SDPatternOperator node = null_frag>{ 5324 5325 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5326 let Inst{23-22} = 0b00; // 32-bit registers 5327 } 5328 5329 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5330 let Inst{23-22} = 0b01; // 64-bit registers 5331 } 5332} 5333 5334// FRInt[32|64][Z|N] instructions 5335multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5336 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5337 5338//--- 5339// Two operand floating point data processing 5340//--- 5341 5342let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5343class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5344 string asm, list<dag> pat> 5345 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5346 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5347 Sched<[WriteF]> { 5348 bits<5> Rd; 5349 bits<5> Rn; 5350 bits<5> Rm; 5351 let Inst{31-24} = 0b00011110; 5352 let Inst{21} = 1; 5353 let Inst{20-16} = Rm; 5354 let Inst{15-12} = opcode; 5355 let Inst{11-10} = 0b10; 5356 let Inst{9-5} = Rn; 5357 let Inst{4-0} = Rd; 5358} 5359 5360multiclass TwoOperandFPData<bits<4> opcode, string asm, 5361 SDPatternOperator node = null_frag> { 5362 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5363 [(set (f16 FPR16:$Rd), 5364 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5365 let Inst{23-22} = 0b11; // 16-bit size flag 5366 let Predicates = [HasFullFP16]; 5367 } 5368 5369 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5370 [(set (f32 FPR32:$Rd), 5371 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5372 let Inst{23-22} = 0b00; // 32-bit size flag 5373 } 5374 5375 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5376 [(set (f64 FPR64:$Rd), 5377 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5378 let Inst{23-22} = 0b01; // 64-bit size flag 5379 } 5380} 5381 5382multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5383 SDPatternOperator node> { 5384 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5385 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5386 let Inst{23-22} = 0b11; // 16-bit size flag 5387 let Predicates = [HasFullFP16]; 5388 } 5389 5390 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5391 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5392 let Inst{23-22} = 0b00; // 32-bit size flag 5393 } 5394 5395 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5396 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5397 let Inst{23-22} = 0b01; // 64-bit size flag 5398 } 5399} 5400 5401 5402//--- 5403// Three operand floating point data processing 5404//--- 5405 5406let mayRaiseFPException = 1, Uses = [FPCR] in 5407class BaseThreeOperandFPData<bit isNegated, bit isSub, 5408 RegisterClass regtype, string asm, list<dag> pat> 5409 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5410 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5411 Sched<[WriteFMul]> { 5412 bits<5> Rd; 5413 bits<5> Rn; 5414 bits<5> Rm; 5415 bits<5> Ra; 5416 let Inst{31-24} = 0b00011111; 5417 let Inst{21} = isNegated; 5418 let Inst{20-16} = Rm; 5419 let Inst{15} = isSub; 5420 let Inst{14-10} = Ra; 5421 let Inst{9-5} = Rn; 5422 let Inst{4-0} = Rd; 5423} 5424 5425multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5426 SDPatternOperator node> { 5427 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5428 [(set (f16 FPR16:$Rd), 5429 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5430 let Inst{23-22} = 0b11; // 16-bit size flag 5431 let Predicates = [HasFullFP16]; 5432 } 5433 5434 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5435 [(set FPR32:$Rd, 5436 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5437 let Inst{23-22} = 0b00; // 32-bit size flag 5438 } 5439 5440 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5441 [(set FPR64:$Rd, 5442 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5443 let Inst{23-22} = 0b01; // 64-bit size flag 5444 } 5445 5446 let Predicates = [HasFullFP16] in { 5447 def : Pat<(f16 (node (f16 FPR16:$Rn), 5448 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))), 5449 (f16 FPR16:$Ra))), 5450 (!cast<Instruction>(NAME # Hrrr) 5451 FPR16:$Rn, (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>; 5452 5453 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))), 5454 (f16 FPR16:$Rm), 5455 (f16 FPR16:$Ra))), 5456 (!cast<Instruction>(NAME # Hrrr) 5457 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>; 5458 } 5459 5460 def : Pat<(f32 (node (f32 FPR32:$Rn), 5461 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))), 5462 (f32 FPR32:$Ra))), 5463 (!cast<Instruction>(NAME # Srrr) 5464 FPR32:$Rn, (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>; 5465 5466 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))), 5467 (f32 FPR32:$Rm), 5468 (f32 FPR32:$Ra))), 5469 (!cast<Instruction>(NAME # Srrr) 5470 (EXTRACT_SUBREG V128:$Rn, ssub), FPR32:$Rm, FPR32:$Ra)>; 5471 5472 def : Pat<(f64 (node (f64 FPR64:$Rn), 5473 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))), 5474 (f64 FPR64:$Ra))), 5475 (!cast<Instruction>(NAME # Drrr) 5476 FPR64:$Rn, (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>; 5477 5478 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))), 5479 (f64 FPR64:$Rm), 5480 (f64 FPR64:$Ra))), 5481 (!cast<Instruction>(NAME # Drrr) 5482 (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>; 5483} 5484 5485//--- 5486// Floating point data comparisons 5487//--- 5488 5489let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5490class BaseOneOperandFPComparison<bit signalAllNans, 5491 RegisterClass regtype, string asm, 5492 list<dag> pat> 5493 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5494 Sched<[WriteFCmp]> { 5495 bits<5> Rn; 5496 let Inst{31-24} = 0b00011110; 5497 let Inst{21} = 1; 5498 5499 let Inst{15-10} = 0b001000; 5500 let Inst{9-5} = Rn; 5501 let Inst{4} = signalAllNans; 5502 let Inst{3-0} = 0b1000; 5503 5504 // Rm should be 0b00000 canonically, but we need to accept any value. 5505 let PostEncoderMethod = "fixOneOperandFPComparison"; 5506} 5507 5508let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5509class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5510 string asm, list<dag> pat> 5511 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5512 Sched<[WriteFCmp]> { 5513 bits<5> Rm; 5514 bits<5> Rn; 5515 let Inst{31-24} = 0b00011110; 5516 let Inst{21} = 1; 5517 let Inst{20-16} = Rm; 5518 let Inst{15-10} = 0b001000; 5519 let Inst{9-5} = Rn; 5520 let Inst{4} = signalAllNans; 5521 let Inst{3-0} = 0b0000; 5522} 5523 5524multiclass FPComparison<bit signalAllNans, string asm, 5525 SDPatternOperator OpNode = null_frag> { 5526 let Defs = [NZCV] in { 5527 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5528 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5529 let Inst{23-22} = 0b11; 5530 let Predicates = [HasFullFP16]; 5531 } 5532 5533 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5534 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5535 let Inst{23-22} = 0b11; 5536 let Predicates = [HasFullFP16]; 5537 } 5538 5539 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5540 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5541 let Inst{23-22} = 0b00; 5542 } 5543 5544 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5545 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5546 let Inst{23-22} = 0b00; 5547 } 5548 5549 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5550 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5551 let Inst{23-22} = 0b01; 5552 } 5553 5554 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5555 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5556 let Inst{23-22} = 0b01; 5557 } 5558 } // Defs = [NZCV] 5559} 5560 5561//--- 5562// Floating point conditional comparisons 5563//--- 5564 5565let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5566class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5567 string mnemonic, list<dag> pat> 5568 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5569 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5570 Sched<[WriteFCmp]> { 5571 let Uses = [NZCV]; 5572 let Defs = [NZCV]; 5573 5574 bits<5> Rn; 5575 bits<5> Rm; 5576 bits<4> nzcv; 5577 bits<4> cond; 5578 5579 let Inst{31-24} = 0b00011110; 5580 let Inst{21} = 1; 5581 let Inst{20-16} = Rm; 5582 let Inst{15-12} = cond; 5583 let Inst{11-10} = 0b01; 5584 let Inst{9-5} = Rn; 5585 let Inst{4} = signalAllNans; 5586 let Inst{3-0} = nzcv; 5587} 5588 5589multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5590 SDPatternOperator OpNode = null_frag> { 5591 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5592 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5593 (i32 imm:$cond), NZCV))]> { 5594 let Inst{23-22} = 0b11; 5595 let Predicates = [HasFullFP16]; 5596 } 5597 5598 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5599 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5600 (i32 imm:$cond), NZCV))]> { 5601 let Inst{23-22} = 0b00; 5602 } 5603 5604 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5605 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5606 (i32 imm:$cond), NZCV))]> { 5607 let Inst{23-22} = 0b01; 5608 } 5609} 5610 5611//--- 5612// Floating point conditional select 5613//--- 5614 5615class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5616 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5617 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5618 [(set regtype:$Rd, 5619 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5620 (i32 imm:$cond), NZCV))]>, 5621 Sched<[WriteF]> { 5622 bits<5> Rd; 5623 bits<5> Rn; 5624 bits<5> Rm; 5625 bits<4> cond; 5626 5627 let Inst{31-24} = 0b00011110; 5628 let Inst{21} = 1; 5629 let Inst{20-16} = Rm; 5630 let Inst{15-12} = cond; 5631 let Inst{11-10} = 0b11; 5632 let Inst{9-5} = Rn; 5633 let Inst{4-0} = Rd; 5634} 5635 5636multiclass FPCondSelect<string asm> { 5637 let Uses = [NZCV] in { 5638 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5639 let Inst{23-22} = 0b11; 5640 let Predicates = [HasFullFP16]; 5641 } 5642 5643 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5644 let Inst{23-22} = 0b00; 5645 } 5646 5647 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5648 let Inst{23-22} = 0b01; 5649 } 5650 } // Uses = [NZCV] 5651} 5652 5653//--- 5654// Floating move immediate 5655//--- 5656 5657class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5658 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5659 [(set regtype:$Rd, fpimmtype:$imm)]>, 5660 Sched<[WriteFImm]> { 5661 bits<5> Rd; 5662 bits<8> imm; 5663 let Inst{31-24} = 0b00011110; 5664 let Inst{21} = 1; 5665 let Inst{20-13} = imm; 5666 let Inst{12-5} = 0b10000000; 5667 let Inst{4-0} = Rd; 5668} 5669 5670multiclass FPMoveImmediate<string asm> { 5671 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5672 let Inst{23-22} = 0b11; 5673 let Predicates = [HasFullFP16]; 5674 } 5675 5676 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5677 let Inst{23-22} = 0b00; 5678 } 5679 5680 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5681 let Inst{23-22} = 0b01; 5682 } 5683} 5684} // end of 'let Predicates = [HasFPARMv8]' 5685 5686//---------------------------------------------------------------------------- 5687// AdvSIMD 5688//---------------------------------------------------------------------------- 5689 5690let Predicates = [HasNEON] in { 5691 5692//---------------------------------------------------------------------------- 5693// AdvSIMD three register vector instructions 5694//---------------------------------------------------------------------------- 5695 5696let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5697class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5698 RegisterOperand regtype, string asm, string kind, 5699 list<dag> pattern> 5700 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5701 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5702 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5703 Sched<[!if(Q, WriteVq, WriteVd)]> { 5704 bits<5> Rd; 5705 bits<5> Rn; 5706 bits<5> Rm; 5707 let Inst{31} = 0; 5708 let Inst{30} = Q; 5709 let Inst{29} = U; 5710 let Inst{28-24} = 0b01110; 5711 let Inst{23-21} = size; 5712 let Inst{20-16} = Rm; 5713 let Inst{15-11} = opcode; 5714 let Inst{10} = 1; 5715 let Inst{9-5} = Rn; 5716 let Inst{4-0} = Rd; 5717} 5718 5719let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5720class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5721 RegisterOperand regtype, string asm, string kind, 5722 list<dag> pattern> 5723 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5724 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5725 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5726 Sched<[!if(Q, WriteVq, WriteVd)]> { 5727 bits<5> Rd; 5728 bits<5> Rn; 5729 bits<5> Rm; 5730 let Inst{31} = 0; 5731 let Inst{30} = Q; 5732 let Inst{29} = U; 5733 let Inst{28-24} = 0b01110; 5734 let Inst{23-21} = size; 5735 let Inst{20-16} = Rm; 5736 let Inst{15-11} = opcode; 5737 let Inst{10} = 1; 5738 let Inst{9-5} = Rn; 5739 let Inst{4-0} = Rd; 5740} 5741 5742let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5743class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5744 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5745 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5746 5747multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5748 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5749 [(set (v8i8 V64:$dst), 5750 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5751 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5752 [(set (v16i8 V128:$dst), 5753 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5754 (v16i8 V128:$Rm)))]>; 5755 5756 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5757 (v4i16 V64:$RHS))), 5758 (!cast<Instruction>(NAME#"v8i8") 5759 V64:$LHS, V64:$MHS, V64:$RHS)>; 5760 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5761 (v2i32 V64:$RHS))), 5762 (!cast<Instruction>(NAME#"v8i8") 5763 V64:$LHS, V64:$MHS, V64:$RHS)>; 5764 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5765 (v1i64 V64:$RHS))), 5766 (!cast<Instruction>(NAME#"v8i8") 5767 V64:$LHS, V64:$MHS, V64:$RHS)>; 5768 5769 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5770 (v8i16 V128:$RHS))), 5771 (!cast<Instruction>(NAME#"v16i8") 5772 V128:$LHS, V128:$MHS, V128:$RHS)>; 5773 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5774 (v4i32 V128:$RHS))), 5775 (!cast<Instruction>(NAME#"v16i8") 5776 V128:$LHS, V128:$MHS, V128:$RHS)>; 5777 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5778 (v2i64 V128:$RHS))), 5779 (!cast<Instruction>(NAME#"v16i8") 5780 V128:$LHS, V128:$MHS, V128:$RHS)>; 5781} 5782 5783// All operand sizes distinguished in the encoding. 5784multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5785 SDPatternOperator OpNode> { 5786 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5787 asm, ".8b", 5788 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5789 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5790 asm, ".16b", 5791 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5792 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5793 asm, ".4h", 5794 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5795 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5796 asm, ".8h", 5797 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5798 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5799 asm, ".2s", 5800 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5801 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5802 asm, ".4s", 5803 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5804 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5805 asm, ".2d", 5806 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5807} 5808 5809multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5810 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5811 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5812 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5813 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5814 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5815 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5816 5817 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5818 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5819 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5820 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5821 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5822 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5823 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5824 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5825} 5826 5827// As above, but D sized elements unsupported. 5828multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5829 SDPatternOperator OpNode> { 5830 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5831 asm, ".8b", 5832 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5833 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5834 asm, ".16b", 5835 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5836 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5837 asm, ".4h", 5838 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5839 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5840 asm, ".8h", 5841 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5842 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5843 asm, ".2s", 5844 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5845 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5846 asm, ".4s", 5847 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5848} 5849 5850multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5851 SDPatternOperator OpNode> { 5852 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5853 asm, ".8b", 5854 [(set (v8i8 V64:$dst), 5855 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5856 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5857 asm, ".16b", 5858 [(set (v16i8 V128:$dst), 5859 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5860 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5861 asm, ".4h", 5862 [(set (v4i16 V64:$dst), 5863 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5864 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5865 asm, ".8h", 5866 [(set (v8i16 V128:$dst), 5867 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5868 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5869 asm, ".2s", 5870 [(set (v2i32 V64:$dst), 5871 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5872 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5873 asm, ".4s", 5874 [(set (v4i32 V128:$dst), 5875 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5876} 5877 5878// As above, but only B sized elements supported. 5879multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5880 SDPatternOperator OpNode> { 5881 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5882 asm, ".8b", 5883 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5884 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5885 asm, ".16b", 5886 [(set (v16i8 V128:$Rd), 5887 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5888} 5889 5890// As above, but only floating point elements supported. 5891let mayRaiseFPException = 1, Uses = [FPCR] in 5892multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5893 string asm, SDPatternOperator OpNode> { 5894 let Predicates = [HasNEON, HasFullFP16] in { 5895 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5896 asm, ".4h", 5897 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5898 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5899 asm, ".8h", 5900 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5901 } // Predicates = [HasNEON, HasFullFP16] 5902 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5903 asm, ".2s", 5904 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5905 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5906 asm, ".4s", 5907 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5908 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5909 asm, ".2d", 5910 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5911} 5912 5913let mayRaiseFPException = 1, Uses = [FPCR] in 5914multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5915 string asm, 5916 SDPatternOperator OpNode> { 5917 let Predicates = [HasNEON, HasFullFP16] in { 5918 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5919 asm, ".4h", 5920 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5921 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5922 asm, ".8h", 5923 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5924 } // Predicates = [HasNEON, HasFullFP16] 5925 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5926 asm, ".2s", 5927 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5928 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5929 asm, ".4s", 5930 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5931 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5932 asm, ".2d", 5933 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5934} 5935 5936let mayRaiseFPException = 1, Uses = [FPCR] in 5937multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5938 string asm, SDPatternOperator OpNode> { 5939 let Predicates = [HasNEON, HasFullFP16] in { 5940 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5941 asm, ".4h", 5942 [(set (v4f16 V64:$dst), 5943 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5944 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5945 asm, ".8h", 5946 [(set (v8f16 V128:$dst), 5947 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5948 } // Predicates = [HasNEON, HasFullFP16] 5949 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5950 asm, ".2s", 5951 [(set (v2f32 V64:$dst), 5952 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5953 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5954 asm, ".4s", 5955 [(set (v4f32 V128:$dst), 5956 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5957 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5958 asm, ".2d", 5959 [(set (v2f64 V128:$dst), 5960 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5961} 5962 5963// As above, but D and B sized elements unsupported. 5964let mayRaiseFPException = 1, Uses = [FPCR] in 5965multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5966 SDPatternOperator OpNode> { 5967 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5968 asm, ".4h", 5969 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5970 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5971 asm, ".8h", 5972 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5973 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5974 asm, ".2s", 5975 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5976 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5977 asm, ".4s", 5978 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5979} 5980 5981// Logical three vector ops share opcode bits, and only use B sized elements. 5982multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5983 SDPatternOperator OpNode = null_frag> { 5984 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5985 asm, ".8b", 5986 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5987 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5988 asm, ".16b", 5989 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5990 5991 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5992 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5993 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5994 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5995 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5996 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5997 5998 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5999 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6000 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 6001 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6002 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 6003 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6004} 6005 6006multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 6007 string asm, SDPatternOperator OpNode = null_frag> { 6008 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 6009 asm, ".8b", 6010 [(set (v8i8 V64:$dst), 6011 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6012 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 6013 asm, ".16b", 6014 [(set (v16i8 V128:$dst), 6015 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 6016 (v16i8 V128:$Rm)))]>; 6017 6018 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 6019 (v4i16 V64:$RHS))), 6020 (!cast<Instruction>(NAME#"v8i8") 6021 V64:$LHS, V64:$MHS, V64:$RHS)>; 6022 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 6023 (v2i32 V64:$RHS))), 6024 (!cast<Instruction>(NAME#"v8i8") 6025 V64:$LHS, V64:$MHS, V64:$RHS)>; 6026 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 6027 (v1i64 V64:$RHS))), 6028 (!cast<Instruction>(NAME#"v8i8") 6029 V64:$LHS, V64:$MHS, V64:$RHS)>; 6030 6031 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 6032 (v8i16 V128:$RHS))), 6033 (!cast<Instruction>(NAME#"v16i8") 6034 V128:$LHS, V128:$MHS, V128:$RHS)>; 6035 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 6036 (v4i32 V128:$RHS))), 6037 (!cast<Instruction>(NAME#"v16i8") 6038 V128:$LHS, V128:$MHS, V128:$RHS)>; 6039 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 6040 (v2i64 V128:$RHS))), 6041 (!cast<Instruction>(NAME#"v16i8") 6042 V128:$LHS, V128:$MHS, V128:$RHS)>; 6043} 6044 6045// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 6046// bytes from S-sized elements. 6047class BaseSIMDThreeSameVectorDot<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 6048 string kind1, string kind2, RegisterOperand RegType, 6049 ValueType AccumType, ValueType InputType, 6050 SDPatternOperator OpNode> : 6051 BaseSIMDThreeSameVectorTied<Q, U, {sz, 0b0}, {0b1, opc}, RegType, asm, kind1, 6052 [(set (AccumType RegType:$dst), 6053 (OpNode (AccumType RegType:$Rd), 6054 (InputType RegType:$Rn), 6055 (InputType RegType:$Rm)))]> { 6056 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6057} 6058 6059multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 6060 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, 0b10, {0b001, Mixed}, asm, ".2s", ".8b", V64, 6061 v2i32, v8i8, OpNode>; 6062 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, 0b10, {0b001, Mixed}, asm, ".4s", ".16b", V128, 6063 v4i32, v16i8, OpNode>; 6064} 6065 6066// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 6067// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 6068// 8H to 4S, when Q=1). 6069let mayRaiseFPException = 1, Uses = [FPCR] in 6070class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 6071 string kind2, RegisterOperand RegType, 6072 ValueType AccumType, ValueType InputType, 6073 SDPatternOperator OpNode> : 6074 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 6075 [(set (AccumType RegType:$dst), 6076 (OpNode (AccumType RegType:$Rd), 6077 (InputType RegType:$Rn), 6078 (InputType RegType:$Rm)))]> { 6079 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6080 let Inst{13} = b13; 6081} 6082 6083multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 6084 SDPatternOperator OpNode> { 6085 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 6086 v2f32, v4f16, OpNode>; 6087 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 6088 v4f32, v8f16, OpNode>; 6089} 6090 6091multiclass SIMDThreeSameVectorMLA<bit Q, string asm>{ 6092 def v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b", 6093 V128, v8f16, v16i8, null_frag>; 6094} 6095 6096multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm>{ 6097 def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b", 6098 V128, v4f32, v16i8, null_frag>; 6099} 6100 6101// FP8 assembly/disassembly classes 6102 6103//---------------------------------------------------------------------------- 6104// FP8 Advanced SIMD three-register extension 6105//---------------------------------------------------------------------------- 6106class BaseSIMDThreeVectors<bit Q, bit U, bits<2> size, bits<4> op, 6107 RegisterOperand regtype1, 6108 RegisterOperand regtype2, string asm, 6109 string kind1, string kind2> 6110 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, regtype2:$Rm), asm, 6111 "\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2, "", []>, Sched<[]> { 6112 bits<5> Rd; 6113 bits<5> Rn; 6114 bits<5> Rm; 6115 let Inst{31} = 0; 6116 let Inst{30} = Q; 6117 let Inst{29} = U; 6118 let Inst{28-24} = 0b01110; 6119 let Inst{23-22} = size; 6120 let Inst{21} = 0b0; 6121 let Inst{20-16} = Rm; 6122 let Inst{15} = 0b1; 6123 let Inst{14-11} = op; 6124 let Inst{10} = 0b1; 6125 let Inst{9-5} = Rn; 6126 let Inst{4-0} = Rd; 6127} 6128 6129 6130// FCVTN (FP16 to FP8) 6131multiclass SIMDThreeSameSizeVectorCvt<string asm> { 6132 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b01, 0b1110, V64, V64, asm, ".8b",".4h">; 6133 def v16f8 : BaseSIMDThreeVectors<0b1, 0b0, 0b01, 0b1110, V128, V128, asm, ".16b", ".8h">; 6134} 6135 6136// TODO : Create v16f8 value type 6137// FCVTN, FCVTN2 (FP32 to FP8) 6138multiclass SIMDThreeVectorCvt<string asm> { 6139 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b00, 0b1110, V64, V128, asm, ".8b", ".4s">; 6140 def 2v16f8 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1110, asm#2, ".16b", ".4s", 6141 V128, v16i8, v4f32, null_frag>; 6142} 6143 6144// TODO: Create a new Value Type v8f8 and v16f8 6145multiclass SIMDThreeSameVectorDOT2<string asm> { 6146 def v4f16 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b01, 0b1111, asm, ".4h", ".8b", 6147 V64, v4f16, v8i8, null_frag>; 6148 def v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1111, asm, ".8h", ".16b", 6149 V128, v8f16, v16i8, null_frag>; 6150} 6151 6152multiclass SIMDThreeSameVectorDOT4<string asm> { 6153 def v2f32 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b00, 0b1111, asm, ".2s", ".8b", 6154 V64, v2f32, v8i8, null_frag>; 6155 def v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1111, asm, ".4s", ".16b", 6156 V128, v4f32, v16i8, null_frag>; 6157} 6158 6159//---------------------------------------------------------------------------- 6160// AdvSIMD two register vector instructions. 6161//---------------------------------------------------------------------------- 6162 6163let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6164class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6165 bits<2> size2, RegisterOperand regtype, string asm, 6166 string dstkind, string srckind, list<dag> pattern> 6167 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6168 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6169 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 6170 Sched<[!if(Q, WriteVq, WriteVd)]> { 6171 bits<5> Rd; 6172 bits<5> Rn; 6173 let Inst{31} = 0; 6174 let Inst{30} = Q; 6175 let Inst{29} = U; 6176 let Inst{28-24} = 0b01110; 6177 let Inst{23-22} = size; 6178 let Inst{21} = 0b1; 6179 let Inst{20-19} = size2; 6180 let Inst{18-17} = 0b00; 6181 let Inst{16-12} = opcode; 6182 let Inst{11-10} = 0b10; 6183 let Inst{9-5} = Rn; 6184 let Inst{4-0} = Rd; 6185} 6186 6187let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6188class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6189 bits<2> size2, RegisterOperand regtype, 6190 string asm, string dstkind, string srckind, 6191 list<dag> pattern> 6192 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 6193 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6194 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6195 Sched<[!if(Q, WriteVq, WriteVd)]> { 6196 bits<5> Rd; 6197 bits<5> Rn; 6198 let Inst{31} = 0; 6199 let Inst{30} = Q; 6200 let Inst{29} = U; 6201 let Inst{28-24} = 0b01110; 6202 let Inst{23-22} = size; 6203 let Inst{21} = 0b1; 6204 let Inst{20-19} = size2; 6205 let Inst{18-17} = 0b00; 6206 let Inst{16-12} = opcode; 6207 let Inst{11-10} = 0b10; 6208 let Inst{9-5} = Rn; 6209 let Inst{4-0} = Rd; 6210} 6211 6212// Supports B, H, and S element sizes. 6213multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 6214 SDPatternOperator OpNode> { 6215 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6216 asm, ".8b", ".8b", 6217 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6218 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6219 asm, ".16b", ".16b", 6220 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6221 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6222 asm, ".4h", ".4h", 6223 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6224 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6225 asm, ".8h", ".8h", 6226 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6227 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6228 asm, ".2s", ".2s", 6229 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6230 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6231 asm, ".4s", ".4s", 6232 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6233} 6234 6235class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 6236 RegisterOperand regtype, string asm, string dstkind, 6237 string srckind, string amount> 6238 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 6239 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 6240 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 6241 Sched<[WriteVq]> { 6242 bits<5> Rd; 6243 bits<5> Rn; 6244 let Inst{31} = 0; 6245 let Inst{30} = Q; 6246 let Inst{29-24} = 0b101110; 6247 let Inst{23-22} = size; 6248 let Inst{21-10} = 0b100001001110; 6249 let Inst{9-5} = Rn; 6250 let Inst{4-0} = Rd; 6251} 6252 6253multiclass SIMDVectorLShiftLongBySizeBHS { 6254 let hasSideEffects = 0 in { 6255 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 6256 "shll", ".8h", ".8b", "8">; 6257 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 6258 "shll2", ".8h", ".16b", "8">; 6259 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 6260 "shll", ".4s", ".4h", "16">; 6261 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 6262 "shll2", ".4s", ".8h", "16">; 6263 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 6264 "shll", ".2d", ".2s", "32">; 6265 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 6266 "shll2", ".2d", ".4s", "32">; 6267 } 6268} 6269 6270// Supports all element sizes. 6271multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 6272 SDPatternOperator OpNode> { 6273 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6274 asm, ".4h", ".8b", 6275 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6276 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6277 asm, ".8h", ".16b", 6278 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6279 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6280 asm, ".2s", ".4h", 6281 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6282 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6283 asm, ".4s", ".8h", 6284 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6285 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6286 asm, ".1d", ".2s", 6287 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6288 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6289 asm, ".2d", ".4s", 6290 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6291} 6292 6293multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 6294 SDPatternOperator OpNode> { 6295 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6296 asm, ".4h", ".8b", 6297 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 6298 (v8i8 V64:$Rn)))]>; 6299 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6300 asm, ".8h", ".16b", 6301 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 6302 (v16i8 V128:$Rn)))]>; 6303 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6304 asm, ".2s", ".4h", 6305 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 6306 (v4i16 V64:$Rn)))]>; 6307 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6308 asm, ".4s", ".8h", 6309 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 6310 (v8i16 V128:$Rn)))]>; 6311 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6312 asm, ".1d", ".2s", 6313 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 6314 (v2i32 V64:$Rn)))]>; 6315 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6316 asm, ".2d", ".4s", 6317 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 6318 (v4i32 V128:$Rn)))]>; 6319} 6320 6321// Supports all element sizes, except 1xD. 6322multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 6323 SDPatternOperator OpNode> { 6324 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6325 asm, ".8b", ".8b", 6326 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 6327 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6328 asm, ".16b", ".16b", 6329 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 6330 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6331 asm, ".4h", ".4h", 6332 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 6333 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6334 asm, ".8h", ".8h", 6335 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 6336 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6337 asm, ".2s", ".2s", 6338 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 6339 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6340 asm, ".4s", ".4s", 6341 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 6342 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 6343 asm, ".2d", ".2d", 6344 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 6345} 6346 6347multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 6348 SDPatternOperator OpNode = null_frag> { 6349 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6350 asm, ".8b", ".8b", 6351 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6352 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6353 asm, ".16b", ".16b", 6354 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6355 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6356 asm, ".4h", ".4h", 6357 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6358 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6359 asm, ".8h", ".8h", 6360 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6361 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6362 asm, ".2s", ".2s", 6363 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6364 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6365 asm, ".4s", ".4s", 6366 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6367 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6368 asm, ".2d", ".2d", 6369 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6370} 6371 6372 6373// Supports only B element sizes. 6374multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6375 SDPatternOperator OpNode> { 6376 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6377 asm, ".8b", ".8b", 6378 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6379 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6380 asm, ".16b", ".16b", 6381 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6382 6383} 6384 6385// Supports only B and H element sizes. 6386multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6387 SDPatternOperator OpNode> { 6388 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6389 asm, ".8b", ".8b", 6390 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6391 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6392 asm, ".16b", ".16b", 6393 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6394 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6395 asm, ".4h", ".4h", 6396 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6397 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6398 asm, ".8h", ".8h", 6399 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6400} 6401 6402// Supports H, S and D element sizes, uses high bit of the size field 6403// as an extra opcode bit. 6404multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6405 SDPatternOperator OpNode, 6406 int fpexceptions = 1> { 6407 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 6408 let Predicates = [HasNEON, HasFullFP16] in { 6409 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6410 asm, ".4h", ".4h", 6411 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6412 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6413 asm, ".8h", ".8h", 6414 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6415 } // Predicates = [HasNEON, HasFullFP16] 6416 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6417 asm, ".2s", ".2s", 6418 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6419 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6420 asm, ".4s", ".4s", 6421 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6422 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6423 asm, ".2d", ".2d", 6424 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6425 } 6426} 6427 6428multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6429 SDPatternOperator OpNode> 6430 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6431 6432// Supports only S and D element sizes 6433let mayRaiseFPException = 1, Uses = [FPCR] in 6434multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6435 SDPatternOperator OpNode = null_frag> { 6436 6437 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6438 asm, ".2s", ".2s", 6439 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6440 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6441 asm, ".4s", ".4s", 6442 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6443 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6444 asm, ".2d", ".2d", 6445 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6446} 6447 6448multiclass FRIntNNTVector<bit U, bit op, string asm, 6449 SDPatternOperator OpNode = null_frag> : 6450 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6451 6452// Supports only S element size. 6453multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6454 SDPatternOperator OpNode> { 6455 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6456 asm, ".2s", ".2s", 6457 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6458 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6459 asm, ".4s", ".4s", 6460 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6461} 6462 6463let mayRaiseFPException = 1, Uses = [FPCR] in 6464multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6465 SDPatternOperator OpNode> { 6466 let Predicates = [HasNEON, HasFullFP16] in { 6467 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6468 asm, ".4h", ".4h", 6469 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6470 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6471 asm, ".8h", ".8h", 6472 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6473 } // Predicates = [HasNEON, HasFullFP16] 6474 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6475 asm, ".2s", ".2s", 6476 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6477 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6478 asm, ".4s", ".4s", 6479 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6480 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6481 asm, ".2d", ".2d", 6482 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6483} 6484 6485let mayRaiseFPException = 1, Uses = [FPCR] in 6486multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6487 SDPatternOperator OpNode> { 6488 let Predicates = [HasNEON, HasFullFP16] in { 6489 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6490 asm, ".4h", ".4h", 6491 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6492 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6493 asm, ".8h", ".8h", 6494 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6495 } // Predicates = [HasNEON, HasFullFP16] 6496 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6497 asm, ".2s", ".2s", 6498 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6499 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6500 asm, ".4s", ".4s", 6501 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6502 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6503 asm, ".2d", ".2d", 6504 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6505} 6506 6507let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6508class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6509 RegisterOperand inreg, RegisterOperand outreg, 6510 string asm, string outkind, string inkind, 6511 list<dag> pattern> 6512 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6513 "{\t$Rd" # outkind # ", $Rn" # inkind # 6514 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6515 Sched<[WriteVq]> { 6516 bits<5> Rd; 6517 bits<5> Rn; 6518 let Inst{31} = 0; 6519 let Inst{30} = Q; 6520 let Inst{29} = U; 6521 let Inst{28-24} = 0b01110; 6522 let Inst{23-22} = size; 6523 let Inst{21-17} = 0b10000; 6524 let Inst{16-12} = opcode; 6525 let Inst{11-10} = 0b10; 6526 let Inst{9-5} = Rn; 6527 let Inst{4-0} = Rd; 6528} 6529 6530let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6531class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6532 RegisterOperand inreg, RegisterOperand outreg, 6533 string asm, string outkind, string inkind, 6534 list<dag> pattern> 6535 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6536 "{\t$Rd" # outkind # ", $Rn" # inkind # 6537 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6538 Sched<[WriteVq]> { 6539 bits<5> Rd; 6540 bits<5> Rn; 6541 let Inst{31} = 0; 6542 let Inst{30} = Q; 6543 let Inst{29} = U; 6544 let Inst{28-24} = 0b01110; 6545 let Inst{23-22} = size; 6546 let Inst{21-17} = 0b10000; 6547 let Inst{16-12} = opcode; 6548 let Inst{11-10} = 0b10; 6549 let Inst{9-5} = Rn; 6550 let Inst{4-0} = Rd; 6551} 6552 6553multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6554 SDPatternOperator OpNode> { 6555 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6556 asm, ".8b", ".8h", 6557 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6558 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6559 asm#"2", ".16b", ".8h", []>; 6560 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6561 asm, ".4h", ".4s", 6562 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6563 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6564 asm#"2", ".8h", ".4s", []>; 6565 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6566 asm, ".2s", ".2d", 6567 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6568 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6569 asm#"2", ".4s", ".2d", []>; 6570 6571 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6572 (!cast<Instruction>(NAME # "v16i8") 6573 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6574 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6575 (!cast<Instruction>(NAME # "v8i16") 6576 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6577 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6578 (!cast<Instruction>(NAME # "v4i32") 6579 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6580} 6581 6582//---------------------------------------------------------------------------- 6583// FP8 Advanced SIMD two-register miscellaneous 6584//---------------------------------------------------------------------------- 6585multiclass SIMDMixedTwoVectorFP8<bits<2>sz, string asm> { 6586 def v8f16 : BaseSIMDMixedTwoVector<0b0, 0b1, sz, 0b10111, V64, V128, 6587 asm, ".8h", ".8b", []>; 6588 def 2v8f16 : BaseSIMDMixedTwoVector<0b1, 0b1, sz, 0b10111, V128, V128, 6589 asm#2, ".8h", ".16b", []>; 6590} 6591 6592class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6593 bits<5> opcode, RegisterOperand regtype, string asm, 6594 string kind, string zero, ValueType dty, 6595 ValueType sty, SDNode OpNode> 6596 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6597 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6598 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6599 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6600 Sched<[!if(Q, WriteVq, WriteVd)]> { 6601 bits<5> Rd; 6602 bits<5> Rn; 6603 let Inst{31} = 0; 6604 let Inst{30} = Q; 6605 let Inst{29} = U; 6606 let Inst{28-24} = 0b01110; 6607 let Inst{23-22} = size; 6608 let Inst{21} = 0b1; 6609 let Inst{20-19} = size2; 6610 let Inst{18-17} = 0b00; 6611 let Inst{16-12} = opcode; 6612 let Inst{11-10} = 0b10; 6613 let Inst{9-5} = Rn; 6614 let Inst{4-0} = Rd; 6615} 6616 6617// Comparisons support all element sizes, except 1xD. 6618multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6619 SDNode OpNode> { 6620 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6621 asm, ".8b", "0", 6622 v8i8, v8i8, OpNode>; 6623 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6624 asm, ".16b", "0", 6625 v16i8, v16i8, OpNode>; 6626 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6627 asm, ".4h", "0", 6628 v4i16, v4i16, OpNode>; 6629 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6630 asm, ".8h", "0", 6631 v8i16, v8i16, OpNode>; 6632 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6633 asm, ".2s", "0", 6634 v2i32, v2i32, OpNode>; 6635 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6636 asm, ".4s", "0", 6637 v4i32, v4i32, OpNode>; 6638 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6639 asm, ".2d", "0", 6640 v2i64, v2i64, OpNode>; 6641} 6642 6643// FP Comparisons support only S and D element sizes (and H for v8.2a). 6644multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6645 string asm, SDNode OpNode> { 6646 6647 let mayRaiseFPException = 1, Uses = [FPCR] in { 6648 let Predicates = [HasNEON, HasFullFP16] in { 6649 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6650 asm, ".4h", "0.0", 6651 v4i16, v4f16, OpNode>; 6652 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6653 asm, ".8h", "0.0", 6654 v8i16, v8f16, OpNode>; 6655 } // Predicates = [HasNEON, HasFullFP16] 6656 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6657 asm, ".2s", "0.0", 6658 v2i32, v2f32, OpNode>; 6659 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6660 asm, ".4s", "0.0", 6661 v4i32, v4f32, OpNode>; 6662 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6663 asm, ".2d", "0.0", 6664 v2i64, v2f64, OpNode>; 6665 } 6666 6667 let Predicates = [HasNEON, HasFullFP16] in { 6668 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6669 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6670 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6671 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6672 } 6673 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6674 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6675 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6676 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6677 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6678 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6679 let Predicates = [HasNEON, HasFullFP16] in { 6680 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6681 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6682 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6683 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6684 } 6685 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6686 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6687 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6688 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6689 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6690 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6691} 6692 6693let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6694class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6695 RegisterOperand outtype, RegisterOperand intype, 6696 string asm, string VdTy, string VnTy, 6697 list<dag> pattern> 6698 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6699 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6700 Sched<[WriteVq]> { 6701 bits<5> Rd; 6702 bits<5> Rn; 6703 let Inst{31} = 0; 6704 let Inst{30} = Q; 6705 let Inst{29} = U; 6706 let Inst{28-24} = 0b01110; 6707 let Inst{23-22} = size; 6708 let Inst{21-17} = 0b10000; 6709 let Inst{16-12} = opcode; 6710 let Inst{11-10} = 0b10; 6711 let Inst{9-5} = Rn; 6712 let Inst{4-0} = Rd; 6713} 6714 6715let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6716class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6717 RegisterOperand outtype, RegisterOperand intype, 6718 string asm, string VdTy, string VnTy, 6719 list<dag> pattern> 6720 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6721 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6722 Sched<[WriteVq]> { 6723 bits<5> Rd; 6724 bits<5> Rn; 6725 let Inst{31} = 0; 6726 let Inst{30} = Q; 6727 let Inst{29} = U; 6728 let Inst{28-24} = 0b01110; 6729 let Inst{23-22} = size; 6730 let Inst{21-17} = 0b10000; 6731 let Inst{16-12} = opcode; 6732 let Inst{11-10} = 0b10; 6733 let Inst{9-5} = Rn; 6734 let Inst{4-0} = Rd; 6735} 6736 6737multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6738 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6739 asm, ".4s", ".4h", []>; 6740 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6741 asm#"2", ".4s", ".8h", []>; 6742 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6743 asm, ".2d", ".2s", []>; 6744 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6745 asm#"2", ".2d", ".4s", []>; 6746} 6747 6748multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6749 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6750 asm, ".4h", ".4s", []>; 6751 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6752 asm#"2", ".8h", ".4s", []>; 6753 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6754 asm, ".2s", ".2d", []>; 6755 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6756 asm#"2", ".4s", ".2d", []>; 6757} 6758 6759multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6760 Intrinsic OpNode> { 6761 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6762 asm, ".2s", ".2d", 6763 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6764 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6765 asm#"2", ".4s", ".2d", []>; 6766 6767 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6768 (!cast<Instruction>(NAME # "v4f32") 6769 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6770} 6771 6772//---------------------------------------------------------------------------- 6773// AdvSIMD three register different-size vector instructions. 6774//---------------------------------------------------------------------------- 6775 6776let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6777class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6778 RegisterOperand outtype, RegisterOperand intype1, 6779 RegisterOperand intype2, string asm, 6780 string outkind, string inkind1, string inkind2, 6781 list<dag> pattern> 6782 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6783 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6784 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6785 Sched<[WriteVq]> { 6786 bits<5> Rd; 6787 bits<5> Rn; 6788 bits<5> Rm; 6789 let Inst{31} = 0; 6790 let Inst{30} = size{0}; 6791 let Inst{29} = U; 6792 let Inst{28-24} = 0b01110; 6793 let Inst{23-22} = size{2-1}; 6794 let Inst{21} = 1; 6795 let Inst{20-16} = Rm; 6796 let Inst{15-12} = opcode; 6797 let Inst{11-10} = 0b00; 6798 let Inst{9-5} = Rn; 6799 let Inst{4-0} = Rd; 6800} 6801 6802let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6803class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6804 RegisterOperand outtype, RegisterOperand intype1, 6805 RegisterOperand intype2, string asm, 6806 string outkind, string inkind1, string inkind2, 6807 list<dag> pattern> 6808 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6809 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6810 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6811 Sched<[WriteVq]> { 6812 bits<5> Rd; 6813 bits<5> Rn; 6814 bits<5> Rm; 6815 let Inst{31} = 0; 6816 let Inst{30} = size{0}; 6817 let Inst{29} = U; 6818 let Inst{28-24} = 0b01110; 6819 let Inst{23-22} = size{2-1}; 6820 let Inst{21} = 1; 6821 let Inst{20-16} = Rm; 6822 let Inst{15-12} = opcode; 6823 let Inst{11-10} = 0b00; 6824 let Inst{9-5} = Rn; 6825 let Inst{4-0} = Rd; 6826} 6827 6828// FIXME: TableGen doesn't know how to deal with expanded types that also 6829// change the element count (in this case, placing the results in 6830// the high elements of the result register rather than the low 6831// elements). Until that's fixed, we can't code-gen those. 6832multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6833 Intrinsic IntOp> { 6834 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6835 V64, V128, V128, 6836 asm, ".8b", ".8h", ".8h", 6837 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6838 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6839 V128, V128, V128, 6840 asm#"2", ".16b", ".8h", ".8h", 6841 []>; 6842 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6843 V64, V128, V128, 6844 asm, ".4h", ".4s", ".4s", 6845 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6846 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6847 V128, V128, V128, 6848 asm#"2", ".8h", ".4s", ".4s", 6849 []>; 6850 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6851 V64, V128, V128, 6852 asm, ".2s", ".2d", ".2d", 6853 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6854 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6855 V128, V128, V128, 6856 asm#"2", ".4s", ".2d", ".2d", 6857 []>; 6858 6859 6860 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6861 // a version attached to an instruction. 6862 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6863 (v8i16 V128:$Rm))), 6864 (!cast<Instruction>(NAME # "v8i16_v16i8") 6865 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6866 V128:$Rn, V128:$Rm)>; 6867 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6868 (v4i32 V128:$Rm))), 6869 (!cast<Instruction>(NAME # "v4i32_v8i16") 6870 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6871 V128:$Rn, V128:$Rm)>; 6872 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6873 (v2i64 V128:$Rm))), 6874 (!cast<Instruction>(NAME # "v2i64_v4i32") 6875 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6876 V128:$Rn, V128:$Rm)>; 6877} 6878 6879multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6880 SDPatternOperator OpNode> { 6881 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6882 V128, V64, V64, 6883 asm, ".8h", ".8b", ".8b", 6884 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6885 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6886 V128, V128, V128, 6887 asm#"2", ".8h", ".16b", ".16b", []>; 6888 let Predicates = [HasAES] in { 6889 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6890 V128, V64, V64, 6891 asm, ".1q", ".1d", ".1d", 6892 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>; 6893 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6894 V128, V128, V128, 6895 asm#"2", ".1q", ".2d", ".2d", 6896 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)), 6897 (extract_high_v2i64 (v2i64 V128:$Rm))))]>; 6898 } 6899 6900 def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6901 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6902 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6903} 6904 6905multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6906 SDPatternOperator OpNode> { 6907 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6908 V128, V64, V64, 6909 asm, ".4s", ".4h", ".4h", 6910 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6911 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6912 V128, V128, V128, 6913 asm#"2", ".4s", ".8h", ".8h", 6914 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6915 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6916 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6917 V128, V64, V64, 6918 asm, ".2d", ".2s", ".2s", 6919 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6920 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6921 V128, V128, V128, 6922 asm#"2", ".2d", ".4s", ".4s", 6923 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6924 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6925} 6926 6927multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6928 SDPatternOperator OpNode = null_frag> { 6929 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6930 V128, V64, V64, 6931 asm, ".8h", ".8b", ".8b", 6932 [(set (v8i16 V128:$Rd), 6933 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6934 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6935 V128, V128, V128, 6936 asm#"2", ".8h", ".16b", ".16b", 6937 [(set (v8i16 V128:$Rd), 6938 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6939 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 6940 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6941 V128, V64, V64, 6942 asm, ".4s", ".4h", ".4h", 6943 [(set (v4i32 V128:$Rd), 6944 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6945 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6946 V128, V128, V128, 6947 asm#"2", ".4s", ".8h", ".8h", 6948 [(set (v4i32 V128:$Rd), 6949 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6950 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 6951 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6952 V128, V64, V64, 6953 asm, ".2d", ".2s", ".2s", 6954 [(set (v2i64 V128:$Rd), 6955 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6956 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6957 V128, V128, V128, 6958 asm#"2", ".2d", ".4s", ".4s", 6959 [(set (v2i64 V128:$Rd), 6960 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6961 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 6962} 6963 6964multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6965 string asm, 6966 SDPatternOperator OpNode> { 6967 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6968 V128, V64, V64, 6969 asm, ".8h", ".8b", ".8b", 6970 [(set (v8i16 V128:$dst), 6971 (add (v8i16 V128:$Rd), 6972 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6973 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6974 V128, V128, V128, 6975 asm#"2", ".8h", ".16b", ".16b", 6976 [(set (v8i16 V128:$dst), 6977 (add (v8i16 V128:$Rd), 6978 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 6979 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 6980 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6981 V128, V64, V64, 6982 asm, ".4s", ".4h", ".4h", 6983 [(set (v4i32 V128:$dst), 6984 (add (v4i32 V128:$Rd), 6985 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6986 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6987 V128, V128, V128, 6988 asm#"2", ".4s", ".8h", ".8h", 6989 [(set (v4i32 V128:$dst), 6990 (add (v4i32 V128:$Rd), 6991 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6992 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 6993 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6994 V128, V64, V64, 6995 asm, ".2d", ".2s", ".2s", 6996 [(set (v2i64 V128:$dst), 6997 (add (v2i64 V128:$Rd), 6998 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6999 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7000 V128, V128, V128, 7001 asm#"2", ".2d", ".4s", ".4s", 7002 [(set (v2i64 V128:$dst), 7003 (add (v2i64 V128:$Rd), 7004 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7005 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 7006} 7007 7008multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 7009 SDPatternOperator OpNode = null_frag> { 7010 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7011 V128, V64, V64, 7012 asm, ".8h", ".8b", ".8b", 7013 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7014 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7015 V128, V128, V128, 7016 asm#"2", ".8h", ".16b", ".16b", 7017 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7018 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7019 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7020 V128, V64, V64, 7021 asm, ".4s", ".4h", ".4h", 7022 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7023 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7024 V128, V128, V128, 7025 asm#"2", ".4s", ".8h", ".8h", 7026 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7027 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7028 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7029 V128, V64, V64, 7030 asm, ".2d", ".2s", ".2s", 7031 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7032 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7033 V128, V128, V128, 7034 asm#"2", ".2d", ".4s", ".4s", 7035 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7036 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7037} 7038 7039multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 7040 string asm, 7041 SDPatternOperator OpNode> { 7042 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7043 V128, V64, V64, 7044 asm, ".8h", ".8b", ".8b", 7045 [(set (v8i16 V128:$dst), 7046 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7047 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7048 V128, V128, V128, 7049 asm#"2", ".8h", ".16b", ".16b", 7050 [(set (v8i16 V128:$dst), 7051 (OpNode (v8i16 V128:$Rd), 7052 (extract_high_v16i8 (v16i8 V128:$Rn)), 7053 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7054 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7055 V128, V64, V64, 7056 asm, ".4s", ".4h", ".4h", 7057 [(set (v4i32 V128:$dst), 7058 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7059 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7060 V128, V128, V128, 7061 asm#"2", ".4s", ".8h", ".8h", 7062 [(set (v4i32 V128:$dst), 7063 (OpNode (v4i32 V128:$Rd), 7064 (extract_high_v8i16 (v8i16 V128:$Rn)), 7065 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7066 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7067 V128, V64, V64, 7068 asm, ".2d", ".2s", ".2s", 7069 [(set (v2i64 V128:$dst), 7070 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7071 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7072 V128, V128, V128, 7073 asm#"2", ".2d", ".4s", ".4s", 7074 [(set (v2i64 V128:$dst), 7075 (OpNode (v2i64 V128:$Rd), 7076 (extract_high_v4i32 (v4i32 V128:$Rn)), 7077 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7078} 7079 7080multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 7081 SDPatternOperator Accum> { 7082 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7083 V128, V64, V64, 7084 asm, ".4s", ".4h", ".4h", 7085 [(set (v4i32 V128:$dst), 7086 (Accum (v4i32 V128:$Rd), 7087 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 7088 (v4i16 V64:$Rm)))))]>; 7089 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7090 V128, V128, V128, 7091 asm#"2", ".4s", ".8h", ".8h", 7092 [(set (v4i32 V128:$dst), 7093 (Accum (v4i32 V128:$Rd), 7094 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 7095 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7096 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7097 V128, V64, V64, 7098 asm, ".2d", ".2s", ".2s", 7099 [(set (v2i64 V128:$dst), 7100 (Accum (v2i64 V128:$Rd), 7101 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 7102 (v2i32 V64:$Rm)))))]>; 7103 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7104 V128, V128, V128, 7105 asm#"2", ".2d", ".4s", ".4s", 7106 [(set (v2i64 V128:$dst), 7107 (Accum (v2i64 V128:$Rd), 7108 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 7109 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7110} 7111 7112multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 7113 SDPatternOperator OpNode> { 7114 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7115 V128, V128, V64, 7116 asm, ".8h", ".8h", ".8b", 7117 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 7118 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7119 V128, V128, V128, 7120 asm#"2", ".8h", ".8h", ".16b", 7121 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7122 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7123 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7124 V128, V128, V64, 7125 asm, ".4s", ".4s", ".4h", 7126 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 7127 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7128 V128, V128, V128, 7129 asm#"2", ".4s", ".4s", ".8h", 7130 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7131 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7132 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7133 V128, V128, V64, 7134 asm, ".2d", ".2d", ".2s", 7135 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 7136 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7137 V128, V128, V128, 7138 asm#"2", ".2d", ".2d", ".4s", 7139 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7140 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7141} 7142 7143//---------------------------------------------------------------------------- 7144// AdvSIMD bitwise extract from vector 7145//---------------------------------------------------------------------------- 7146 7147class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 7148 string asm, string kind> 7149 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 7150 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 7151 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 7152 [(set (vty regtype:$Rd), 7153 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 7154 Sched<[!if(size, WriteVq, WriteVd)]> { 7155 bits<5> Rd; 7156 bits<5> Rn; 7157 bits<5> Rm; 7158 bits<4> imm; 7159 let Inst{31} = 0; 7160 let Inst{30} = size; 7161 let Inst{29-21} = 0b101110000; 7162 let Inst{20-16} = Rm; 7163 let Inst{15} = 0; 7164 let Inst{14-11} = imm; 7165 let Inst{10} = 0; 7166 let Inst{9-5} = Rn; 7167 let Inst{4-0} = Rd; 7168} 7169 7170 7171multiclass SIMDBitwiseExtract<string asm> { 7172 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 7173 let imm{3} = 0; 7174 } 7175 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 7176} 7177 7178//---------------------------------------------------------------------------- 7179// AdvSIMD zip vector 7180//---------------------------------------------------------------------------- 7181 7182class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 7183 string asm, string kind, SDNode OpNode, ValueType valty> 7184 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7185 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 7186 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 7187 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 7188 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 7189 bits<5> Rd; 7190 bits<5> Rn; 7191 bits<5> Rm; 7192 let Inst{31} = 0; 7193 let Inst{30} = size{0}; 7194 let Inst{29-24} = 0b001110; 7195 let Inst{23-22} = size{2-1}; 7196 let Inst{21} = 0; 7197 let Inst{20-16} = Rm; 7198 let Inst{15} = 0; 7199 let Inst{14-12} = opc; 7200 let Inst{11-10} = 0b10; 7201 let Inst{9-5} = Rn; 7202 let Inst{4-0} = Rd; 7203} 7204 7205multiclass SIMDZipVector<bits<3>opc, string asm, 7206 SDNode OpNode> { 7207 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 7208 asm, ".8b", OpNode, v8i8>; 7209 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 7210 asm, ".16b", OpNode, v16i8>; 7211 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 7212 asm, ".4h", OpNode, v4i16>; 7213 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 7214 asm, ".8h", OpNode, v8i16>; 7215 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 7216 asm, ".2s", OpNode, v2i32>; 7217 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 7218 asm, ".4s", OpNode, v4i32>; 7219 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 7220 asm, ".2d", OpNode, v2i64>; 7221 7222 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 7223 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7224 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)), 7225 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7226 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 7227 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7228 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)), 7229 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7230 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 7231 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 7232 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 7233 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 7234 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 7235 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 7236} 7237 7238//---------------------------------------------------------------------------- 7239// AdvSIMD three register scalar instructions 7240//---------------------------------------------------------------------------- 7241 7242let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7243class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 7244 RegisterClass regtype, string asm, 7245 list<dag> pattern> 7246 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7247 "\t$Rd, $Rn, $Rm", "", pattern>, 7248 Sched<[WriteVd]> { 7249 bits<5> Rd; 7250 bits<5> Rn; 7251 bits<5> Rm; 7252 let Inst{31-30} = 0b01; 7253 let Inst{29} = U; 7254 let Inst{28-24} = 0b11110; 7255 let Inst{23-21} = size; 7256 let Inst{20-16} = Rm; 7257 let Inst{15-11} = opcode; 7258 let Inst{10} = 1; 7259 let Inst{9-5} = Rn; 7260 let Inst{4-0} = Rd; 7261} 7262 7263let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7264class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 7265 dag oops, dag iops, string asm, 7266 list<dag> pattern> 7267 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 7268 Sched<[WriteVd]> { 7269 bits<5> Rd; 7270 bits<5> Rn; 7271 bits<5> Rm; 7272 let Inst{31-30} = 0b01; 7273 let Inst{29} = U; 7274 let Inst{28-24} = 0b11110; 7275 let Inst{23-22} = size; 7276 let Inst{21} = R; 7277 let Inst{20-16} = Rm; 7278 let Inst{15-11} = opcode; 7279 let Inst{10} = 1; 7280 let Inst{9-5} = Rn; 7281 let Inst{4-0} = Rd; 7282} 7283 7284multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 7285 SDPatternOperator OpNode> { 7286 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7287 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7288} 7289 7290multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 7291 SDPatternOperator OpNode> { 7292 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7293 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7294 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 7295 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7296 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 7297 7298 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 7299 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 7300 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 7301 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 7302} 7303 7304multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 7305 SDPatternOperator OpNode> { 7306 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 7307 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7308 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7309} 7310 7311multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 7312 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 7313 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 7314 asm, []>; 7315 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 7316 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 7317 asm, []>; 7318} 7319 7320multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 7321 SDPatternOperator OpNode = null_frag, 7322 Predicate pred = HasNEON> { 7323 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7324 let Predicates = [pred] in { 7325 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7326 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7327 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7328 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7329 } 7330 let Predicates = [pred, HasFullFP16] in { 7331 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7332 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 7333 } 7334 } 7335 7336 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7337 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7338} 7339 7340multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 7341 SDPatternOperator OpNode = null_frag> { 7342 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7343 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7344 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7345 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7346 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 7347 let Predicates = [HasNEON, HasFullFP16] in { 7348 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7349 []>; 7350 } // Predicates = [HasNEON, HasFullFP16] 7351 } 7352 7353 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7354 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7355} 7356 7357class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 7358 dag oops, dag iops, string asm, string cstr, list<dag> pat> 7359 : I<oops, iops, asm, 7360 "\t$Rd, $Rn, $Rm", cstr, pat>, 7361 Sched<[WriteVd]> { 7362 bits<5> Rd; 7363 bits<5> Rn; 7364 bits<5> Rm; 7365 let Inst{31-30} = 0b01; 7366 let Inst{29} = U; 7367 let Inst{28-24} = 0b11110; 7368 let Inst{23-22} = size; 7369 let Inst{21} = 1; 7370 let Inst{20-16} = Rm; 7371 let Inst{15-11} = opcode; 7372 let Inst{10} = 0; 7373 let Inst{9-5} = Rn; 7374 let Inst{4-0} = Rd; 7375} 7376 7377let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7378multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 7379 SDPatternOperator OpNode = null_frag> { 7380 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7381 (outs FPR32:$Rd), 7382 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7383 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7384 (outs FPR64:$Rd), 7385 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7386 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7387} 7388 7389let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7390multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7391 SDPatternOperator OpNode = null_frag> { 7392 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7393 (outs FPR32:$dst), 7394 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7395 asm, "$Rd = $dst", []>; 7396 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7397 (outs FPR64:$dst), 7398 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7399 asm, "$Rd = $dst", 7400 [(set (i64 FPR64:$dst), 7401 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7402} 7403 7404//---------------------------------------------------------------------------- 7405// AdvSIMD two register scalar instructions 7406//---------------------------------------------------------------------------- 7407 7408let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7409class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7410 RegisterClass regtype, RegisterClass regtype2, 7411 string asm, list<dag> pat> 7412 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7413 "\t$Rd, $Rn", "", pat>, 7414 Sched<[WriteVd]> { 7415 bits<5> Rd; 7416 bits<5> Rn; 7417 let Inst{31-30} = 0b01; 7418 let Inst{29} = U; 7419 let Inst{28-24} = 0b11110; 7420 let Inst{23-22} = size; 7421 let Inst{21} = 0b1; 7422 let Inst{20-19} = size2; 7423 let Inst{18-17} = 0b00; 7424 let Inst{16-12} = opcode; 7425 let Inst{11-10} = 0b10; 7426 let Inst{9-5} = Rn; 7427 let Inst{4-0} = Rd; 7428} 7429 7430let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7431class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7432 RegisterClass regtype, RegisterClass regtype2, 7433 string asm, list<dag> pat> 7434 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7435 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7436 Sched<[WriteVd]> { 7437 bits<5> Rd; 7438 bits<5> Rn; 7439 let Inst{31-30} = 0b01; 7440 let Inst{29} = U; 7441 let Inst{28-24} = 0b11110; 7442 let Inst{23-22} = size; 7443 let Inst{21-17} = 0b10000; 7444 let Inst{16-12} = opcode; 7445 let Inst{11-10} = 0b10; 7446 let Inst{9-5} = Rn; 7447 let Inst{4-0} = Rd; 7448} 7449 7450 7451let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7452class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7453 RegisterClass regtype, string asm, string zero> 7454 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7455 "\t$Rd, $Rn, #" # zero, "", []>, 7456 Sched<[WriteVd]> { 7457 bits<5> Rd; 7458 bits<5> Rn; 7459 let Inst{31-30} = 0b01; 7460 let Inst{29} = U; 7461 let Inst{28-24} = 0b11110; 7462 let Inst{23-22} = size; 7463 let Inst{21} = 0b1; 7464 let Inst{20-19} = size2; 7465 let Inst{18-17} = 0b00; 7466 let Inst{16-12} = opcode; 7467 let Inst{11-10} = 0b10; 7468 let Inst{9-5} = Rn; 7469 let Inst{4-0} = Rd; 7470} 7471 7472let mayRaiseFPException = 1, Uses = [FPCR] in 7473class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7474 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7475 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7476 Sched<[WriteVd]> { 7477 bits<5> Rd; 7478 bits<5> Rn; 7479 let Inst{31-17} = 0b011111100110000; 7480 let Inst{16-12} = opcode; 7481 let Inst{11-10} = 0b10; 7482 let Inst{9-5} = Rn; 7483 let Inst{4-0} = Rd; 7484} 7485 7486multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7487 SDPatternOperator OpNode> { 7488 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7489 7490 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7491 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7492} 7493 7494multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7495 SDPatternOperator OpNode> { 7496 let mayRaiseFPException = 1, Uses = [FPCR] in { 7497 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7498 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7499 let Predicates = [HasNEON, HasFullFP16] in { 7500 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7501 } 7502 } 7503 7504 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7505 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7506 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7507 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7508 let Predicates = [HasNEON, HasFullFP16] in { 7509 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7510 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7511 } 7512 7513 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7514 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7515} 7516 7517multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7518 SDPatternOperator OpNode = null_frag, 7519 list<Predicate> preds = []> { 7520 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7521 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7522 7523 let Predicates = preds in { 7524 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7525 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7526 } 7527} 7528 7529let mayRaiseFPException = 1, Uses = [FPCR] in 7530multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7531 Predicate pred = HasNEON> { 7532 let Predicates = [pred] in { 7533 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7534 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7535 } 7536 let Predicates = [pred, HasFullFP16] in { 7537 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7538 } 7539} 7540 7541let mayRaiseFPException = 1, Uses = [FPCR] in 7542multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7543 SDPatternOperator OpNode> { 7544 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7545 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7546 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7547 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7548 let Predicates = [HasNEON, HasFullFP16] in { 7549 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7550 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7551 } 7552} 7553 7554multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7555 SDPatternOperator OpNode = null_frag> { 7556 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7557 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7558 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7559 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7560 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7561 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7562 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7563 } 7564 7565 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7566 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7567} 7568 7569multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7570 Intrinsic OpNode> { 7571 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7572 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7573 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7574 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7575 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7576 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7577 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7578 } 7579 7580 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7581 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7582} 7583 7584 7585 7586let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7587multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7588 SDPatternOperator OpNode = null_frag> { 7589 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7590 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>; 7591 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7592 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7593} 7594 7595//---------------------------------------------------------------------------- 7596// AdvSIMD scalar pairwise instructions 7597//---------------------------------------------------------------------------- 7598 7599let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7600class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7601 RegisterOperand regtype, RegisterOperand vectype, 7602 string asm, string kind> 7603 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7604 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7605 Sched<[WriteVd]> { 7606 bits<5> Rd; 7607 bits<5> Rn; 7608 let Inst{31-30} = 0b01; 7609 let Inst{29} = U; 7610 let Inst{28-24} = 0b11110; 7611 let Inst{23-22} = size; 7612 let Inst{21-17} = 0b11000; 7613 let Inst{16-12} = opcode; 7614 let Inst{11-10} = 0b10; 7615 let Inst{9-5} = Rn; 7616 let Inst{4-0} = Rd; 7617} 7618 7619multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7620 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7621 asm, ".2d">; 7622} 7623 7624let mayRaiseFPException = 1, Uses = [FPCR] in 7625multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7626 let Predicates = [HasNEON, HasFullFP16] in { 7627 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7628 asm, ".2h">; 7629 } 7630 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7631 asm, ".2s">; 7632 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7633 asm, ".2d">; 7634} 7635 7636//---------------------------------------------------------------------------- 7637// AdvSIMD across lanes instructions 7638//---------------------------------------------------------------------------- 7639 7640let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7641class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7642 RegisterClass regtype, RegisterOperand vectype, 7643 string asm, string kind, list<dag> pattern> 7644 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7645 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7646 Sched<[!if(Q, WriteVq, WriteVd)]> { 7647 bits<5> Rd; 7648 bits<5> Rn; 7649 let Inst{31} = 0; 7650 let Inst{30} = Q; 7651 let Inst{29} = U; 7652 let Inst{28-24} = 0b01110; 7653 let Inst{23-22} = size; 7654 let Inst{21-17} = 0b11000; 7655 let Inst{16-12} = opcode; 7656 let Inst{11-10} = 0b10; 7657 let Inst{9-5} = Rn; 7658 let Inst{4-0} = Rd; 7659} 7660 7661multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7662 string asm> { 7663 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7664 asm, ".8b", []>; 7665 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7666 asm, ".16b", []>; 7667 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7668 asm, ".4h", []>; 7669 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7670 asm, ".8h", []>; 7671 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7672 asm, ".4s", []>; 7673} 7674 7675multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7676 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7677 asm, ".8b", []>; 7678 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7679 asm, ".16b", []>; 7680 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7681 asm, ".4h", []>; 7682 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7683 asm, ".8h", []>; 7684 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7685 asm, ".4s", []>; 7686} 7687 7688let mayRaiseFPException = 1, Uses = [FPCR] in 7689multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7690 SDPatternOperator intOp> { 7691 let Predicates = [HasNEON, HasFullFP16] in { 7692 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7693 asm, ".4h", 7694 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7695 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7696 asm, ".8h", 7697 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7698 } // Predicates = [HasNEON, HasFullFP16] 7699 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7700 asm, ".4s", 7701 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7702} 7703 7704//---------------------------------------------------------------------------- 7705// AdvSIMD INS/DUP instructions 7706//---------------------------------------------------------------------------- 7707 7708// FIXME: There has got to be a better way to factor these. ugh. 7709 7710class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7711 string operands, string constraints, list<dag> pattern> 7712 : I<outs, ins, asm, operands, constraints, pattern>, 7713 Sched<[!if(Q, WriteVq, WriteVd)]> { 7714 bits<5> Rd; 7715 bits<5> Rn; 7716 let Inst{31} = 0; 7717 let Inst{30} = Q; 7718 let Inst{29} = op; 7719 let Inst{28-21} = 0b01110000; 7720 let Inst{15} = 0; 7721 let Inst{10} = 1; 7722 let Inst{9-5} = Rn; 7723 let Inst{4-0} = Rd; 7724} 7725 7726class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7727 RegisterOperand vecreg, RegisterClass regtype> 7728 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7729 "{\t$Rd" # size # ", $Rn" # 7730 "|" # size # "\t$Rd, $Rn}", "", 7731 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7732 let Inst{20-16} = imm5; 7733 let Inst{14-11} = 0b0001; 7734} 7735 7736class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7737 ValueType vectype, ValueType insreg, 7738 RegisterOperand vecreg, Operand idxtype, 7739 SDNode OpNode> 7740 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7741 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7742 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7743 [(set (vectype vecreg:$Rd), 7744 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7745 let Inst{14-11} = 0b0000; 7746} 7747 7748class SIMDDup64FromElement 7749 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7750 VectorIndexD, AArch64duplane64> { 7751 bits<1> idx; 7752 let Inst{20} = idx; 7753 let Inst{19-16} = 0b1000; 7754} 7755 7756class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7757 RegisterOperand vecreg> 7758 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7759 VectorIndexS, AArch64duplane32> { 7760 bits<2> idx; 7761 let Inst{20-19} = idx; 7762 let Inst{18-16} = 0b100; 7763} 7764 7765class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7766 RegisterOperand vecreg> 7767 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7768 VectorIndexH, AArch64duplane16> { 7769 bits<3> idx; 7770 let Inst{20-18} = idx; 7771 let Inst{17-16} = 0b10; 7772} 7773 7774class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7775 RegisterOperand vecreg> 7776 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7777 VectorIndexB, AArch64duplane8> { 7778 bits<4> idx; 7779 let Inst{20-17} = idx; 7780 let Inst{16} = 1; 7781} 7782 7783class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7784 Operand idxtype, string asm, list<dag> pattern> 7785 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7786 "{\t$Rd, $Rn" # size # "$idx" # 7787 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7788 let Inst{14-11} = imm4; 7789} 7790 7791class SIMDSMov<bit Q, string size, RegisterClass regtype, 7792 Operand idxtype> 7793 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7794class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7795 Operand idxtype> 7796 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7797 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7798 7799class SIMDMovAlias<string asm, string size, Instruction inst, 7800 RegisterClass regtype, Operand idxtype> 7801 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7802 "|" # size # "\t$dst, $src$idx}", 7803 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7804 7805multiclass SMov { 7806 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7807 // streaming mode. 7808 let Predicates = [HasNEONorSME] in { 7809 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7810 let Inst{20-16} = 0b00001; 7811 } 7812 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7813 let Inst{20-16} = 0b00001; 7814 } 7815 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7816 let Inst{20-16} = 0b00010; 7817 } 7818 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7819 let Inst{20-16} = 0b00010; 7820 } 7821 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7822 let Inst{20-16} = 0b00100; 7823 } 7824 } 7825 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7826 bits<4> idx; 7827 let Inst{20-17} = idx; 7828 let Inst{16} = 1; 7829 } 7830 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7831 bits<4> idx; 7832 let Inst{20-17} = idx; 7833 let Inst{16} = 1; 7834 } 7835 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7836 bits<3> idx; 7837 let Inst{20-18} = idx; 7838 let Inst{17-16} = 0b10; 7839 } 7840 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7841 bits<3> idx; 7842 let Inst{20-18} = idx; 7843 let Inst{17-16} = 0b10; 7844 } 7845 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7846 bits<2> idx; 7847 let Inst{20-19} = idx; 7848 let Inst{18-16} = 0b100; 7849 } 7850} 7851 7852multiclass UMov { 7853 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7854 // streaming mode. 7855 let Predicates = [HasNEONorSME] in { 7856 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7857 let Inst{20-16} = 0b00001; 7858 } 7859 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7860 let Inst{20-16} = 0b00010; 7861 } 7862 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7863 let Inst{20-16} = 0b00100; 7864 } 7865 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7866 let Inst{20-16} = 0b01000; 7867 } 7868 def : SIMDMovAlias<"mov", ".s", 7869 !cast<Instruction>(NAME # vi32_idx0), 7870 GPR32, VectorIndex0>; 7871 def : SIMDMovAlias<"mov", ".d", 7872 !cast<Instruction>(NAME # vi64_idx0), 7873 GPR64, VectorIndex0>; 7874 } 7875 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7876 bits<4> idx; 7877 let Inst{20-17} = idx; 7878 let Inst{16} = 1; 7879 } 7880 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7881 bits<3> idx; 7882 let Inst{20-18} = idx; 7883 let Inst{17-16} = 0b10; 7884 } 7885 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7886 bits<2> idx; 7887 let Inst{20-19} = idx; 7888 let Inst{18-16} = 0b100; 7889 } 7890 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7891 bits<1> idx; 7892 let Inst{20} = idx; 7893 let Inst{19-16} = 0b1000; 7894 } 7895 def : SIMDMovAlias<"mov", ".s", 7896 !cast<Instruction>(NAME#"vi32"), 7897 GPR32, VectorIndexS>; 7898 def : SIMDMovAlias<"mov", ".d", 7899 !cast<Instruction>(NAME#"vi64"), 7900 GPR64, VectorIndexD>; 7901} 7902 7903class SIMDInsFromMain<string size, ValueType vectype, 7904 RegisterClass regtype, Operand idxtype> 7905 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7906 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7907 "{\t$Rd" # size # "$idx, $Rn" # 7908 "|" # size # "\t$Rd$idx, $Rn}", 7909 "$Rd = $dst", 7910 [(set V128:$dst, 7911 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7912 let Inst{14-11} = 0b0011; 7913} 7914 7915class SIMDInsFromElement<string size, ValueType vectype, 7916 ValueType elttype, Operand idxtype> 7917 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7918 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7919 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7920 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7921 "$Rd = $dst", 7922 [(set V128:$dst, 7923 (vector_insert 7924 (vectype V128:$Rd), 7925 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7926 idxtype:$idx))]>; 7927 7928class SIMDInsMainMovAlias<string size, Instruction inst, 7929 RegisterClass regtype, Operand idxtype> 7930 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7931 "|" # size #"\t$dst$idx, $src}", 7932 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7933class SIMDInsElementMovAlias<string size, Instruction inst, 7934 Operand idxtype> 7935 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 7936 # "|" # size #"\t$dst$idx, $src$idx2}", 7937 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7938 7939 7940multiclass SIMDIns { 7941 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7942 bits<4> idx; 7943 let Inst{20-17} = idx; 7944 let Inst{16} = 1; 7945 } 7946 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7947 bits<3> idx; 7948 let Inst{20-18} = idx; 7949 let Inst{17-16} = 0b10; 7950 } 7951 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7952 bits<2> idx; 7953 let Inst{20-19} = idx; 7954 let Inst{18-16} = 0b100; 7955 } 7956 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7957 bits<1> idx; 7958 let Inst{20} = idx; 7959 let Inst{19-16} = 0b1000; 7960 } 7961 7962 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7963 bits<4> idx; 7964 bits<4> idx2; 7965 let Inst{20-17} = idx; 7966 let Inst{16} = 1; 7967 let Inst{14-11} = idx2; 7968 } 7969 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7970 bits<3> idx; 7971 bits<3> idx2; 7972 let Inst{20-18} = idx; 7973 let Inst{17-16} = 0b10; 7974 let Inst{14-12} = idx2; 7975 let Inst{11} = {?}; 7976 } 7977 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7978 bits<2> idx; 7979 bits<2> idx2; 7980 let Inst{20-19} = idx; 7981 let Inst{18-16} = 0b100; 7982 let Inst{14-13} = idx2; 7983 let Inst{12-11} = {?,?}; 7984 } 7985 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7986 bits<1> idx; 7987 bits<1> idx2; 7988 let Inst{20} = idx; 7989 let Inst{19-16} = 0b1000; 7990 let Inst{14} = idx2; 7991 let Inst{13-11} = {?,?,?}; 7992 } 7993 7994 // For all forms of the INS instruction, the "mov" mnemonic is the 7995 // preferred alias. Why they didn't just call the instruction "mov" in 7996 // the first place is a very good question indeed... 7997 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7998 GPR32, VectorIndexB>; 7999 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 8000 GPR32, VectorIndexH>; 8001 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 8002 GPR32, VectorIndexS>; 8003 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 8004 GPR64, VectorIndexD>; 8005 8006 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 8007 VectorIndexB>; 8008 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 8009 VectorIndexH>; 8010 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 8011 VectorIndexS>; 8012 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 8013 VectorIndexD>; 8014} 8015 8016//---------------------------------------------------------------------------- 8017// AdvSIMD TBL/TBX 8018//---------------------------------------------------------------------------- 8019 8020let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8021class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8022 RegisterOperand listtype, string asm, string kind> 8023 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 8024 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 8025 Sched<[!if(Q, WriteVq, WriteVd)]> { 8026 bits<5> Vd; 8027 bits<5> Vn; 8028 bits<5> Vm; 8029 let Inst{31} = 0; 8030 let Inst{30} = Q; 8031 let Inst{29-21} = 0b001110000; 8032 let Inst{20-16} = Vm; 8033 let Inst{15} = 0; 8034 let Inst{14-13} = len; 8035 let Inst{12} = op; 8036 let Inst{11-10} = 0b00; 8037 let Inst{9-5} = Vn; 8038 let Inst{4-0} = Vd; 8039} 8040 8041let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8042class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8043 RegisterOperand listtype, string asm, string kind> 8044 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 8045 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 8046 Sched<[!if(Q, WriteVq, WriteVd)]> { 8047 bits<5> Vd; 8048 bits<5> Vn; 8049 bits<5> Vm; 8050 let Inst{31} = 0; 8051 let Inst{30} = Q; 8052 let Inst{29-21} = 0b001110000; 8053 let Inst{20-16} = Vm; 8054 let Inst{15} = 0; 8055 let Inst{14-13} = len; 8056 let Inst{12} = op; 8057 let Inst{11-10} = 0b00; 8058 let Inst{9-5} = Vn; 8059 let Inst{4-0} = Vd; 8060} 8061 8062class SIMDTableLookupAlias<string asm, Instruction inst, 8063 RegisterOperand vectype, RegisterOperand listtype> 8064 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 8065 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 8066 8067multiclass SIMDTableLookup<bit op, string asm> { 8068 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 8069 asm, ".8b">; 8070 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 8071 asm, ".8b">; 8072 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 8073 asm, ".8b">; 8074 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 8075 asm, ".8b">; 8076 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 8077 asm, ".16b">; 8078 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 8079 asm, ".16b">; 8080 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 8081 asm, ".16b">; 8082 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 8083 asm, ".16b">; 8084 8085 def : SIMDTableLookupAlias<asm # ".8b", 8086 !cast<Instruction>(NAME#"v8i8One"), 8087 V64, VecListOne128>; 8088 def : SIMDTableLookupAlias<asm # ".8b", 8089 !cast<Instruction>(NAME#"v8i8Two"), 8090 V64, VecListTwo128>; 8091 def : SIMDTableLookupAlias<asm # ".8b", 8092 !cast<Instruction>(NAME#"v8i8Three"), 8093 V64, VecListThree128>; 8094 def : SIMDTableLookupAlias<asm # ".8b", 8095 !cast<Instruction>(NAME#"v8i8Four"), 8096 V64, VecListFour128>; 8097 def : SIMDTableLookupAlias<asm # ".16b", 8098 !cast<Instruction>(NAME#"v16i8One"), 8099 V128, VecListOne128>; 8100 def : SIMDTableLookupAlias<asm # ".16b", 8101 !cast<Instruction>(NAME#"v16i8Two"), 8102 V128, VecListTwo128>; 8103 def : SIMDTableLookupAlias<asm # ".16b", 8104 !cast<Instruction>(NAME#"v16i8Three"), 8105 V128, VecListThree128>; 8106 def : SIMDTableLookupAlias<asm # ".16b", 8107 !cast<Instruction>(NAME#"v16i8Four"), 8108 V128, VecListFour128>; 8109} 8110 8111multiclass SIMDTableLookupTied<bit op, string asm> { 8112 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 8113 asm, ".8b">; 8114 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 8115 asm, ".8b">; 8116 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 8117 asm, ".8b">; 8118 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 8119 asm, ".8b">; 8120 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 8121 asm, ".16b">; 8122 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 8123 asm, ".16b">; 8124 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 8125 asm, ".16b">; 8126 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 8127 asm, ".16b">; 8128 8129 def : SIMDTableLookupAlias<asm # ".8b", 8130 !cast<Instruction>(NAME#"v8i8One"), 8131 V64, VecListOne128>; 8132 def : SIMDTableLookupAlias<asm # ".8b", 8133 !cast<Instruction>(NAME#"v8i8Two"), 8134 V64, VecListTwo128>; 8135 def : SIMDTableLookupAlias<asm # ".8b", 8136 !cast<Instruction>(NAME#"v8i8Three"), 8137 V64, VecListThree128>; 8138 def : SIMDTableLookupAlias<asm # ".8b", 8139 !cast<Instruction>(NAME#"v8i8Four"), 8140 V64, VecListFour128>; 8141 def : SIMDTableLookupAlias<asm # ".16b", 8142 !cast<Instruction>(NAME#"v16i8One"), 8143 V128, VecListOne128>; 8144 def : SIMDTableLookupAlias<asm # ".16b", 8145 !cast<Instruction>(NAME#"v16i8Two"), 8146 V128, VecListTwo128>; 8147 def : SIMDTableLookupAlias<asm # ".16b", 8148 !cast<Instruction>(NAME#"v16i8Three"), 8149 V128, VecListThree128>; 8150 def : SIMDTableLookupAlias<asm # ".16b", 8151 !cast<Instruction>(NAME#"v16i8Four"), 8152 V128, VecListFour128>; 8153} 8154 8155//---------------------------------------------------------------------------- 8156// AdvSIMD LUT 8157//---------------------------------------------------------------------------- 8158let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8159class BaseSIMDTableLookupIndexed<bit Q, bits<5> opc, RegisterOperand vectype, 8160 RegisterOperand listtype, Operand idx_type, 8161 string asm, string kind> 8162 : I<(outs vectype:$Rd), 8163 (ins listtype:$Rn, vectype:$Rm, idx_type:$idx), 8164 asm, "\t$Rd" # kind # ", $Rn, $Rm$idx", "", []>, 8165 Sched<[]> { 8166 bits<5> Rd; 8167 bits<5> Rn; 8168 bits<5> Rm; 8169 let Inst{31} = 0; 8170 let Inst{30} = Q; 8171 let Inst{29-24} = 0b001110; 8172 let Inst{23-22} = opc{4-3}; 8173 let Inst{21} = 0; 8174 let Inst{20-16} = Rm; 8175 let Inst{15} = 0; 8176 let Inst{14-12} = opc{2-0}; 8177 let Inst{11-10} = 0b00; 8178 let Inst{9-5} = Rn; 8179 let Inst{4-0} = Rd; 8180} 8181 8182multiclass BaseSIMDTableLookupIndexed2<string asm> { 8183 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, V128, VecListOne16b, VectorIndexS, asm, ".16b"> { 8184 bits<2> idx; 8185 let Inst{14-13} = idx; 8186 } 8187 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, V128, VecListOne8h, VectorIndexH, asm, ".8h" > { 8188 bits<3> idx; 8189 let Inst{14-12} = idx; 8190 } 8191} 8192 8193multiclass BaseSIMDTableLookupIndexed4<string asm> { 8194 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, V128, VecListOne16b, VectorIndexD, asm, ".16b"> { 8195 bit idx; 8196 let Inst{14} = idx; 8197 } 8198 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, V128, VecListTwo8h, VectorIndexS, asm, ".8h" > { 8199 bits<2> idx; 8200 let Inst{14-13} = idx; 8201 } 8202} 8203 8204//---------------------------------------------------------------------------- 8205// AdvSIMD scalar DUP 8206//---------------------------------------------------------------------------- 8207let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8208class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 8209 string asm, string kind, Operand idxtype> 8210 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 8211 "{\t$dst, $src" # kind # "$idx" # 8212 "|\t$dst, $src$idx}", "", []>, 8213 Sched<[WriteVd]> { 8214 bits<5> dst; 8215 bits<5> src; 8216 let Inst{31-21} = 0b01011110000; 8217 let Inst{15-10} = 0b000001; 8218 let Inst{9-5} = src; 8219 let Inst{4-0} = dst; 8220} 8221 8222class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 8223 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 8224 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 8225 # "|\t$dst, $src$index}", 8226 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 8227 8228 8229multiclass SIMDScalarDUP<string asm> { 8230 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 8231 bits<4> idx; 8232 let Inst{20-17} = idx; 8233 let Inst{16} = 1; 8234 } 8235 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 8236 bits<3> idx; 8237 let Inst{20-18} = idx; 8238 let Inst{17-16} = 0b10; 8239 } 8240 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 8241 bits<2> idx; 8242 let Inst{20-19} = idx; 8243 let Inst{18-16} = 0b100; 8244 } 8245 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 8246 bits<1> idx; 8247 let Inst{20} = idx; 8248 let Inst{19-16} = 0b1000; 8249 } 8250 8251 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 8252 VectorIndexD:$idx)))), 8253 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 8254 8255 // 'DUP' mnemonic aliases. 8256 def : SIMDScalarDUPAlias<"dup", ".b", 8257 !cast<Instruction>(NAME#"i8"), 8258 FPR8, V128, VectorIndexB>; 8259 def : SIMDScalarDUPAlias<"dup", ".h", 8260 !cast<Instruction>(NAME#"i16"), 8261 FPR16, V128, VectorIndexH>; 8262 def : SIMDScalarDUPAlias<"dup", ".s", 8263 !cast<Instruction>(NAME#"i32"), 8264 FPR32, V128, VectorIndexS>; 8265 def : SIMDScalarDUPAlias<"dup", ".d", 8266 !cast<Instruction>(NAME#"i64"), 8267 FPR64, V128, VectorIndexD>; 8268} 8269 8270//---------------------------------------------------------------------------- 8271// AdvSIMD modified immediate instructions 8272//---------------------------------------------------------------------------- 8273 8274class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 8275 string asm, string op_string, 8276 string cstr, list<dag> pattern> 8277 : I<oops, iops, asm, op_string, cstr, pattern>, 8278 Sched<[!if(Q, WriteVq, WriteVd)]> { 8279 bits<5> Rd; 8280 bits<8> imm8; 8281 let Inst{31} = 0; 8282 let Inst{30} = Q; 8283 let Inst{29} = op; 8284 let Inst{28-19} = 0b0111100000; 8285 let Inst{18-16} = imm8{7-5}; 8286 let Inst{11} = op2; 8287 let Inst{10} = 1; 8288 let Inst{9-5} = imm8{4-0}; 8289 let Inst{4-0} = Rd; 8290} 8291 8292class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 8293 Operand immtype, dag opt_shift_iop, 8294 string opt_shift, string asm, string kind, 8295 list<dag> pattern> 8296 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 8297 !con((ins immtype:$imm8), opt_shift_iop), asm, 8298 "{\t$Rd" # kind # ", $imm8" # opt_shift # 8299 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8300 "", pattern> { 8301 let DecoderMethod = "DecodeModImmInstruction"; 8302} 8303 8304class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 8305 Operand immtype, dag opt_shift_iop, 8306 string opt_shift, string asm, string kind, 8307 list<dag> pattern> 8308 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 8309 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 8310 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 8311 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8312 "$Rd = $dst", pattern> { 8313 let DecoderMethod = "DecodeModImmTiedInstruction"; 8314} 8315 8316class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 8317 RegisterOperand vectype, string asm, 8318 string kind, list<dag> pattern> 8319 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8320 (ins logical_vec_shift:$shift), 8321 "$shift", asm, kind, pattern> { 8322 bits<2> shift; 8323 let Inst{15} = b15_b12{1}; 8324 let Inst{14-13} = shift; 8325 let Inst{12} = b15_b12{0}; 8326} 8327 8328class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 8329 RegisterOperand vectype, string asm, 8330 string kind, list<dag> pattern> 8331 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8332 (ins logical_vec_shift:$shift), 8333 "$shift", asm, kind, pattern> { 8334 bits<2> shift; 8335 let Inst{15} = b15_b12{1}; 8336 let Inst{14-13} = shift; 8337 let Inst{12} = b15_b12{0}; 8338} 8339 8340 8341class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 8342 RegisterOperand vectype, string asm, 8343 string kind, list<dag> pattern> 8344 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8345 (ins logical_vec_hw_shift:$shift), 8346 "$shift", asm, kind, pattern> { 8347 bits<2> shift; 8348 let Inst{15} = b15_b12{1}; 8349 let Inst{14} = 0; 8350 let Inst{13} = shift{0}; 8351 let Inst{12} = b15_b12{0}; 8352} 8353 8354class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 8355 RegisterOperand vectype, string asm, 8356 string kind, list<dag> pattern> 8357 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8358 (ins logical_vec_hw_shift:$shift), 8359 "$shift", asm, kind, pattern> { 8360 bits<2> shift; 8361 let Inst{15} = b15_b12{1}; 8362 let Inst{14} = 0; 8363 let Inst{13} = shift{0}; 8364 let Inst{12} = b15_b12{0}; 8365} 8366 8367multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 8368 string asm> { 8369 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 8370 asm, ".4h", []>; 8371 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 8372 asm, ".8h", []>; 8373 8374 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 8375 asm, ".2s", []>; 8376 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 8377 asm, ".4s", []>; 8378} 8379 8380multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 8381 bits<2> w_cmode, string asm, 8382 SDNode OpNode> { 8383 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 8384 asm, ".4h", 8385 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 8386 imm0_255:$imm8, 8387 (i32 imm:$shift)))]>; 8388 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 8389 asm, ".8h", 8390 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 8391 imm0_255:$imm8, 8392 (i32 imm:$shift)))]>; 8393 8394 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 8395 asm, ".2s", 8396 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 8397 imm0_255:$imm8, 8398 (i32 imm:$shift)))]>; 8399 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 8400 asm, ".4s", 8401 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 8402 imm0_255:$imm8, 8403 (i32 imm:$shift)))]>; 8404} 8405 8406class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 8407 RegisterOperand vectype, string asm, 8408 string kind, list<dag> pattern> 8409 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8410 (ins move_vec_shift:$shift), 8411 "$shift", asm, kind, pattern> { 8412 bits<1> shift; 8413 let Inst{15-13} = cmode{3-1}; 8414 let Inst{12} = shift; 8415} 8416 8417class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 8418 RegisterOperand vectype, 8419 Operand imm_type, string asm, 8420 string kind, list<dag> pattern> 8421 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 8422 asm, kind, pattern> { 8423 let Inst{15-12} = cmode; 8424} 8425 8426class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 8427 list<dag> pattern> 8428 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 8429 "\t$Rd, $imm8", "", pattern> { 8430 let Inst{15-12} = cmode; 8431 let DecoderMethod = "DecodeModImmInstruction"; 8432} 8433 8434//---------------------------------------------------------------------------- 8435// AdvSIMD indexed element 8436//---------------------------------------------------------------------------- 8437 8438let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8439class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8440 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8441 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8442 string apple_kind, string dst_kind, string lhs_kind, 8443 string rhs_kind, list<dag> pattern> 8444 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8445 asm, 8446 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8447 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8448 Sched<[WriteVd]> { 8449 bits<5> Rd; 8450 bits<5> Rn; 8451 bits<5> Rm; 8452 8453 let Inst{31} = 0; 8454 let Inst{30} = Q; 8455 let Inst{29} = U; 8456 let Inst{28} = Scalar; 8457 let Inst{27-24} = 0b1111; 8458 let Inst{23-22} = size; 8459 // Bit 21 must be set by the derived class. 8460 let Inst{20-16} = Rm; 8461 let Inst{15-12} = opc; 8462 // Bit 11 must be set by the derived class. 8463 let Inst{10} = 0; 8464 let Inst{9-5} = Rn; 8465 let Inst{4-0} = Rd; 8466} 8467 8468let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8469class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8470 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8471 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8472 string apple_kind, string dst_kind, string lhs_kind, 8473 string rhs_kind, list<dag> pattern> 8474 : I<(outs dst_reg:$dst), 8475 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8476 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8477 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8478 Sched<[WriteVd]> { 8479 bits<5> Rd; 8480 bits<5> Rn; 8481 bits<5> Rm; 8482 8483 let Inst{31} = 0; 8484 let Inst{30} = Q; 8485 let Inst{29} = U; 8486 let Inst{28} = Scalar; 8487 let Inst{27-24} = 0b1111; 8488 let Inst{23-22} = size; 8489 // Bit 21 must be set by the derived class. 8490 let Inst{20-16} = Rm; 8491 let Inst{15-12} = opc; 8492 // Bit 11 must be set by the derived class. 8493 let Inst{10} = 0; 8494 let Inst{9-5} = Rn; 8495 let Inst{4-0} = Rd; 8496} 8497 8498 8499//---------------------------------------------------------------------------- 8500// Armv8.6 BFloat16 Extension 8501//---------------------------------------------------------------------------- 8502let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8503 8504class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8505 string kind2, RegisterOperand RegType, 8506 ValueType AccumType, ValueType InputType> 8507 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8508 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8509 (InputType RegType:$Rn), 8510 (InputType RegType:$Rm)))]> { 8511 let AsmString = !strconcat(asm, 8512 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8513 ", $Rm" # kind2 # "}"); 8514} 8515 8516multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8517 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8518 v2f32, v4bf16>; 8519 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8520 v4f32, v8bf16>; 8521} 8522 8523class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8524 string dst_kind, string lhs_kind, 8525 string rhs_kind, 8526 RegisterOperand RegType, 8527 ValueType AccumType, 8528 ValueType InputType> 8529 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8530 RegType, RegType, V128, VectorIndexS, 8531 asm, "", dst_kind, lhs_kind, rhs_kind, 8532 [(set (AccumType RegType:$dst), 8533 (AccumType (int_aarch64_neon_bfdot 8534 (AccumType RegType:$Rd), 8535 (InputType RegType:$Rn), 8536 (InputType (bitconvert (AccumType 8537 (AArch64duplane32 (v4f32 V128:$Rm), 8538 VectorIndexS:$idx)))))))]> { 8539 8540 bits<2> idx; 8541 let Inst{21} = idx{0}; // L 8542 let Inst{11} = idx{1}; // H 8543} 8544 8545multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8546 8547 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8548 ".2h", V64, v2f32, v4bf16>; 8549 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8550 ".2h", V128, v4f32, v8bf16>; 8551} 8552 8553let mayRaiseFPException = 1, Uses = [FPCR] in 8554class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8555 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8556 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8557 (v8bf16 V128:$Rn), 8558 (v8bf16 V128:$Rm)))]> { 8559 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8560} 8561 8562let mayRaiseFPException = 1, Uses = [FPCR] in 8563class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8564 : I<(outs V128:$dst), 8565 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8566 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8567 [(set (v4f32 V128:$dst), 8568 (v4f32 (OpNode (v4f32 V128:$Rd), 8569 (v8bf16 V128:$Rn), 8570 (v8bf16 8571 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8572 VectorIndexH:$idx)))))]>, 8573 Sched<[WriteVq]> { 8574 bits<5> Rd; 8575 bits<5> Rn; 8576 bits<4> Rm; 8577 bits<3> idx; 8578 8579 let Inst{31} = 0; 8580 let Inst{30} = Q; 8581 let Inst{29-22} = 0b00111111; 8582 let Inst{21-20} = idx{1-0}; 8583 let Inst{19-16} = Rm; 8584 let Inst{15-12} = 0b1111; 8585 let Inst{11} = idx{2}; // H 8586 let Inst{10} = 0; 8587 let Inst{9-5} = Rn; 8588 let Inst{4-0} = Rd; 8589} 8590 8591class SIMDThreeSameVectorBF16MatrixMul<string asm> 8592 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8593 V128, asm, ".4s", 8594 [(set (v4f32 V128:$dst), 8595 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8596 (v8bf16 V128:$Rn), 8597 (v8bf16 V128:$Rm)))]> { 8598 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8599 ", $Rm", ".8h", "}"); 8600} 8601 8602let mayRaiseFPException = 1, Uses = [FPCR] in 8603class SIMD_BFCVTN 8604 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8605 "bfcvtn", ".4h", ".4s", 8606 [(set (v8bf16 V128:$Rd), 8607 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8608 8609let mayRaiseFPException = 1, Uses = [FPCR] in 8610class SIMD_BFCVTN2 8611 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8612 "bfcvtn2", ".8h", ".4s", 8613 [(set (v8bf16 V128:$dst), 8614 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8615 8616let mayRaiseFPException = 1, Uses = [FPCR] in 8617class BF16ToSinglePrecision<string asm> 8618 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8619 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8620 Sched<[WriteFCvt]> { 8621 bits<5> Rd; 8622 bits<5> Rn; 8623 let Inst{31-10} = 0b0001111001100011010000; 8624 let Inst{9-5} = Rn; 8625 let Inst{4-0} = Rd; 8626} 8627} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8628 8629//---------------------------------------------------------------------------- 8630class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc, 8631 string asm, string dst_kind, 8632 RegisterOperand RegType, 8633 RegisterOperand RegType_lo> 8634 : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc, 8635 RegType, RegType, RegType_lo, VectorIndexB, 8636 asm, "", dst_kind, ".16b", ".b", []> { 8637 8638 // idx = H:L:M 8639 bits<4> idx; 8640 let Inst{11} = idx{3}; 8641 let Inst{21-19} = idx{2-0}; 8642} 8643 8644multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm> { 8645 def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h", 8646 V128, V128_0to7>; 8647} 8648 8649multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm> { 8650 def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s", 8651 V128, V128_0to7>; 8652} 8653 8654//---------------------------------------------------------------------------- 8655// Armv8.6 Matrix Multiply Extension 8656//---------------------------------------------------------------------------- 8657 8658class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8659 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8660 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8661 (v16i8 V128:$Rn), 8662 (v16i8 V128:$Rm)))]> { 8663 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8664} 8665 8666//---------------------------------------------------------------------------- 8667// ARMv8.2-A Dot Product Instructions (Indexed) 8668class BaseSIMDThreeSameVectorIndexS<bit Q, bit U, bits<2> size, bits<4> opc, string asm, 8669 string dst_kind, string lhs_kind, string rhs_kind, 8670 RegisterOperand RegType, 8671 ValueType AccumType, ValueType InputType, 8672 SDPatternOperator OpNode> : 8673 BaseSIMDIndexedTied<Q, U, 0b0, size, opc, RegType, RegType, V128, 8674 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8675 [(set (AccumType RegType:$dst), 8676 (AccumType (OpNode (AccumType RegType:$Rd), 8677 (InputType RegType:$Rn), 8678 (InputType (bitconvert (AccumType 8679 (AArch64duplane32 (v4i32 V128:$Rm), 8680 VectorIndexS:$idx)))))))]> { 8681 bits<2> idx; 8682 let Inst{21} = idx{0}; // L 8683 let Inst{11} = idx{1}; // H 8684} 8685 8686multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8687 SDPatternOperator OpNode> { 8688 def v8i8 : BaseSIMDThreeSameVectorIndexS<0, U, size, {0b111, Mixed}, asm, ".2s", ".8b", ".4b", 8689 V64, v2i32, v8i8, OpNode>; 8690 def v16i8 : BaseSIMDThreeSameVectorIndexS<1, U, size, {0b111, Mixed}, asm, ".4s", ".16b", ".4b", 8691 V128, v4i32, v16i8, OpNode>; 8692} 8693 8694// TODO: The vectors v8i8 and v16i8 should be v8f8 and v16f8 8695multiclass SIMDThreeSameVectorFP8DOT4Index<string asm> { 8696 def v8f8 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b00, 0b0000, asm, ".2s", ".8b", ".4b", 8697 V64, v2f32, v8i8, null_frag>; 8698 def v16f8 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b00, 0b0000, asm, ".4s", ".16b",".4b", 8699 V128, v4f32, v16i8, null_frag>; 8700} 8701 8702// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8703let mayRaiseFPException = 1, Uses = [FPCR] in 8704class BaseSIMDThreeSameVectorIndexH<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 8705 string dst_kind, string lhs_kind, 8706 string rhs_kind, RegisterOperand RegType, 8707 RegisterOperand RegType_lo, ValueType AccumType, 8708 ValueType InputType, SDPatternOperator OpNode> : 8709 BaseSIMDIndexedTied<Q, U, 0, sz, opc, RegType, RegType, RegType_lo, 8710 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8711 [(set (AccumType RegType:$dst), 8712 (AccumType (OpNode (AccumType RegType:$Rd), 8713 (InputType RegType:$Rn), 8714 (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm), 8715 VectorIndexH:$idx)))))]> { 8716 // idx = H:L:M 8717 bits<3> idx; 8718 let Inst{11} = idx{2}; // H 8719 let Inst{21} = idx{1}; // L 8720 let Inst{20} = idx{0}; // M 8721} 8722 8723multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8724 SDPatternOperator OpNode> { 8725 def v4f16 : BaseSIMDThreeSameVectorIndexH<0, U, 0b10, opc, asm, ".2s", ".2h", ".h", 8726 V64, V128_lo, v2f32, v4f16, OpNode>; 8727 def v8f16 : BaseSIMDThreeSameVectorIndexH<1, U, 0b10, opc, asm, ".4s", ".4h", ".h", 8728 V128, V128_lo, v4f32, v8f16, OpNode>; 8729} 8730 8731//---------------------------------------------------------------------------- 8732// FP8 Advanced SIMD vector x indexed element 8733// TODO: Replace value types v8i8 and v16i8 by v8f8 and v16f8 8734multiclass SIMDThreeSameVectorFP8DOT2Index<string asm> { 8735 def v4f16 : BaseSIMDThreeSameVectorIndexH<0b0, 0b0, 0b01, 0b0000, asm, ".4h", ".8b", ".2b", 8736 V64, V128_lo, v4f16, v8i8, null_frag>; 8737 def v8f16 : BaseSIMDThreeSameVectorIndexH<0b1, 0b0, 0b01, 0b0000, asm, ".8h", ".16b", ".2b", 8738 V128, V128_lo, v8f16, v8i16, null_frag>; 8739} 8740 8741multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8742 SDPatternOperator OpNode> { 8743 let mayRaiseFPException = 1, Uses = [FPCR] in { 8744 let Predicates = [HasNEON, HasFullFP16] in { 8745 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8746 V64, V64, 8747 V128_lo, VectorIndexH, 8748 asm, ".4h", ".4h", ".4h", ".h", 8749 [(set (v4f16 V64:$Rd), 8750 (OpNode (v4f16 V64:$Rn), 8751 (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8752 bits<3> idx; 8753 let Inst{11} = idx{2}; 8754 let Inst{21} = idx{1}; 8755 let Inst{20} = idx{0}; 8756 } 8757 8758 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8759 V128, V128, 8760 V128_lo, VectorIndexH, 8761 asm, ".8h", ".8h", ".8h", ".h", 8762 [(set (v8f16 V128:$Rd), 8763 (OpNode (v8f16 V128:$Rn), 8764 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8765 bits<3> idx; 8766 let Inst{11} = idx{2}; 8767 let Inst{21} = idx{1}; 8768 let Inst{20} = idx{0}; 8769 } 8770 } // Predicates = [HasNEON, HasFullFP16] 8771 8772 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8773 V64, V64, 8774 V128, VectorIndexS, 8775 asm, ".2s", ".2s", ".2s", ".s", 8776 [(set (v2f32 V64:$Rd), 8777 (OpNode (v2f32 V64:$Rn), 8778 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> { 8779 bits<2> idx; 8780 let Inst{11} = idx{1}; 8781 let Inst{21} = idx{0}; 8782 } 8783 8784 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8785 V128, V128, 8786 V128, VectorIndexS, 8787 asm, ".4s", ".4s", ".4s", ".s", 8788 [(set (v4f32 V128:$Rd), 8789 (OpNode (v4f32 V128:$Rn), 8790 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8791 bits<2> idx; 8792 let Inst{11} = idx{1}; 8793 let Inst{21} = idx{0}; 8794 } 8795 8796 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8797 V128, V128, 8798 V128, VectorIndexD, 8799 asm, ".2d", ".2d", ".2d", ".d", 8800 [(set (v2f64 V128:$Rd), 8801 (OpNode (v2f64 V128:$Rn), 8802 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8803 bits<1> idx; 8804 let Inst{11} = idx{0}; 8805 let Inst{21} = 0; 8806 } 8807 8808 let Predicates = [HasNEON, HasFullFP16] in { 8809 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8810 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8811 asm, ".h", "", "", ".h", 8812 [(set (f16 FPR16Op:$Rd), 8813 (OpNode (f16 FPR16Op:$Rn), 8814 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8815 VectorIndexH:$idx))))]> { 8816 bits<3> idx; 8817 let Inst{11} = idx{2}; 8818 let Inst{21} = idx{1}; 8819 let Inst{20} = idx{0}; 8820 } 8821 } // Predicates = [HasNEON, HasFullFP16] 8822 8823 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8824 FPR32Op, FPR32Op, V128, VectorIndexS, 8825 asm, ".s", "", "", ".s", 8826 [(set (f32 FPR32Op:$Rd), 8827 (OpNode (f32 FPR32Op:$Rn), 8828 (f32 (vector_extract (v4f32 V128:$Rm), 8829 VectorIndexS:$idx))))]> { 8830 bits<2> idx; 8831 let Inst{11} = idx{1}; 8832 let Inst{21} = idx{0}; 8833 } 8834 8835 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8836 FPR64Op, FPR64Op, V128, VectorIndexD, 8837 asm, ".d", "", "", ".d", 8838 [(set (f64 FPR64Op:$Rd), 8839 (OpNode (f64 FPR64Op:$Rn), 8840 (f64 (vector_extract (v2f64 V128:$Rm), 8841 VectorIndexD:$idx))))]> { 8842 bits<1> idx; 8843 let Inst{11} = idx{0}; 8844 let Inst{21} = 0; 8845 } 8846 } // mayRaiseFPException = 1, Uses = [FPCR] 8847 8848 let Predicates = [HasNEON, HasFullFP16] in { 8849 def : Pat<(f16 (OpNode 8850 (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))), 8851 (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))), 8852 (!cast<Instruction>(NAME # v1i16_indexed) 8853 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128:$Rm, VectorIndexH:$idx)>; 8854 } 8855 8856 let Predicates = [HasNEON] in { 8857 def : Pat<(f32 (OpNode 8858 (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))), 8859 (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))), 8860 (!cast<Instruction>(NAME # v1i32_indexed) 8861 (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>; 8862 8863 def : Pat<(f64 (OpNode 8864 (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))), 8865 (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))), 8866 (!cast<Instruction>(NAME # v1i64_indexed) 8867 (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>; 8868 } 8869} 8870 8871multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8872 let Predicates = [HasNEON, HasFullFP16] in { 8873 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8874 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8875 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8876 VectorIndexH:$idx))), 8877 (!cast<Instruction>(INST # "v8i16_indexed") 8878 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8879 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8880 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8881 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8882 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8883 8884 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8885 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8886 VectorIndexH:$idx))), 8887 (!cast<Instruction>(INST # "v4i16_indexed") 8888 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8889 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8890 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8891 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8892 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8893 8894 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8895 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8896 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8897 V128_lo:$Rm, VectorIndexH:$idx)>; 8898 } // Predicates = [HasNEON, HasFullFP16] 8899 8900 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8901 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8902 (AArch64duplane32 (v4f32 V128:$Rm), 8903 VectorIndexS:$idx))), 8904 (!cast<Instruction>(INST # v2i32_indexed) 8905 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8906 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8907 (AArch64dup (f32 FPR32Op:$Rm)))), 8908 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8909 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8910 8911 8912 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8913 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8914 (AArch64duplane32 (v4f32 V128:$Rm), 8915 VectorIndexS:$idx))), 8916 (!cast<Instruction>(INST # "v4i32_indexed") 8917 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8918 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8919 (AArch64dup (f32 FPR32Op:$Rm)))), 8920 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8921 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8922 8923 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8924 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8925 (AArch64duplane64 (v2f64 V128:$Rm), 8926 VectorIndexD:$idx))), 8927 (!cast<Instruction>(INST # "v2i64_indexed") 8928 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8929 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8930 (AArch64dup (f64 FPR64Op:$Rm)))), 8931 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 8932 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 8933 8934 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 8935 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 8936 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 8937 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 8938 V128:$Rm, VectorIndexS:$idx)>; 8939 8940 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 8941 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 8942 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 8943 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 8944 V128:$Rm, VectorIndexD:$idx)>; 8945} 8946 8947let mayRaiseFPException = 1, Uses = [FPCR] in 8948multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 8949 let Predicates = [HasNEON, HasFullFP16] in { 8950 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 8951 V128_lo, VectorIndexH, 8952 asm, ".4h", ".4h", ".4h", ".h", []> { 8953 bits<3> idx; 8954 let Inst{11} = idx{2}; 8955 let Inst{21} = idx{1}; 8956 let Inst{20} = idx{0}; 8957 } 8958 8959 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 8960 V128, V128, 8961 V128_lo, VectorIndexH, 8962 asm, ".8h", ".8h", ".8h", ".h", []> { 8963 bits<3> idx; 8964 let Inst{11} = idx{2}; 8965 let Inst{21} = idx{1}; 8966 let Inst{20} = idx{0}; 8967 } 8968 } // Predicates = [HasNEON, HasFullFP16] 8969 8970 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 8971 V128, VectorIndexS, 8972 asm, ".2s", ".2s", ".2s", ".s", []> { 8973 bits<2> idx; 8974 let Inst{11} = idx{1}; 8975 let Inst{21} = idx{0}; 8976 } 8977 8978 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8979 V128, V128, 8980 V128, VectorIndexS, 8981 asm, ".4s", ".4s", ".4s", ".s", []> { 8982 bits<2> idx; 8983 let Inst{11} = idx{1}; 8984 let Inst{21} = idx{0}; 8985 } 8986 8987 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 8988 V128, V128, 8989 V128, VectorIndexD, 8990 asm, ".2d", ".2d", ".2d", ".d", []> { 8991 bits<1> idx; 8992 let Inst{11} = idx{0}; 8993 let Inst{21} = 0; 8994 } 8995 8996 let Predicates = [HasNEON, HasFullFP16] in { 8997 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 8998 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8999 asm, ".h", "", "", ".h", []> { 9000 bits<3> idx; 9001 let Inst{11} = idx{2}; 9002 let Inst{21} = idx{1}; 9003 let Inst{20} = idx{0}; 9004 } 9005 } // Predicates = [HasNEON, HasFullFP16] 9006 9007 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9008 FPR32Op, FPR32Op, V128, VectorIndexS, 9009 asm, ".s", "", "", ".s", []> { 9010 bits<2> idx; 9011 let Inst{11} = idx{1}; 9012 let Inst{21} = idx{0}; 9013 } 9014 9015 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 9016 FPR64Op, FPR64Op, V128, VectorIndexD, 9017 asm, ".d", "", "", ".d", []> { 9018 bits<1> idx; 9019 let Inst{11} = idx{0}; 9020 let Inst{21} = 0; 9021 } 9022} 9023 9024multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 9025 SDPatternOperator OpNodeLaneQ> { 9026 9027 def : Pat<(v4i16 (OpNodeLane 9028 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 9029 VectorIndexS32b:$idx)), 9030 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 9031 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 9032 (UImmS1XForm $idx))>; 9033 9034 def : Pat<(v4i16 (OpNodeLaneQ 9035 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 9036 VectorIndexH32b:$idx)), 9037 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 9038 (UImmS1XForm $idx))>; 9039 9040 def : Pat<(v8i16 (OpNodeLane 9041 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 9042 VectorIndexS32b:$idx)), 9043 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 9044 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9045 (UImmS1XForm $idx))>; 9046 9047 def : Pat<(v8i16 (OpNodeLaneQ 9048 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 9049 VectorIndexH32b:$idx)), 9050 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 9051 (UImmS1XForm $idx))>; 9052 9053 def : Pat<(v2i32 (OpNodeLane 9054 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 9055 VectorIndexD32b:$idx)), 9056 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 9057 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 9058 (UImmS1XForm $idx))>; 9059 9060 def : Pat<(v2i32 (OpNodeLaneQ 9061 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 9062 VectorIndexS32b:$idx)), 9063 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 9064 (UImmS1XForm $idx))>; 9065 9066 def : Pat<(v4i32 (OpNodeLane 9067 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 9068 VectorIndexD32b:$idx)), 9069 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 9070 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9071 (UImmS1XForm $idx))>; 9072 9073 def : Pat<(v4i32 (OpNodeLaneQ 9074 (v4i32 V128:$Rn), 9075 (v4i32 V128:$Rm), 9076 VectorIndexS32b:$idx)), 9077 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 9078 (UImmS1XForm $idx))>; 9079 9080} 9081 9082multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 9083 SDPatternOperator OpNode> { 9084 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 9085 V128_lo, VectorIndexH, 9086 asm, ".4h", ".4h", ".4h", ".h", 9087 [(set (v4i16 V64:$Rd), 9088 (OpNode (v4i16 V64:$Rn), 9089 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9090 bits<3> idx; 9091 let Inst{11} = idx{2}; 9092 let Inst{21} = idx{1}; 9093 let Inst{20} = idx{0}; 9094 } 9095 9096 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9097 V128, V128, 9098 V128_lo, VectorIndexH, 9099 asm, ".8h", ".8h", ".8h", ".h", 9100 [(set (v8i16 V128:$Rd), 9101 (OpNode (v8i16 V128:$Rn), 9102 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9103 bits<3> idx; 9104 let Inst{11} = idx{2}; 9105 let Inst{21} = idx{1}; 9106 let Inst{20} = idx{0}; 9107 } 9108 9109 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9110 V64, V64, 9111 V128, VectorIndexS, 9112 asm, ".2s", ".2s", ".2s", ".s", 9113 [(set (v2i32 V64:$Rd), 9114 (OpNode (v2i32 V64:$Rn), 9115 (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 v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9122 V128, V128, 9123 V128, VectorIndexS, 9124 asm, ".4s", ".4s", ".4s", ".s", 9125 [(set (v4i32 V128:$Rd), 9126 (OpNode (v4i32 V128:$Rn), 9127 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9128 bits<2> idx; 9129 let Inst{11} = idx{1}; 9130 let Inst{21} = idx{0}; 9131 } 9132 9133 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9134 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9135 asm, ".h", "", "", ".h", []> { 9136 bits<3> idx; 9137 let Inst{11} = idx{2}; 9138 let Inst{21} = idx{1}; 9139 let Inst{20} = idx{0}; 9140 } 9141 9142 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9143 FPR32Op, FPR32Op, V128, VectorIndexS, 9144 asm, ".s", "", "", ".s", 9145 [(set (i32 FPR32Op:$Rd), 9146 (OpNode FPR32Op:$Rn, 9147 (i32 (vector_extract (v4i32 V128:$Rm), 9148 VectorIndexS:$idx))))]> { 9149 bits<2> idx; 9150 let Inst{11} = idx{1}; 9151 let Inst{21} = idx{0}; 9152 } 9153} 9154 9155multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 9156 SDPatternOperator OpNode> { 9157 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9158 V64, V64, 9159 V128_lo, VectorIndexH, 9160 asm, ".4h", ".4h", ".4h", ".h", 9161 [(set (v4i16 V64:$Rd), 9162 (OpNode (v4i16 V64:$Rn), 9163 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9164 bits<3> idx; 9165 let Inst{11} = idx{2}; 9166 let Inst{21} = idx{1}; 9167 let Inst{20} = idx{0}; 9168 } 9169 9170 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9171 V128, V128, 9172 V128_lo, VectorIndexH, 9173 asm, ".8h", ".8h", ".8h", ".h", 9174 [(set (v8i16 V128:$Rd), 9175 (OpNode (v8i16 V128:$Rn), 9176 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9177 bits<3> idx; 9178 let Inst{11} = idx{2}; 9179 let Inst{21} = idx{1}; 9180 let Inst{20} = idx{0}; 9181 } 9182 9183 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9184 V64, V64, 9185 V128, VectorIndexS, 9186 asm, ".2s", ".2s", ".2s", ".s", 9187 [(set (v2i32 V64:$Rd), 9188 (OpNode (v2i32 V64:$Rn), 9189 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9190 bits<2> idx; 9191 let Inst{11} = idx{1}; 9192 let Inst{21} = idx{0}; 9193 } 9194 9195 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9196 V128, V128, 9197 V128, VectorIndexS, 9198 asm, ".4s", ".4s", ".4s", ".s", 9199 [(set (v4i32 V128:$Rd), 9200 (OpNode (v4i32 V128:$Rn), 9201 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9202 bits<2> idx; 9203 let Inst{11} = idx{1}; 9204 let Inst{21} = idx{0}; 9205 } 9206} 9207 9208multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 9209 SDPatternOperator OpNode> { 9210 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 9211 V128_lo, VectorIndexH, 9212 asm, ".4h", ".4h", ".4h", ".h", 9213 [(set (v4i16 V64:$dst), 9214 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 9215 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9216 bits<3> idx; 9217 let Inst{11} = idx{2}; 9218 let Inst{21} = idx{1}; 9219 let Inst{20} = idx{0}; 9220 } 9221 9222 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9223 V128, V128, 9224 V128_lo, VectorIndexH, 9225 asm, ".8h", ".8h", ".8h", ".h", 9226 [(set (v8i16 V128:$dst), 9227 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9228 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9229 bits<3> idx; 9230 let Inst{11} = idx{2}; 9231 let Inst{21} = idx{1}; 9232 let Inst{20} = idx{0}; 9233 } 9234 9235 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9236 V64, V64, 9237 V128, VectorIndexS, 9238 asm, ".2s", ".2s", ".2s", ".s", 9239 [(set (v2i32 V64:$dst), 9240 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9241 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9242 bits<2> idx; 9243 let Inst{11} = idx{1}; 9244 let Inst{21} = idx{0}; 9245 } 9246 9247 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9248 V128, V128, 9249 V128, VectorIndexS, 9250 asm, ".4s", ".4s", ".4s", ".s", 9251 [(set (v4i32 V128:$dst), 9252 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9253 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9254 bits<2> idx; 9255 let Inst{11} = idx{1}; 9256 let Inst{21} = idx{0}; 9257 } 9258} 9259 9260multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 9261 SDPatternOperator OpNode> { 9262 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9263 V128, V64, 9264 V128_lo, VectorIndexH, 9265 asm, ".4s", ".4s", ".4h", ".h", 9266 [(set (v4i32 V128:$Rd), 9267 (OpNode (v4i16 V64:$Rn), 9268 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9269 bits<3> idx; 9270 let Inst{11} = idx{2}; 9271 let Inst{21} = idx{1}; 9272 let Inst{20} = idx{0}; 9273 } 9274 9275 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9276 V128, V128, 9277 V128_lo, VectorIndexH, 9278 asm#"2", ".4s", ".4s", ".8h", ".h", 9279 [(set (v4i32 V128:$Rd), 9280 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9281 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9282 9283 bits<3> idx; 9284 let Inst{11} = idx{2}; 9285 let Inst{21} = idx{1}; 9286 let Inst{20} = idx{0}; 9287 } 9288 9289 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9290 V128, V64, 9291 V128, VectorIndexS, 9292 asm, ".2d", ".2d", ".2s", ".s", 9293 [(set (v2i64 V128:$Rd), 9294 (OpNode (v2i32 V64:$Rn), 9295 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9296 bits<2> idx; 9297 let Inst{11} = idx{1}; 9298 let Inst{21} = idx{0}; 9299 } 9300 9301 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9302 V128, V128, 9303 V128, VectorIndexS, 9304 asm#"2", ".2d", ".2d", ".4s", ".s", 9305 [(set (v2i64 V128:$Rd), 9306 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9307 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9308 bits<2> idx; 9309 let Inst{11} = idx{1}; 9310 let Inst{21} = idx{0}; 9311 } 9312 9313 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9314 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9315 asm, ".h", "", "", ".h", []> { 9316 bits<3> idx; 9317 let Inst{11} = idx{2}; 9318 let Inst{21} = idx{1}; 9319 let Inst{20} = idx{0}; 9320 } 9321 9322 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9323 FPR64Op, FPR32Op, V128, VectorIndexS, 9324 asm, ".s", "", "", ".s", []> { 9325 bits<2> idx; 9326 let Inst{11} = idx{1}; 9327 let Inst{21} = idx{0}; 9328 } 9329} 9330 9331multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 9332 SDPatternOperator Accum> { 9333 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9334 V128, V64, 9335 V128_lo, VectorIndexH, 9336 asm, ".4s", ".4s", ".4h", ".h", 9337 [(set (v4i32 V128:$dst), 9338 (Accum (v4i32 V128:$Rd), 9339 (v4i32 (int_aarch64_neon_sqdmull 9340 (v4i16 V64:$Rn), 9341 (dup_v8i16 (v8i16 V128_lo:$Rm), 9342 VectorIndexH:$idx)))))]> { 9343 bits<3> idx; 9344 let Inst{11} = idx{2}; 9345 let Inst{21} = idx{1}; 9346 let Inst{20} = idx{0}; 9347 } 9348 9349 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9350 V128, V128, 9351 V128_lo, VectorIndexH, 9352 asm#"2", ".4s", ".4s", ".8h", ".h", 9353 [(set (v4i32 V128:$dst), 9354 (Accum (v4i32 V128:$Rd), 9355 (v4i32 (int_aarch64_neon_sqdmull 9356 (extract_high_v8i16 (v8i16 V128:$Rn)), 9357 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 9358 bits<3> idx; 9359 let Inst{11} = idx{2}; 9360 let Inst{21} = idx{1}; 9361 let Inst{20} = idx{0}; 9362 } 9363 9364 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9365 V128, V64, 9366 V128, VectorIndexS, 9367 asm, ".2d", ".2d", ".2s", ".s", 9368 [(set (v2i64 V128:$dst), 9369 (Accum (v2i64 V128:$Rd), 9370 (v2i64 (int_aarch64_neon_sqdmull 9371 (v2i32 V64:$Rn), 9372 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9373 bits<2> idx; 9374 let Inst{11} = idx{1}; 9375 let Inst{21} = idx{0}; 9376 } 9377 9378 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9379 V128, V128, 9380 V128, VectorIndexS, 9381 asm#"2", ".2d", ".2d", ".4s", ".s", 9382 [(set (v2i64 V128:$dst), 9383 (Accum (v2i64 V128:$Rd), 9384 (v2i64 (int_aarch64_neon_sqdmull 9385 (extract_high_v4i32 (v4i32 V128:$Rn)), 9386 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9387 bits<2> idx; 9388 let Inst{11} = idx{1}; 9389 let Inst{21} = idx{0}; 9390 } 9391 9392 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9393 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9394 asm, ".h", "", "", ".h", []> { 9395 bits<3> idx; 9396 let Inst{11} = idx{2}; 9397 let Inst{21} = idx{1}; 9398 let Inst{20} = idx{0}; 9399 } 9400 9401 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9402 (i32 (vector_extract 9403 (v4i32 (int_aarch64_neon_sqdmull 9404 (v4i16 V64:$Rn), 9405 (v4i16 V64:$Rm))), 9406 (i64 0))))), 9407 (!cast<Instruction>(NAME # v1i32_indexed) 9408 FPR32Op:$Rd, 9409 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9410 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub), 9411 (i64 0))>; 9412 9413 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9414 (i32 (vector_extract 9415 (v4i32 (int_aarch64_neon_sqdmull 9416 (v4i16 V64:$Rn), 9417 (dup_v8i16 (v8i16 V128_lo:$Rm), 9418 VectorIndexH:$idx))), 9419 (i64 0))))), 9420 (!cast<Instruction>(NAME # v1i32_indexed) 9421 FPR32Op:$Rd, 9422 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9423 V128_lo:$Rm, 9424 VectorIndexH:$idx)>; 9425 9426 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9427 FPR64Op, FPR32Op, V128, VectorIndexS, 9428 asm, ".s", "", "", ".s", 9429 [(set (i64 FPR64Op:$dst), 9430 (Accum (i64 FPR64Op:$Rd), 9431 (i64 (int_aarch64_neon_sqdmulls_scalar 9432 (i32 FPR32Op:$Rn), 9433 (i32 (vector_extract (v4i32 V128:$Rm), 9434 VectorIndexS:$idx))))))]> { 9435 9436 bits<2> idx; 9437 let Inst{11} = idx{1}; 9438 let Inst{21} = idx{0}; 9439 } 9440} 9441 9442multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 9443 SDPatternOperator OpNode> { 9444 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9445 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9446 V128, V64, 9447 V128_lo, VectorIndexH, 9448 asm, ".4s", ".4s", ".4h", ".h", 9449 [(set (v4i32 V128:$Rd), 9450 (OpNode (v4i16 V64:$Rn), 9451 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9452 bits<3> idx; 9453 let Inst{11} = idx{2}; 9454 let Inst{21} = idx{1}; 9455 let Inst{20} = idx{0}; 9456 } 9457 9458 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9459 V128, V128, 9460 V128_lo, VectorIndexH, 9461 asm#"2", ".4s", ".4s", ".8h", ".h", 9462 [(set (v4i32 V128:$Rd), 9463 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9464 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9465 9466 bits<3> idx; 9467 let Inst{11} = idx{2}; 9468 let Inst{21} = idx{1}; 9469 let Inst{20} = idx{0}; 9470 } 9471 9472 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9473 V128, V64, 9474 V128, VectorIndexS, 9475 asm, ".2d", ".2d", ".2s", ".s", 9476 [(set (v2i64 V128:$Rd), 9477 (OpNode (v2i32 V64:$Rn), 9478 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9479 bits<2> idx; 9480 let Inst{11} = idx{1}; 9481 let Inst{21} = idx{0}; 9482 } 9483 9484 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9485 V128, V128, 9486 V128, VectorIndexS, 9487 asm#"2", ".2d", ".2d", ".4s", ".s", 9488 [(set (v2i64 V128:$Rd), 9489 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9490 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9491 bits<2> idx; 9492 let Inst{11} = idx{1}; 9493 let Inst{21} = idx{0}; 9494 } 9495 } 9496} 9497 9498multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 9499 SDPatternOperator OpNode> { 9500 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9501 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9502 V128, V64, 9503 V128_lo, VectorIndexH, 9504 asm, ".4s", ".4s", ".4h", ".h", 9505 [(set (v4i32 V128:$dst), 9506 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 9507 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9508 bits<3> idx; 9509 let Inst{11} = idx{2}; 9510 let Inst{21} = idx{1}; 9511 let Inst{20} = idx{0}; 9512 } 9513 9514 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9515 V128, V128, 9516 V128_lo, VectorIndexH, 9517 asm#"2", ".4s", ".4s", ".8h", ".h", 9518 [(set (v4i32 V128:$dst), 9519 (OpNode (v4i32 V128:$Rd), 9520 (extract_high_v8i16 (v8i16 V128:$Rn)), 9521 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9522 bits<3> idx; 9523 let Inst{11} = idx{2}; 9524 let Inst{21} = idx{1}; 9525 let Inst{20} = idx{0}; 9526 } 9527 9528 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9529 V128, V64, 9530 V128, VectorIndexS, 9531 asm, ".2d", ".2d", ".2s", ".s", 9532 [(set (v2i64 V128:$dst), 9533 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9534 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9535 bits<2> idx; 9536 let Inst{11} = idx{1}; 9537 let Inst{21} = idx{0}; 9538 } 9539 9540 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9541 V128, V128, 9542 V128, VectorIndexS, 9543 asm#"2", ".2d", ".2d", ".4s", ".s", 9544 [(set (v2i64 V128:$dst), 9545 (OpNode (v2i64 V128:$Rd), 9546 (extract_high_v4i32 (v4i32 V128:$Rn)), 9547 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9548 bits<2> idx; 9549 let Inst{11} = idx{1}; 9550 let Inst{21} = idx{0}; 9551 } 9552 } 9553} 9554 9555//---------------------------------------------------------------------------- 9556// AdvSIMD scalar shift by immediate 9557//---------------------------------------------------------------------------- 9558 9559let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9560class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9561 RegisterClass regtype1, RegisterClass regtype2, 9562 Operand immtype, string asm, list<dag> pattern> 9563 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9564 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9565 Sched<[WriteVd]> { 9566 bits<5> Rd; 9567 bits<5> Rn; 9568 bits<7> imm; 9569 let Inst{31-30} = 0b01; 9570 let Inst{29} = U; 9571 let Inst{28-23} = 0b111110; 9572 let Inst{22-16} = fixed_imm; 9573 let Inst{15-11} = opc; 9574 let Inst{10} = 1; 9575 let Inst{9-5} = Rn; 9576 let Inst{4-0} = Rd; 9577} 9578 9579let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9580class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9581 RegisterClass regtype1, RegisterClass regtype2, 9582 Operand immtype, string asm, list<dag> pattern> 9583 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9584 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9585 Sched<[WriteVd]> { 9586 bits<5> Rd; 9587 bits<5> Rn; 9588 bits<7> imm; 9589 let Inst{31-30} = 0b01; 9590 let Inst{29} = U; 9591 let Inst{28-23} = 0b111110; 9592 let Inst{22-16} = fixed_imm; 9593 let Inst{15-11} = opc; 9594 let Inst{10} = 1; 9595 let Inst{9-5} = Rn; 9596 let Inst{4-0} = Rd; 9597} 9598 9599 9600multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9601 let Predicates = [HasNEON, HasFullFP16] in { 9602 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9603 FPR16, FPR16, vecshiftR16, asm, []> { 9604 let Inst{19-16} = imm{3-0}; 9605 } 9606 } // Predicates = [HasNEON, HasFullFP16] 9607 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9608 FPR32, FPR32, vecshiftR32, asm, []> { 9609 let Inst{20-16} = imm{4-0}; 9610 } 9611 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9612 FPR64, FPR64, vecshiftR64, asm, []> { 9613 let Inst{21-16} = imm{5-0}; 9614 } 9615} 9616 9617multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9618 SDPatternOperator OpNode> { 9619 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9620 FPR64, FPR64, vecshiftR64, asm, 9621 [(set (i64 FPR64:$Rd), 9622 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9623 let Inst{21-16} = imm{5-0}; 9624 } 9625 9626 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9627 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9628} 9629 9630multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9631 SDPatternOperator OpNode = null_frag> { 9632 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9633 FPR64, FPR64, vecshiftR64, asm, 9634 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9635 (i32 vecshiftR64:$imm)))]> { 9636 let Inst{21-16} = imm{5-0}; 9637 } 9638 9639 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9640 (i32 vecshiftR64:$imm))), 9641 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9642 vecshiftR64:$imm)>; 9643} 9644 9645multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9646 SDPatternOperator OpNode> { 9647 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9648 FPR64, FPR64, vecshiftL64, asm, 9649 [(set (i64 FPR64:$Rd), 9650 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9651 let Inst{21-16} = imm{5-0}; 9652 } 9653 9654 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9655 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9656} 9657 9658let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9659multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9660 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9661 FPR64, FPR64, vecshiftL64, asm, []> { 9662 let Inst{21-16} = imm{5-0}; 9663 } 9664} 9665 9666let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9667multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9668 SDPatternOperator OpNode = null_frag> { 9669 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9670 FPR8, FPR16, vecshiftR8, asm, []> { 9671 let Inst{18-16} = imm{2-0}; 9672 } 9673 9674 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9675 FPR16, FPR32, vecshiftR16, asm, []> { 9676 let Inst{19-16} = imm{3-0}; 9677 } 9678 9679 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9680 FPR32, FPR64, vecshiftR32, asm, 9681 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9682 let Inst{20-16} = imm{4-0}; 9683 } 9684} 9685 9686multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9687 SDPatternOperator OpNode> { 9688 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9689 FPR8, FPR8, vecshiftL8, asm, []> { 9690 let Inst{18-16} = imm{2-0}; 9691 } 9692 9693 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9694 FPR16, FPR16, vecshiftL16, asm, []> { 9695 let Inst{19-16} = imm{3-0}; 9696 } 9697 9698 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9699 FPR32, FPR32, vecshiftL32, asm, 9700 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9701 let Inst{20-16} = imm{4-0}; 9702 } 9703 9704 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9705 FPR64, FPR64, vecshiftL64, asm, 9706 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9707 let Inst{21-16} = imm{5-0}; 9708 } 9709 9710 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9711 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9712} 9713 9714multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9715 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9716 FPR8, FPR8, vecshiftR8, asm, []> { 9717 let Inst{18-16} = imm{2-0}; 9718 } 9719 9720 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9721 FPR16, FPR16, vecshiftR16, asm, []> { 9722 let Inst{19-16} = imm{3-0}; 9723 } 9724 9725 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9726 FPR32, FPR32, vecshiftR32, asm, []> { 9727 let Inst{20-16} = imm{4-0}; 9728 } 9729 9730 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9731 FPR64, FPR64, vecshiftR64, asm, []> { 9732 let Inst{21-16} = imm{5-0}; 9733 } 9734} 9735 9736//---------------------------------------------------------------------------- 9737// AdvSIMD vector x indexed element 9738//---------------------------------------------------------------------------- 9739 9740let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9741class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9742 RegisterOperand dst_reg, RegisterOperand src_reg, 9743 Operand immtype, 9744 string asm, string dst_kind, string src_kind, 9745 list<dag> pattern> 9746 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9747 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9748 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9749 Sched<[!if(Q, WriteVq, WriteVd)]> { 9750 bits<5> Rd; 9751 bits<5> Rn; 9752 let Inst{31} = 0; 9753 let Inst{30} = Q; 9754 let Inst{29} = U; 9755 let Inst{28-23} = 0b011110; 9756 let Inst{22-16} = fixed_imm; 9757 let Inst{15-11} = opc; 9758 let Inst{10} = 1; 9759 let Inst{9-5} = Rn; 9760 let Inst{4-0} = Rd; 9761} 9762 9763let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9764class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9765 RegisterOperand vectype1, RegisterOperand vectype2, 9766 Operand immtype, 9767 string asm, string dst_kind, string src_kind, 9768 list<dag> pattern> 9769 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9770 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9771 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9772 Sched<[!if(Q, WriteVq, WriteVd)]> { 9773 bits<5> Rd; 9774 bits<5> Rn; 9775 let Inst{31} = 0; 9776 let Inst{30} = Q; 9777 let Inst{29} = U; 9778 let Inst{28-23} = 0b011110; 9779 let Inst{22-16} = fixed_imm; 9780 let Inst{15-11} = opc; 9781 let Inst{10} = 1; 9782 let Inst{9-5} = Rn; 9783 let Inst{4-0} = Rd; 9784} 9785 9786multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9787 Intrinsic OpNode> { 9788 let Predicates = [HasNEON, HasFullFP16] in { 9789 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9790 V64, V64, vecshiftR16, 9791 asm, ".4h", ".4h", 9792 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9793 bits<4> imm; 9794 let Inst{19-16} = imm; 9795 } 9796 9797 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9798 V128, V128, vecshiftR16, 9799 asm, ".8h", ".8h", 9800 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9801 bits<4> imm; 9802 let Inst{19-16} = imm; 9803 } 9804 } // Predicates = [HasNEON, HasFullFP16] 9805 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9806 V64, V64, vecshiftR32, 9807 asm, ".2s", ".2s", 9808 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9809 bits<5> imm; 9810 let Inst{20-16} = imm; 9811 } 9812 9813 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9814 V128, V128, vecshiftR32, 9815 asm, ".4s", ".4s", 9816 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9817 bits<5> imm; 9818 let Inst{20-16} = imm; 9819 } 9820 9821 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9822 V128, V128, vecshiftR64, 9823 asm, ".2d", ".2d", 9824 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9825 bits<6> imm; 9826 let Inst{21-16} = imm; 9827 } 9828} 9829 9830multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9831 Intrinsic OpNode> { 9832 let Predicates = [HasNEON, HasFullFP16] in { 9833 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9834 V64, V64, vecshiftR16, 9835 asm, ".4h", ".4h", 9836 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9837 bits<4> imm; 9838 let Inst{19-16} = imm; 9839 } 9840 9841 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9842 V128, V128, vecshiftR16, 9843 asm, ".8h", ".8h", 9844 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9845 bits<4> imm; 9846 let Inst{19-16} = imm; 9847 } 9848 } // Predicates = [HasNEON, HasFullFP16] 9849 9850 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9851 V64, V64, vecshiftR32, 9852 asm, ".2s", ".2s", 9853 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9854 bits<5> imm; 9855 let Inst{20-16} = imm; 9856 } 9857 9858 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9859 V128, V128, vecshiftR32, 9860 asm, ".4s", ".4s", 9861 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9862 bits<5> imm; 9863 let Inst{20-16} = imm; 9864 } 9865 9866 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9867 V128, V128, vecshiftR64, 9868 asm, ".2d", ".2d", 9869 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9870 bits<6> imm; 9871 let Inst{21-16} = imm; 9872 } 9873} 9874 9875multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9876 SDPatternOperator OpNode> { 9877 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9878 V64, V128, vecshiftR16Narrow, 9879 asm, ".8b", ".8h", 9880 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9881 bits<3> imm; 9882 let Inst{18-16} = imm; 9883 } 9884 9885 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9886 V128, V128, vecshiftR16Narrow, 9887 asm#"2", ".16b", ".8h", []> { 9888 bits<3> imm; 9889 let Inst{18-16} = imm; 9890 let hasSideEffects = 0; 9891 } 9892 9893 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9894 V64, V128, vecshiftR32Narrow, 9895 asm, ".4h", ".4s", 9896 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9897 bits<4> imm; 9898 let Inst{19-16} = imm; 9899 } 9900 9901 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9902 V128, V128, vecshiftR32Narrow, 9903 asm#"2", ".8h", ".4s", []> { 9904 bits<4> imm; 9905 let Inst{19-16} = imm; 9906 let hasSideEffects = 0; 9907 } 9908 9909 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9910 V64, V128, vecshiftR64Narrow, 9911 asm, ".2s", ".2d", 9912 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9913 bits<5> imm; 9914 let Inst{20-16} = imm; 9915 } 9916 9917 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9918 V128, V128, vecshiftR64Narrow, 9919 asm#"2", ".4s", ".2d", []> { 9920 bits<5> imm; 9921 let Inst{20-16} = imm; 9922 let hasSideEffects = 0; 9923 } 9924 9925 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 9926 // themselves, so put them here instead. 9927 9928 // Patterns involving what's effectively an insert high and a normal 9929 // intrinsic, represented by CONCAT_VECTORS. 9930 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 9931 vecshiftR16Narrow:$imm)), 9932 (!cast<Instruction>(NAME # "v16i8_shift") 9933 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9934 V128:$Rn, vecshiftR16Narrow:$imm)>; 9935 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 9936 vecshiftR32Narrow:$imm)), 9937 (!cast<Instruction>(NAME # "v8i16_shift") 9938 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9939 V128:$Rn, vecshiftR32Narrow:$imm)>; 9940 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 9941 vecshiftR64Narrow:$imm)), 9942 (!cast<Instruction>(NAME # "v4i32_shift") 9943 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 9944 V128:$Rn, vecshiftR64Narrow:$imm)>; 9945} 9946 9947multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 9948 SDPatternOperator OpNode> { 9949 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9950 V64, V64, vecshiftL8, 9951 asm, ".8b", ".8b", 9952 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 9953 (i32 vecshiftL8:$imm)))]> { 9954 bits<3> imm; 9955 let Inst{18-16} = imm; 9956 } 9957 9958 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 9959 V128, V128, vecshiftL8, 9960 asm, ".16b", ".16b", 9961 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 9962 (i32 vecshiftL8:$imm)))]> { 9963 bits<3> imm; 9964 let Inst{18-16} = imm; 9965 } 9966 9967 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9968 V64, V64, vecshiftL16, 9969 asm, ".4h", ".4h", 9970 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 9971 (i32 vecshiftL16:$imm)))]> { 9972 bits<4> imm; 9973 let Inst{19-16} = imm; 9974 } 9975 9976 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9977 V128, V128, vecshiftL16, 9978 asm, ".8h", ".8h", 9979 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 9980 (i32 vecshiftL16:$imm)))]> { 9981 bits<4> imm; 9982 let Inst{19-16} = imm; 9983 } 9984 9985 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9986 V64, V64, vecshiftL32, 9987 asm, ".2s", ".2s", 9988 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 9989 (i32 vecshiftL32:$imm)))]> { 9990 bits<5> imm; 9991 let Inst{20-16} = imm; 9992 } 9993 9994 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9995 V128, V128, vecshiftL32, 9996 asm, ".4s", ".4s", 9997 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 9998 (i32 vecshiftL32:$imm)))]> { 9999 bits<5> imm; 10000 let Inst{20-16} = imm; 10001 } 10002 10003 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10004 V128, V128, vecshiftL64, 10005 asm, ".2d", ".2d", 10006 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10007 (i32 vecshiftL64:$imm)))]> { 10008 bits<6> imm; 10009 let Inst{21-16} = imm; 10010 } 10011} 10012 10013multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 10014 SDPatternOperator OpNode> { 10015 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10016 V64, V64, vecshiftR8, 10017 asm, ".8b", ".8b", 10018 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10019 (i32 vecshiftR8:$imm)))]> { 10020 bits<3> imm; 10021 let Inst{18-16} = imm; 10022 } 10023 10024 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10025 V128, V128, vecshiftR8, 10026 asm, ".16b", ".16b", 10027 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10028 (i32 vecshiftR8:$imm)))]> { 10029 bits<3> imm; 10030 let Inst{18-16} = imm; 10031 } 10032 10033 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10034 V64, V64, vecshiftR16, 10035 asm, ".4h", ".4h", 10036 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10037 (i32 vecshiftR16:$imm)))]> { 10038 bits<4> imm; 10039 let Inst{19-16} = imm; 10040 } 10041 10042 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10043 V128, V128, vecshiftR16, 10044 asm, ".8h", ".8h", 10045 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10046 (i32 vecshiftR16:$imm)))]> { 10047 bits<4> imm; 10048 let Inst{19-16} = imm; 10049 } 10050 10051 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10052 V64, V64, vecshiftR32, 10053 asm, ".2s", ".2s", 10054 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10055 (i32 vecshiftR32:$imm)))]> { 10056 bits<5> imm; 10057 let Inst{20-16} = imm; 10058 } 10059 10060 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10061 V128, V128, vecshiftR32, 10062 asm, ".4s", ".4s", 10063 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10064 (i32 vecshiftR32:$imm)))]> { 10065 bits<5> imm; 10066 let Inst{20-16} = imm; 10067 } 10068 10069 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10070 V128, V128, vecshiftR64, 10071 asm, ".2d", ".2d", 10072 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10073 (i32 vecshiftR64:$imm)))]> { 10074 bits<6> imm; 10075 let Inst{21-16} = imm; 10076 } 10077} 10078 10079let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10080multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 10081 SDPatternOperator OpNode = null_frag> { 10082 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10083 V64, V64, vecshiftR8, asm, ".8b", ".8b", 10084 [(set (v8i8 V64:$dst), 10085 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10086 (i32 vecshiftR8:$imm)))]> { 10087 bits<3> imm; 10088 let Inst{18-16} = imm; 10089 } 10090 10091 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10092 V128, V128, vecshiftR8, asm, ".16b", ".16b", 10093 [(set (v16i8 V128:$dst), 10094 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10095 (i32 vecshiftR8:$imm)))]> { 10096 bits<3> imm; 10097 let Inst{18-16} = imm; 10098 } 10099 10100 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10101 V64, V64, vecshiftR16, asm, ".4h", ".4h", 10102 [(set (v4i16 V64:$dst), 10103 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10104 (i32 vecshiftR16:$imm)))]> { 10105 bits<4> imm; 10106 let Inst{19-16} = imm; 10107 } 10108 10109 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10110 V128, V128, vecshiftR16, asm, ".8h", ".8h", 10111 [(set (v8i16 V128:$dst), 10112 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10113 (i32 vecshiftR16:$imm)))]> { 10114 bits<4> imm; 10115 let Inst{19-16} = imm; 10116 } 10117 10118 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10119 V64, V64, vecshiftR32, asm, ".2s", ".2s", 10120 [(set (v2i32 V64:$dst), 10121 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10122 (i32 vecshiftR32:$imm)))]> { 10123 bits<5> imm; 10124 let Inst{20-16} = imm; 10125 } 10126 10127 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10128 V128, V128, vecshiftR32, asm, ".4s", ".4s", 10129 [(set (v4i32 V128:$dst), 10130 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10131 (i32 vecshiftR32:$imm)))]> { 10132 bits<5> imm; 10133 let Inst{20-16} = imm; 10134 } 10135 10136 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10137 V128, V128, vecshiftR64, 10138 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 10139 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10140 (i32 vecshiftR64:$imm)))]> { 10141 bits<6> imm; 10142 let Inst{21-16} = imm; 10143 } 10144} 10145 10146multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 10147 SDPatternOperator OpNode = null_frag> { 10148 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10149 V64, V64, vecshiftL8, 10150 asm, ".8b", ".8b", 10151 [(set (v8i8 V64:$dst), 10152 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10153 (i32 vecshiftL8:$imm)))]> { 10154 bits<3> imm; 10155 let Inst{18-16} = imm; 10156 } 10157 10158 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10159 V128, V128, vecshiftL8, 10160 asm, ".16b", ".16b", 10161 [(set (v16i8 V128:$dst), 10162 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10163 (i32 vecshiftL8:$imm)))]> { 10164 bits<3> imm; 10165 let Inst{18-16} = imm; 10166 } 10167 10168 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10169 V64, V64, vecshiftL16, 10170 asm, ".4h", ".4h", 10171 [(set (v4i16 V64:$dst), 10172 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10173 (i32 vecshiftL16:$imm)))]> { 10174 bits<4> imm; 10175 let Inst{19-16} = imm; 10176 } 10177 10178 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10179 V128, V128, vecshiftL16, 10180 asm, ".8h", ".8h", 10181 [(set (v8i16 V128:$dst), 10182 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10183 (i32 vecshiftL16:$imm)))]> { 10184 bits<4> imm; 10185 let Inst{19-16} = imm; 10186 } 10187 10188 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10189 V64, V64, vecshiftL32, 10190 asm, ".2s", ".2s", 10191 [(set (v2i32 V64:$dst), 10192 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10193 (i32 vecshiftL32:$imm)))]> { 10194 bits<5> imm; 10195 let Inst{20-16} = imm; 10196 } 10197 10198 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10199 V128, V128, vecshiftL32, 10200 asm, ".4s", ".4s", 10201 [(set (v4i32 V128:$dst), 10202 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10203 (i32 vecshiftL32:$imm)))]> { 10204 bits<5> imm; 10205 let Inst{20-16} = imm; 10206 } 10207 10208 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10209 V128, V128, vecshiftL64, 10210 asm, ".2d", ".2d", 10211 [(set (v2i64 V128:$dst), 10212 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10213 (i32 vecshiftL64:$imm)))]> { 10214 bits<6> imm; 10215 let Inst{21-16} = imm; 10216 } 10217} 10218 10219multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 10220 SDPatternOperator OpNode> { 10221 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10222 V128, V64, vecshiftL8, asm, ".8h", ".8b", 10223 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 10224 bits<3> imm; 10225 let Inst{18-16} = imm; 10226 } 10227 10228 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10229 V128, V128, vecshiftL8, 10230 asm#"2", ".8h", ".16b", 10231 [(set (v8i16 V128:$Rd), 10232 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 10233 bits<3> imm; 10234 let Inst{18-16} = imm; 10235 } 10236 10237 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10238 V128, V64, vecshiftL16, asm, ".4s", ".4h", 10239 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 10240 bits<4> imm; 10241 let Inst{19-16} = imm; 10242 } 10243 10244 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10245 V128, V128, vecshiftL16, 10246 asm#"2", ".4s", ".8h", 10247 [(set (v4i32 V128:$Rd), 10248 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 10249 10250 bits<4> imm; 10251 let Inst{19-16} = imm; 10252 } 10253 10254 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10255 V128, V64, vecshiftL32, asm, ".2d", ".2s", 10256 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 10257 bits<5> imm; 10258 let Inst{20-16} = imm; 10259 } 10260 10261 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10262 V128, V128, vecshiftL32, 10263 asm#"2", ".2d", ".4s", 10264 [(set (v2i64 V128:$Rd), 10265 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 10266 bits<5> imm; 10267 let Inst{20-16} = imm; 10268 } 10269} 10270 10271 10272//--- 10273// Vector load/store 10274//--- 10275// SIMD ldX/stX no-index memory references don't allow the optional 10276// ", #0" constant and handle post-indexing explicitly, so we use 10277// a more specialized parse method for them. Otherwise, it's the same as 10278// the general GPR64sp handling. 10279 10280class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 10281 string asm, dag oops, dag iops, list<dag> pattern> 10282 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 10283 bits<5> Vt; 10284 bits<5> Rn; 10285 let Inst{31} = 0; 10286 let Inst{30} = Q; 10287 let Inst{29-23} = 0b0011000; 10288 let Inst{22} = L; 10289 let Inst{21-16} = 0b000000; 10290 let Inst{15-12} = opcode; 10291 let Inst{11-10} = size; 10292 let Inst{9-5} = Rn; 10293 let Inst{4-0} = Vt; 10294} 10295 10296class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 10297 string asm, dag oops, dag iops> 10298 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 10299 bits<5> Vt; 10300 bits<5> Rn; 10301 bits<5> Xm; 10302 let Inst{31} = 0; 10303 let Inst{30} = Q; 10304 let Inst{29-23} = 0b0011001; 10305 let Inst{22} = L; 10306 let Inst{21} = 0; 10307 let Inst{20-16} = Xm; 10308 let Inst{15-12} = opcode; 10309 let Inst{11-10} = size; 10310 let Inst{9-5} = Rn; 10311 let Inst{4-0} = Vt; 10312} 10313 10314// The immediate form of AdvSIMD post-indexed addressing is encoded with 10315// register post-index addressing from the zero register. 10316multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 10317 int Offset, int Size> { 10318 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 10319 // "ld1\t$Vt, [$Rn], #16" 10320 // may get mapped to 10321 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 10322 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10323 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10324 GPR64sp:$Rn, 10325 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10326 XZR), 1>; 10327 10328 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 10329 // "ld1.8b\t$Vt, [$Rn], #16" 10330 // may get mapped to 10331 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 10332 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10333 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10334 GPR64sp:$Rn, 10335 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10336 XZR), 0>; 10337 10338 // E.g. "ld1.8b { v0, v1 }, [x1]" 10339 // "ld1\t$Vt, [$Rn]" 10340 // may get mapped to 10341 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 10342 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10343 (!cast<Instruction>(BaseName # Count # "v" # layout) 10344 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10345 GPR64sp:$Rn), 0>; 10346 10347 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 10348 // "ld1\t$Vt, [$Rn], $Xm" 10349 // may get mapped to 10350 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 10351 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10352 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10353 GPR64sp:$Rn, 10354 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10355 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10356} 10357 10358multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 10359 int Offset128, int Offset64, bits<4> opcode> { 10360 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10361 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 10362 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 10363 (ins GPR64sp:$Rn), []>; 10364 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 10365 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 10366 (ins GPR64sp:$Rn), []>; 10367 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 10368 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 10369 (ins GPR64sp:$Rn), []>; 10370 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 10371 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 10372 (ins GPR64sp:$Rn), []>; 10373 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 10374 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 10375 (ins GPR64sp:$Rn), []>; 10376 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 10377 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 10378 (ins GPR64sp:$Rn), []>; 10379 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 10380 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 10381 (ins GPR64sp:$Rn), []>; 10382 10383 10384 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 10385 (outs GPR64sp:$wback, 10386 !cast<RegisterOperand>(veclist # "16b"):$Vt), 10387 (ins GPR64sp:$Rn, 10388 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10389 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 10390 (outs GPR64sp:$wback, 10391 !cast<RegisterOperand>(veclist # "8h"):$Vt), 10392 (ins GPR64sp:$Rn, 10393 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10394 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 10395 (outs GPR64sp:$wback, 10396 !cast<RegisterOperand>(veclist # "4s"):$Vt), 10397 (ins GPR64sp:$Rn, 10398 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10399 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 10400 (outs GPR64sp:$wback, 10401 !cast<RegisterOperand>(veclist # "2d"):$Vt), 10402 (ins GPR64sp:$Rn, 10403 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10404 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 10405 (outs GPR64sp:$wback, 10406 !cast<RegisterOperand>(veclist # "8b"):$Vt), 10407 (ins GPR64sp:$Rn, 10408 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10409 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 10410 (outs GPR64sp:$wback, 10411 !cast<RegisterOperand>(veclist # "4h"):$Vt), 10412 (ins GPR64sp:$Rn, 10413 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10414 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 10415 (outs GPR64sp:$wback, 10416 !cast<RegisterOperand>(veclist # "2s"):$Vt), 10417 (ins GPR64sp:$Rn, 10418 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10419 } 10420 10421 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10422 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10423 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10424 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10425 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10426 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10427 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10428} 10429 10430// Only ld1/st1 has a v1d version. 10431multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 10432 int Offset128, int Offset64, bits<4> opcode> { 10433 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 10434 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 10435 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10436 GPR64sp:$Rn), []>; 10437 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 10438 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10439 GPR64sp:$Rn), []>; 10440 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 10441 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10442 GPR64sp:$Rn), []>; 10443 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 10444 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10445 GPR64sp:$Rn), []>; 10446 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 10447 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10448 GPR64sp:$Rn), []>; 10449 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 10450 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10451 GPR64sp:$Rn), []>; 10452 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 10453 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10454 GPR64sp:$Rn), []>; 10455 10456 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 10457 (outs GPR64sp:$wback), 10458 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10459 GPR64sp:$Rn, 10460 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10461 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 10462 (outs GPR64sp:$wback), 10463 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10464 GPR64sp:$Rn, 10465 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10466 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 10467 (outs GPR64sp:$wback), 10468 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10469 GPR64sp:$Rn, 10470 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10471 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 10472 (outs GPR64sp:$wback), 10473 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10474 GPR64sp:$Rn, 10475 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10476 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 10477 (outs GPR64sp:$wback), 10478 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10479 GPR64sp:$Rn, 10480 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10481 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 10482 (outs GPR64sp:$wback), 10483 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10484 GPR64sp:$Rn, 10485 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10486 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 10487 (outs GPR64sp:$wback), 10488 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10489 GPR64sp:$Rn, 10490 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10491 } 10492 10493 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10494 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10495 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10496 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10497 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10498 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10499 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10500} 10501 10502multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 10503 int Offset128, int Offset64, bits<4> opcode> 10504 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10505 10506 // LD1 instructions have extra "1d" variants. 10507 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10508 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 10509 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10510 (ins GPR64sp:$Rn), []>; 10511 10512 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10513 (outs GPR64sp:$wback, 10514 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10515 (ins GPR64sp:$Rn, 10516 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10517 } 10518 10519 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10520} 10521 10522multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10523 int Offset128, int Offset64, bits<4> opcode> 10524 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10525 10526 // ST1 instructions have extra "1d" variants. 10527 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10528 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10529 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10530 GPR64sp:$Rn), []>; 10531 10532 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10533 (outs GPR64sp:$wback), 10534 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10535 GPR64sp:$Rn, 10536 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10537 } 10538 10539 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10540} 10541 10542multiclass SIMDLd1Multiple<string asm> { 10543 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10544 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10545 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10546 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10547} 10548 10549multiclass SIMDSt1Multiple<string asm> { 10550 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10551 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10552 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10553 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10554} 10555 10556multiclass SIMDLd2Multiple<string asm> { 10557 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10558} 10559 10560multiclass SIMDSt2Multiple<string asm> { 10561 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10562} 10563 10564multiclass SIMDLd3Multiple<string asm> { 10565 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10566} 10567 10568multiclass SIMDSt3Multiple<string asm> { 10569 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10570} 10571 10572multiclass SIMDLd4Multiple<string asm> { 10573 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10574} 10575 10576multiclass SIMDSt4Multiple<string asm> { 10577 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10578} 10579 10580//--- 10581// AdvSIMD Load/store single-element 10582//--- 10583 10584class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10585 string asm, string operands, string cst, 10586 dag oops, dag iops, list<dag> pattern> 10587 : I<oops, iops, asm, operands, cst, pattern> { 10588 bits<5> Vt; 10589 bits<5> Rn; 10590 let Inst{31} = 0; 10591 let Inst{29-24} = 0b001101; 10592 let Inst{22} = L; 10593 let Inst{21} = R; 10594 let Inst{15-13} = opcode; 10595 let Inst{9-5} = Rn; 10596 let Inst{4-0} = Vt; 10597} 10598 10599class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10600 string asm, string operands, string cst, 10601 dag oops, dag iops, list<dag> pattern> 10602 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10603 bits<5> Vt; 10604 bits<5> Rn; 10605 let Inst{31} = 0; 10606 let Inst{29-24} = 0b001101; 10607 let Inst{22} = L; 10608 let Inst{21} = R; 10609 let Inst{15-13} = opcode; 10610 let Inst{9-5} = Rn; 10611 let Inst{4-0} = Vt; 10612} 10613 10614 10615let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10616class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10617 DAGOperand listtype> 10618 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10619 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10620 []> { 10621 let Inst{30} = Q; 10622 let Inst{23} = 0; 10623 let Inst{20-16} = 0b00000; 10624 let Inst{12} = S; 10625 let Inst{11-10} = size; 10626} 10627let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10628class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10629 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10630 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10631 "$Rn = $wback", 10632 (outs GPR64sp:$wback, listtype:$Vt), 10633 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10634 bits<5> Xm; 10635 let Inst{30} = Q; 10636 let Inst{23} = 1; 10637 let Inst{20-16} = Xm; 10638 let Inst{12} = S; 10639 let Inst{11-10} = size; 10640} 10641 10642multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10643 int Offset, int Size> { 10644 // E.g. "ld1r { v0.8b }, [x1], #1" 10645 // "ld1r.8b\t$Vt, [$Rn], #1" 10646 // may get mapped to 10647 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10648 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10649 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10650 GPR64sp:$Rn, 10651 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10652 XZR), 1>; 10653 10654 // E.g. "ld1r.8b { v0 }, [x1], #1" 10655 // "ld1r.8b\t$Vt, [$Rn], #1" 10656 // may get mapped to 10657 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10658 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10659 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10660 GPR64sp:$Rn, 10661 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10662 XZR), 0>; 10663 10664 // E.g. "ld1r.8b { v0 }, [x1]" 10665 // "ld1r.8b\t$Vt, [$Rn]" 10666 // may get mapped to 10667 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10668 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10669 (!cast<Instruction>(BaseName # "v" # layout) 10670 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10671 GPR64sp:$Rn), 0>; 10672 10673 // E.g. "ld1r.8b { v0 }, [x1], x2" 10674 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10675 // may get mapped to 10676 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10677 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10678 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10679 GPR64sp:$Rn, 10680 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10681 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10682} 10683 10684multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10685 int Offset1, int Offset2, int Offset4, int Offset8> { 10686 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10687 !cast<DAGOperand>("VecList" # Count # "8b")>; 10688 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10689 !cast<DAGOperand>("VecList" # Count #"16b")>; 10690 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10691 !cast<DAGOperand>("VecList" # Count #"4h")>; 10692 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10693 !cast<DAGOperand>("VecList" # Count #"8h")>; 10694 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10695 !cast<DAGOperand>("VecList" # Count #"2s")>; 10696 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10697 !cast<DAGOperand>("VecList" # Count #"4s")>; 10698 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10699 !cast<DAGOperand>("VecList" # Count #"1d")>; 10700 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10701 !cast<DAGOperand>("VecList" # Count #"2d")>; 10702 10703 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10704 !cast<DAGOperand>("VecList" # Count # "8b"), 10705 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10706 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10707 !cast<DAGOperand>("VecList" # Count # "16b"), 10708 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10709 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10710 !cast<DAGOperand>("VecList" # Count # "4h"), 10711 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10712 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10713 !cast<DAGOperand>("VecList" # Count # "8h"), 10714 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10715 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10716 !cast<DAGOperand>("VecList" # Count # "2s"), 10717 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10718 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10719 !cast<DAGOperand>("VecList" # Count # "4s"), 10720 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10721 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10722 !cast<DAGOperand>("VecList" # Count # "1d"), 10723 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10724 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10725 !cast<DAGOperand>("VecList" # Count # "2d"), 10726 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10727 10728 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10729 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10730 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10731 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10732 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10733 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10734 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10735 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10736} 10737 10738class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10739 dag oops, dag iops, list<dag> pattern> 10740 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10741 pattern> { 10742 // idx encoded in Q:S:size fields. 10743 bits<4> idx; 10744 let Inst{30} = idx{3}; 10745 let Inst{23} = 0; 10746 let Inst{20-16} = 0b00000; 10747 let Inst{12} = idx{2}; 10748 let Inst{11-10} = idx{1-0}; 10749} 10750class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10751 dag oops, dag iops, list<dag> pattern> 10752 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10753 oops, iops, pattern> { 10754 // idx encoded in Q:S:size fields. 10755 bits<4> idx; 10756 let Inst{30} = idx{3}; 10757 let Inst{23} = 0; 10758 let Inst{20-16} = 0b00000; 10759 let Inst{12} = idx{2}; 10760 let Inst{11-10} = idx{1-0}; 10761} 10762class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10763 dag oops, dag iops> 10764 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10765 "$Rn = $wback", oops, iops, []> { 10766 // idx encoded in Q:S:size fields. 10767 bits<4> idx; 10768 bits<5> Xm; 10769 let Inst{30} = idx{3}; 10770 let Inst{23} = 1; 10771 let Inst{20-16} = Xm; 10772 let Inst{12} = idx{2}; 10773 let Inst{11-10} = idx{1-0}; 10774} 10775class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10776 dag oops, dag iops> 10777 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10778 "$Rn = $wback", oops, iops, []> { 10779 // idx encoded in Q:S:size fields. 10780 bits<4> idx; 10781 bits<5> Xm; 10782 let Inst{30} = idx{3}; 10783 let Inst{23} = 1; 10784 let Inst{20-16} = Xm; 10785 let Inst{12} = idx{2}; 10786 let Inst{11-10} = idx{1-0}; 10787} 10788 10789class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10790 dag oops, dag iops, list<dag> pattern> 10791 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10792 pattern> { 10793 // idx encoded in Q:S:size<1> fields. 10794 bits<3> idx; 10795 let Inst{30} = idx{2}; 10796 let Inst{23} = 0; 10797 let Inst{20-16} = 0b00000; 10798 let Inst{12} = idx{1}; 10799 let Inst{11} = idx{0}; 10800 let Inst{10} = size; 10801} 10802class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10803 dag oops, dag iops, list<dag> pattern> 10804 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10805 oops, iops, pattern> { 10806 // idx encoded in Q:S:size<1> fields. 10807 bits<3> idx; 10808 let Inst{30} = idx{2}; 10809 let Inst{23} = 0; 10810 let Inst{20-16} = 0b00000; 10811 let Inst{12} = idx{1}; 10812 let Inst{11} = idx{0}; 10813 let Inst{10} = size; 10814} 10815 10816class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10817 dag oops, dag iops> 10818 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10819 "$Rn = $wback", oops, iops, []> { 10820 // idx encoded in Q:S:size<1> fields. 10821 bits<3> idx; 10822 bits<5> Xm; 10823 let Inst{30} = idx{2}; 10824 let Inst{23} = 1; 10825 let Inst{20-16} = Xm; 10826 let Inst{12} = idx{1}; 10827 let Inst{11} = idx{0}; 10828 let Inst{10} = size; 10829} 10830class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10831 dag oops, dag iops> 10832 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10833 "$Rn = $wback", oops, iops, []> { 10834 // idx encoded in Q:S:size<1> fields. 10835 bits<3> idx; 10836 bits<5> Xm; 10837 let Inst{30} = idx{2}; 10838 let Inst{23} = 1; 10839 let Inst{20-16} = Xm; 10840 let Inst{12} = idx{1}; 10841 let Inst{11} = idx{0}; 10842 let Inst{10} = size; 10843} 10844class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10845 dag oops, dag iops, list<dag> pattern> 10846 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10847 pattern> { 10848 // idx encoded in Q:S fields. 10849 bits<2> idx; 10850 let Inst{30} = idx{1}; 10851 let Inst{23} = 0; 10852 let Inst{20-16} = 0b00000; 10853 let Inst{12} = idx{0}; 10854 let Inst{11-10} = size; 10855} 10856class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10857 dag oops, dag iops, list<dag> pattern> 10858 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10859 oops, iops, pattern> { 10860 // idx encoded in Q:S fields. 10861 bits<2> idx; 10862 let Inst{30} = idx{1}; 10863 let Inst{23} = 0; 10864 let Inst{20-16} = 0b00000; 10865 let Inst{12} = idx{0}; 10866 let Inst{11-10} = size; 10867} 10868class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10869 string asm, dag oops, dag iops> 10870 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10871 "$Rn = $wback", oops, iops, []> { 10872 // idx encoded in Q:S fields. 10873 bits<2> idx; 10874 bits<5> Xm; 10875 let Inst{30} = idx{1}; 10876 let Inst{23} = 1; 10877 let Inst{20-16} = Xm; 10878 let Inst{12} = idx{0}; 10879 let Inst{11-10} = size; 10880} 10881class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10882 string asm, dag oops, dag iops> 10883 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10884 "$Rn = $wback", oops, iops, []> { 10885 // idx encoded in Q:S fields. 10886 bits<2> idx; 10887 bits<5> Xm; 10888 let Inst{30} = idx{1}; 10889 let Inst{23} = 1; 10890 let Inst{20-16} = Xm; 10891 let Inst{12} = idx{0}; 10892 let Inst{11-10} = size; 10893} 10894class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10895 dag oops, dag iops, list<dag> pattern> 10896 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10897 pattern> { 10898 // idx encoded in Q field. 10899 bits<1> idx; 10900 let Inst{30} = idx; 10901 let Inst{23} = 0; 10902 let Inst{20-16} = 0b00000; 10903 let Inst{12} = 0; 10904 let Inst{11-10} = size; 10905} 10906class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10907 dag oops, dag iops, list<dag> pattern> 10908 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10909 oops, iops, pattern> { 10910 // idx encoded in Q field. 10911 bits<1> idx; 10912 let Inst{30} = idx; 10913 let Inst{23} = 0; 10914 let Inst{20-16} = 0b00000; 10915 let Inst{12} = 0; 10916 let Inst{11-10} = size; 10917} 10918class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10919 string asm, dag oops, dag iops> 10920 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10921 "$Rn = $wback", oops, iops, []> { 10922 // idx encoded in Q field. 10923 bits<1> idx; 10924 bits<5> Xm; 10925 let Inst{30} = idx; 10926 let Inst{23} = 1; 10927 let Inst{20-16} = Xm; 10928 let Inst{12} = 0; 10929 let Inst{11-10} = size; 10930} 10931class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10932 string asm, dag oops, dag iops> 10933 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10934 "$Rn = $wback", oops, iops, []> { 10935 // idx encoded in Q field. 10936 bits<1> idx; 10937 bits<5> Xm; 10938 let Inst{30} = idx; 10939 let Inst{23} = 1; 10940 let Inst{20-16} = Xm; 10941 let Inst{12} = 0; 10942 let Inst{11-10} = size; 10943} 10944 10945let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10946multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 10947 RegisterOperand listtype, 10948 RegisterOperand GPR64pi> { 10949 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 10950 (outs listtype:$dst), 10951 (ins listtype:$Vt, VectorIndexB:$idx, 10952 GPR64sp:$Rn), []>; 10953 10954 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 10955 (outs GPR64sp:$wback, listtype:$dst), 10956 (ins listtype:$Vt, VectorIndexB:$idx, 10957 GPR64sp:$Rn, GPR64pi:$Xm)>; 10958} 10959let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10960multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 10961 RegisterOperand listtype, 10962 RegisterOperand GPR64pi> { 10963 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 10964 (outs listtype:$dst), 10965 (ins listtype:$Vt, VectorIndexH:$idx, 10966 GPR64sp:$Rn), []>; 10967 10968 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 10969 (outs GPR64sp:$wback, listtype:$dst), 10970 (ins listtype:$Vt, VectorIndexH:$idx, 10971 GPR64sp:$Rn, GPR64pi:$Xm)>; 10972} 10973let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10974multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 10975 RegisterOperand listtype, 10976 RegisterOperand GPR64pi> { 10977 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 10978 (outs listtype:$dst), 10979 (ins listtype:$Vt, VectorIndexS:$idx, 10980 GPR64sp:$Rn), []>; 10981 10982 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 10983 (outs GPR64sp:$wback, listtype:$dst), 10984 (ins listtype:$Vt, VectorIndexS:$idx, 10985 GPR64sp:$Rn, GPR64pi:$Xm)>; 10986} 10987let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10988multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 10989 RegisterOperand listtype, RegisterOperand GPR64pi> { 10990 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 10991 (outs listtype:$dst), 10992 (ins listtype:$Vt, VectorIndexD:$idx, 10993 GPR64sp:$Rn), []>; 10994 10995 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 10996 (outs GPR64sp:$wback, listtype:$dst), 10997 (ins listtype:$Vt, VectorIndexD:$idx, 10998 GPR64sp:$Rn, GPR64pi:$Xm)>; 10999} 11000let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11001multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 11002 RegisterOperand listtype, RegisterOperand GPR64pi> { 11003 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 11004 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 11005 GPR64sp:$Rn), []>; 11006 11007 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 11008 (outs GPR64sp:$wback), 11009 (ins listtype:$Vt, VectorIndexB:$idx, 11010 GPR64sp:$Rn, GPR64pi:$Xm)>; 11011} 11012let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11013multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 11014 RegisterOperand listtype, RegisterOperand GPR64pi> { 11015 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 11016 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 11017 GPR64sp:$Rn), []>; 11018 11019 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 11020 (outs GPR64sp:$wback), 11021 (ins listtype:$Vt, VectorIndexH:$idx, 11022 GPR64sp:$Rn, GPR64pi:$Xm)>; 11023} 11024let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11025multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 11026 RegisterOperand listtype, RegisterOperand GPR64pi> { 11027 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 11028 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 11029 GPR64sp:$Rn), []>; 11030 11031 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 11032 (outs GPR64sp:$wback), 11033 (ins listtype:$Vt, VectorIndexS:$idx, 11034 GPR64sp:$Rn, GPR64pi:$Xm)>; 11035} 11036let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11037multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 11038 RegisterOperand listtype, RegisterOperand GPR64pi> { 11039 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 11040 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 11041 GPR64sp:$Rn), []>; 11042 11043 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 11044 (outs GPR64sp:$wback), 11045 (ins listtype:$Vt, VectorIndexD:$idx, 11046 GPR64sp:$Rn, GPR64pi:$Xm)>; 11047} 11048 11049multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 11050 string Count, int Offset, Operand idxtype> { 11051 // E.g. "ld1 { v0.8b }[0], [x1], #1" 11052 // "ld1\t$Vt, [$Rn], #1" 11053 // may get mapped to 11054 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 11055 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 11056 (!cast<Instruction>(NAME # Type # "_POST") 11057 GPR64sp:$Rn, 11058 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 11059 idxtype:$idx, XZR), 1>; 11060 11061 // E.g. "ld1.8b { v0 }[0], [x1], #1" 11062 // "ld1.8b\t$Vt, [$Rn], #1" 11063 // may get mapped to 11064 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 11065 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 11066 (!cast<Instruction>(NAME # Type # "_POST") 11067 GPR64sp:$Rn, 11068 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11069 idxtype:$idx, XZR), 0>; 11070 11071 // E.g. "ld1.8b { v0 }[0], [x1]" 11072 // "ld1.8b\t$Vt, [$Rn]" 11073 // may get mapped to 11074 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 11075 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 11076 (!cast<Instruction>(NAME # Type) 11077 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11078 idxtype:$idx, GPR64sp:$Rn), 0>; 11079 11080 // E.g. "ld1.8b { v0 }[0], [x1], x2" 11081 // "ld1.8b\t$Vt, [$Rn], $Xm" 11082 // may get mapped to 11083 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 11084 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 11085 (!cast<Instruction>(NAME # Type # "_POST") 11086 GPR64sp:$Rn, 11087 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11088 idxtype:$idx, 11089 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 11090} 11091 11092multiclass SIMDLdSt1SingleAliases<string asm> { 11093 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 11094 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 11095 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 11096 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 11097} 11098 11099multiclass SIMDLdSt2SingleAliases<string asm> { 11100 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 11101 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 11102 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 11103 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 11104} 11105 11106multiclass SIMDLdSt3SingleAliases<string asm> { 11107 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 11108 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 11109 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 11110 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 11111} 11112 11113multiclass SIMDLdSt4SingleAliases<string asm> { 11114 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 11115 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 11116 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 11117 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 11118} 11119} // end of 'let Predicates = [HasNEON]' 11120 11121//---------------------------------------------------------------------------- 11122// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 11123//---------------------------------------------------------------------------- 11124 11125let Predicates = [HasNEON, HasRDM] in { 11126 11127class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 11128 RegisterOperand regtype, string asm, 11129 string kind, list<dag> pattern> 11130 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 11131 pattern> { 11132} 11133multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 11134 SDPatternOperator op> { 11135 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 11136 [(set (v4i16 V64:$dst), 11137 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 11138 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 11139 [(set (v8i16 V128:$dst), 11140 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 11141 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 11142 [(set (v2i32 V64:$dst), 11143 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 11144 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 11145 [(set (v4i32 V128:$dst), 11146 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 11147} 11148 11149multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 11150 SDPatternOperator op> { 11151 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 11152 V64, V64, V128_lo, VectorIndexH, 11153 asm, ".4h", ".4h", ".4h", ".h", 11154 [(set (v4i16 V64:$dst), 11155 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 11156 (dup_v8i16 (v8i16 V128_lo:$Rm), 11157 VectorIndexH:$idx))))]> { 11158 bits<3> idx; 11159 let Inst{11} = idx{2}; 11160 let Inst{21} = idx{1}; 11161 let Inst{20} = idx{0}; 11162 } 11163 11164 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 11165 V128, V128, V128_lo, VectorIndexH, 11166 asm, ".8h", ".8h", ".8h", ".h", 11167 [(set (v8i16 V128:$dst), 11168 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 11169 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 11170 VectorIndexH:$idx)))))]> { 11171 bits<3> idx; 11172 let Inst{11} = idx{2}; 11173 let Inst{21} = idx{1}; 11174 let Inst{20} = idx{0}; 11175 } 11176 11177 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 11178 V64, V64, V128, VectorIndexS, 11179 asm, ".2s", ".2s", ".2s", ".s", 11180 [(set (v2i32 V64:$dst), 11181 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 11182 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 11183 bits<2> idx; 11184 let Inst{11} = idx{1}; 11185 let Inst{21} = idx{0}; 11186 } 11187 11188 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 11189 V128, V128, V128, VectorIndexS, 11190 asm, ".4s", ".4s", ".4s", ".s", 11191 [(set (v4i32 V128:$dst), 11192 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11193 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 11194 VectorIndexS:$idx)))))]> { 11195 bits<2> idx; 11196 let Inst{11} = idx{1}; 11197 let Inst{21} = idx{0}; 11198 } 11199 11200 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 11201 FPR16Op, FPR16Op, V128_lo, 11202 VectorIndexH, asm, ".h", "", "", ".h", 11203 []> { 11204 bits<3> idx; 11205 let Inst{11} = idx{2}; 11206 let Inst{21} = idx{1}; 11207 let Inst{20} = idx{0}; 11208 } 11209 11210 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 11211 FPR32Op, FPR32Op, V128, VectorIndexS, 11212 asm, ".s", "", "", ".s", 11213 [(set (i32 FPR32Op:$dst), 11214 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 11215 (i32 (vector_extract (v4i32 V128:$Rm), 11216 VectorIndexS:$idx)))))]> { 11217 bits<2> idx; 11218 let Inst{11} = idx{1}; 11219 let Inst{21} = idx{0}; 11220 } 11221} 11222} // let Predicates = [HasNeon, HasRDM] 11223 11224//---------------------------------------------------------------------------- 11225// ARMv8.3 Complex ADD/MLA instructions 11226//---------------------------------------------------------------------------- 11227 11228class ComplexRotationOperand<int Angle, int Remainder, string Type> 11229 : AsmOperandClass { 11230 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 11231 let DiagnosticType = "InvalidComplexRotation" # Type; 11232 let Name = "ComplexRotation" # Type; 11233} 11234def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11235 SDNodeXForm<imm, [{ 11236 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 11237}]>> { 11238 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 11239 let PrintMethod = "printComplexRotationOp<90, 0>"; 11240} 11241def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11242 SDNodeXForm<imm, [{ 11243 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 11244}]>> { 11245 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 11246 let PrintMethod = "printComplexRotationOp<180, 90>"; 11247} 11248let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11249class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 11250 RegisterOperand regtype, Operand rottype, 11251 string asm, string kind, list<dag> pattern> 11252 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11253 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11254 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 11255 Sched<[!if(Q, WriteVq, WriteVd)]> { 11256 bits<5> Rd; 11257 bits<5> Rn; 11258 bits<5> Rm; 11259 bits<1> rot; 11260 let Inst{31} = 0; 11261 let Inst{30} = Q; 11262 let Inst{29} = U; 11263 let Inst{28-24} = 0b01110; 11264 let Inst{23-22} = size; 11265 let Inst{21} = 0; 11266 let Inst{20-16} = Rm; 11267 let Inst{15-13} = opcode; 11268 // Non-tied version (FCADD) only has one rotation bit 11269 let Inst{12} = rot; 11270 let Inst{11} = 0; 11271 let Inst{10} = 1; 11272 let Inst{9-5} = Rn; 11273 let Inst{4-0} = Rd; 11274} 11275 11276//8.3 CompNum - Floating-point complex number support 11277multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 11278 string asm, SDPatternOperator OpNode>{ 11279 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11280 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 11281 asm, ".4h", 11282 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11283 (v4f16 V64:$Rn), 11284 (v4f16 V64:$Rm), 11285 (i32 rottype:$rot)))]>; 11286 11287 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 11288 asm, ".8h", 11289 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11290 (v8f16 V128:$Rn), 11291 (v8f16 V128:$Rm), 11292 (i32 rottype:$rot)))]>; 11293 } 11294 11295 let Predicates = [HasComplxNum, HasNEON] in { 11296 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 11297 asm, ".2s", 11298 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11299 (v2f32 V64:$Rn), 11300 (v2f32 V64:$Rm), 11301 (i32 rottype:$rot)))]>; 11302 11303 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 11304 asm, ".4s", 11305 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11306 (v4f32 V128:$Rn), 11307 (v4f32 V128:$Rm), 11308 (i32 rottype:$rot)))]>; 11309 11310 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 11311 asm, ".2d", 11312 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11313 (v2f64 V128:$Rn), 11314 (v2f64 V128:$Rm), 11315 (i32 rottype:$rot)))]>; 11316 } 11317} 11318 11319let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11320class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 11321 bits<3> opcode, 11322 RegisterOperand regtype, 11323 Operand rottype, string asm, 11324 string kind, list<dag> pattern> 11325 : I<(outs regtype:$dst), 11326 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11327 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11328 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 11329 Sched<[!if(Q, WriteVq, WriteVd)]> { 11330 bits<5> Rd; 11331 bits<5> Rn; 11332 bits<5> Rm; 11333 bits<2> rot; 11334 let Inst{31} = 0; 11335 let Inst{30} = Q; 11336 let Inst{29} = U; 11337 let Inst{28-24} = 0b01110; 11338 let Inst{23-22} = size; 11339 let Inst{21} = 0; 11340 let Inst{20-16} = Rm; 11341 let Inst{15-13} = opcode; 11342 let Inst{12-11} = rot; 11343 let Inst{10} = 1; 11344 let Inst{9-5} = Rn; 11345 let Inst{4-0} = Rd; 11346} 11347 11348multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 11349 Operand rottype, string asm, 11350 SDPatternOperator OpNode> { 11351 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11352 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 11353 rottype, asm, ".4h", 11354 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11355 (v4f16 V64:$Rn), 11356 (v4f16 V64:$Rm), 11357 (i32 rottype:$rot)))]>; 11358 11359 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 11360 rottype, asm, ".8h", 11361 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11362 (v8f16 V128:$Rn), 11363 (v8f16 V128:$Rm), 11364 (i32 rottype:$rot)))]>; 11365 } 11366 11367 let Predicates = [HasComplxNum, HasNEON] in { 11368 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 11369 rottype, asm, ".2s", 11370 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11371 (v2f32 V64:$Rn), 11372 (v2f32 V64:$Rm), 11373 (i32 rottype:$rot)))]>; 11374 11375 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 11376 rottype, asm, ".4s", 11377 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11378 (v4f32 V128:$Rn), 11379 (v4f32 V128:$Rm), 11380 (i32 rottype:$rot)))]>; 11381 11382 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 11383 rottype, asm, ".2d", 11384 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11385 (v2f64 V128:$Rn), 11386 (v2f64 V128:$Rm), 11387 (i32 rottype:$rot)))]>; 11388 } 11389} 11390 11391let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11392class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 11393 bit opc1, bit opc2, RegisterOperand dst_reg, 11394 RegisterOperand lhs_reg, 11395 RegisterOperand rhs_reg, Operand vec_idx, 11396 Operand rottype, string asm, string apple_kind, 11397 string dst_kind, string lhs_kind, 11398 string rhs_kind, list<dag> pattern> 11399 : I<(outs dst_reg:$dst), 11400 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 11401 asm, 11402 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 11403 "$idx, $rot" # "|" # apple_kind # 11404 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 11405 Sched<[!if(Q, WriteVq, WriteVd)]> { 11406 bits<5> Rd; 11407 bits<5> Rn; 11408 bits<5> Rm; 11409 bits<2> rot; 11410 11411 let Inst{31} = 0; 11412 let Inst{30} = Q; 11413 let Inst{29} = U; 11414 let Inst{28} = Scalar; 11415 let Inst{27-24} = 0b1111; 11416 let Inst{23-22} = size; 11417 // Bit 21 must be set by the derived class. 11418 let Inst{20-16} = Rm; 11419 let Inst{15} = opc1; 11420 let Inst{14-13} = rot; 11421 let Inst{12} = opc2; 11422 // Bit 11 must be set by the derived class. 11423 let Inst{10} = 0; 11424 let Inst{9-5} = Rn; 11425 let Inst{4-0} = Rd; 11426} 11427 11428// The complex instructions index by pairs of elements, so the VectorIndexes 11429// don't match the lane types, and the index bits are different to the other 11430// classes. 11431multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 11432 string asm> { 11433 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11434 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 11435 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 11436 ".4h", ".h", []> { 11437 bits<1> idx; 11438 let Inst{11} = 0; 11439 let Inst{21} = idx{0}; 11440 } 11441 11442 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 11443 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 11444 ".8h", ".8h", ".h", []> { 11445 bits<2> idx; 11446 let Inst{11} = idx{1}; 11447 let Inst{21} = idx{0}; 11448 } 11449 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 11450 11451 let Predicates = [HasComplxNum, HasNEON] in { 11452 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 11453 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 11454 ".4s", ".4s", ".s", []> { 11455 bits<1> idx; 11456 let Inst{11} = idx{0}; 11457 let Inst{21} = 0; 11458 } 11459 } // Predicates = [HasComplxNum, HasNEON] 11460} 11461 11462//---------------------------------------------------------------------------- 11463// Crypto extensions 11464//---------------------------------------------------------------------------- 11465 11466let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11467class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 11468 list<dag> pat> 11469 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 11470 Sched<[WriteVq]>{ 11471 bits<5> Rd; 11472 bits<5> Rn; 11473 let Inst{31-16} = 0b0100111000101000; 11474 let Inst{15-12} = opc; 11475 let Inst{11-10} = 0b10; 11476 let Inst{9-5} = Rn; 11477 let Inst{4-0} = Rd; 11478} 11479 11480class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 11481 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 11482 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 11483 11484class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 11485 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 11486 "$Rd = $dst", 11487 [(set (v16i8 V128:$dst), 11488 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 11489 11490let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11491class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 11492 dag oops, dag iops, list<dag> pat> 11493 : I<oops, iops, asm, 11494 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 11495 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 11496 Sched<[WriteVq]>{ 11497 bits<5> Rd; 11498 bits<5> Rn; 11499 bits<5> Rm; 11500 let Inst{31-21} = 0b01011110000; 11501 let Inst{20-16} = Rm; 11502 let Inst{15} = 0; 11503 let Inst{14-12} = opc; 11504 let Inst{11-10} = 0b00; 11505 let Inst{9-5} = Rn; 11506 let Inst{4-0} = Rd; 11507} 11508 11509class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11510 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11511 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11512 [(set (v4i32 FPR128:$dst), 11513 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11514 (v4i32 V128:$Rm)))]>; 11515 11516class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11517 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11518 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11519 [(set (v4i32 V128:$dst), 11520 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11521 (v4i32 V128:$Rm)))]>; 11522 11523class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11524 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11525 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11526 [(set (v4i32 FPR128:$dst), 11527 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11528 (v4i32 V128:$Rm)))]>; 11529 11530let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11531class SHA2OpInst<bits<4> opc, string asm, string kind, 11532 string cstr, dag oops, dag iops, 11533 list<dag> pat> 11534 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11535 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11536 Sched<[WriteVq]>{ 11537 bits<5> Rd; 11538 bits<5> Rn; 11539 let Inst{31-16} = 0b0101111000101000; 11540 let Inst{15-12} = opc; 11541 let Inst{11-10} = 0b10; 11542 let Inst{9-5} = Rn; 11543 let Inst{4-0} = Rd; 11544} 11545 11546class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11547 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11548 (ins V128:$Rd, V128:$Rn), 11549 [(set (v4i32 V128:$dst), 11550 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11551 11552class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11553 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11554 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11555 11556// Armv8.2-A Crypto extensions 11557class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11558 list<dag> pattern> 11559 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11560 bits<5> Vd; 11561 bits<5> Vn; 11562 let Inst{31-25} = 0b1100111; 11563 let Inst{9-5} = Vn; 11564 let Inst{4-0} = Vd; 11565} 11566 11567class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11568 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11569 "$Vd = $Vdst", []> { 11570 let Inst{31-25} = 0b1100111; 11571 let Inst{24-21} = 0b0110; 11572 let Inst{20-15} = 0b000001; 11573 let Inst{14} = op0; 11574 let Inst{13-12} = 0b00; 11575 let Inst{11-10} = op1; 11576} 11577class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11578 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11579class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11580 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11581 11582class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11583 string asmops, string cst> 11584 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11585 bits<5> Vm; 11586 let Inst{24-21} = 0b0011; 11587 let Inst{20-16} = Vm; 11588 let Inst{15} = 0b1; 11589 let Inst{14} = op0; 11590 let Inst{13-12} = 0b00; 11591 let Inst{11-10} = op1; 11592} 11593class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11594 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11595 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11596class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11597 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11598 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11599class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11600 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11601 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11602class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11603 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11604 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11605class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11606 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11607 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11608 11609class CryptoRRRR<bits<2>op0, string asm, string asmops> 11610 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11611 asmops, "", []> { 11612 bits<5> Vm; 11613 bits<5> Va; 11614 let Inst{24-23} = 0b00; 11615 let Inst{22-21} = op0; 11616 let Inst{20-16} = Vm; 11617 let Inst{15} = 0b0; 11618 let Inst{14-10} = Va; 11619} 11620class CryptoRRRR_16B<bits<2>op0, string asm> 11621 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11622 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11623} 11624class CryptoRRRR_4S<bits<2>op0, string asm> 11625 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11626 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11627} 11628 11629class CryptoRRRi6<string asm> 11630 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11631 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11632 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11633 bits<6> imm; 11634 bits<5> Vm; 11635 let Inst{24-21} = 0b0100; 11636 let Inst{20-16} = Vm; 11637 let Inst{15-10} = imm; 11638 let Inst{9-5} = Vn; 11639 let Inst{4-0} = Vd; 11640} 11641 11642class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11643 : BaseCryptoV82<(outs V128:$Vdst), 11644 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11645 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11646 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11647 bits<2> imm; 11648 bits<5> Vm; 11649 let Inst{24-21} = 0b0010; 11650 let Inst{20-16} = Vm; 11651 let Inst{15} = 0b1; 11652 let Inst{14} = op0; 11653 let Inst{13-12} = imm; 11654 let Inst{11-10} = op1; 11655} 11656 11657//---------------------------------------------------------------------------- 11658// v8.1 atomic instructions extension: 11659// * CAS 11660// * CASP 11661// * SWP 11662// * LDOPregister<OP>, and aliases STOPregister<OP> 11663 11664// Instruction encodings: 11665// 11666// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11667// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11668// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11669// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11670// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11671// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11672 11673// Instruction syntax: 11674// 11675// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11676// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11677// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11678// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11679// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11680// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11681// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11682// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11683// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11684// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11685 11686let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11687class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11688 string cstr, list<dag> pattern> 11689 : I<oops, iops, asm, operands, cstr, pattern> { 11690 bits<2> Sz; 11691 bit NP; 11692 bit Acq; 11693 bit Rel; 11694 bits<5> Rs; 11695 bits<5> Rn; 11696 bits<5> Rt; 11697 let Inst{31-30} = Sz; 11698 let Inst{29-24} = 0b001000; 11699 let Inst{23} = NP; 11700 let Inst{22} = Acq; 11701 let Inst{21} = 0b1; 11702 let Inst{20-16} = Rs; 11703 let Inst{15} = Rel; 11704 let Inst{14-10} = 0b11111; 11705 let Inst{9-5} = Rn; 11706 let Inst{4-0} = Rt; 11707 let Predicates = [HasLSE]; 11708} 11709 11710class BaseCAS<string order, string size, RegisterClass RC> 11711 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11712 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11713 "$out = $Rs",[]>, 11714 Sched<[WriteAtomic]> { 11715 let NP = 1; 11716} 11717 11718multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11719 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11720 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11721 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11722 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11723} 11724 11725class BaseCASP<string order, string size, RegisterOperand RC> 11726 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11727 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11728 "$out = $Rs",[]>, 11729 Sched<[WriteAtomic]> { 11730 let NP = 0; 11731} 11732 11733multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11734 let Sz = 0b00, Acq = Acq, Rel = Rel in 11735 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11736 let Sz = 0b01, Acq = Acq, Rel = Rel in 11737 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11738} 11739 11740let Predicates = [HasLSE] in 11741class BaseSWP<string order, string size, RegisterClass RC> 11742 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11743 "\t$Rs, $Rt, [$Rn]","",[]>, 11744 Sched<[WriteAtomic]> { 11745 bits<2> Sz; 11746 bit Acq; 11747 bit Rel; 11748 bits<5> Rs; 11749 bits<3> opc = 0b000; 11750 bits<5> Rn; 11751 bits<5> Rt; 11752 let Inst{31-30} = Sz; 11753 let Inst{29-24} = 0b111000; 11754 let Inst{23} = Acq; 11755 let Inst{22} = Rel; 11756 let Inst{21} = 0b1; 11757 let Inst{20-16} = Rs; 11758 let Inst{15} = 0b1; 11759 let Inst{14-12} = opc; 11760 let Inst{11-10} = 0b00; 11761 let Inst{9-5} = Rn; 11762 let Inst{4-0} = Rt; 11763 let Predicates = [HasLSE]; 11764} 11765 11766multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11767 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11768 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11769 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11770 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11771} 11772 11773let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11774class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11775 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11776 "\t$Rs, $Rt, [$Rn]","",[]>, 11777 Sched<[WriteAtomic]> { 11778 bits<2> Sz; 11779 bit Acq; 11780 bit Rel; 11781 bits<5> Rs; 11782 bits<3> opc; 11783 bits<5> Rn; 11784 bits<5> Rt; 11785 let Inst{31-30} = Sz; 11786 let Inst{29-24} = 0b111000; 11787 let Inst{23} = Acq; 11788 let Inst{22} = Rel; 11789 let Inst{21} = 0b1; 11790 let Inst{20-16} = Rs; 11791 let Inst{15} = 0b0; 11792 let Inst{14-12} = opc; 11793 let Inst{11-10} = 0b00; 11794 let Inst{9-5} = Rn; 11795 let Inst{4-0} = Rt; 11796 let Predicates = [HasLSE]; 11797} 11798 11799multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11800 string order> { 11801 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11802 def B : BaseLDOPregister<op, order, "b", GPR32>; 11803 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11804 def H : BaseLDOPregister<op, order, "h", GPR32>; 11805 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11806 def W : BaseLDOPregister<op, order, "", GPR32>; 11807 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11808 def X : BaseLDOPregister<op, order, "", GPR64>; 11809} 11810 11811// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11812// complex DAG for DstRHS. 11813let Predicates = [HasLSE] in 11814multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11815 string size, dag SrcRHS, dag DstRHS> { 11816 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11817 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11818 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11819 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11820 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11821 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11822 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11823 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11824 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11825 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11826} 11827 11828multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11829 string size, dag RHS> { 11830 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11831} 11832 11833multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11834 string size, dag LHS, dag RHS> { 11835 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11836} 11837 11838multiclass LDOPregister_patterns<string inst, string op> { 11839 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11840 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11841 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11842 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11843} 11844 11845multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11846 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11847 (i64 GPR64:$Rm), 11848 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11849 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11850 (i32 GPR32:$Rm), 11851 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11852 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11853 (i32 GPR32:$Rm), 11854 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11855 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11856 (i32 GPR32:$Rm), 11857 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11858} 11859 11860let Predicates = [HasLSE] in 11861multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11862 string size, dag OLD, dag NEW> { 11863 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11864 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11865 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11866 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11867 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11868 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11869 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11870 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11871 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11872 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11873} 11874 11875multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11876 string size, dag OLD, dag NEW> { 11877 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11878} 11879 11880multiclass CASregister_patterns<string inst, string op> { 11881 defm : CASregister_patterns_ord<inst, "X", op, "64", 11882 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11883 defm : CASregister_patterns_ord<inst, "W", op, "32", 11884 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11885 defm : CASregister_patterns_ord<inst, "H", op, "16", 11886 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11887 defm : CASregister_patterns_ord<inst, "B", op, "8", 11888 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11889} 11890 11891let Predicates = [HasLSE] in 11892class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11893 Instruction inst> : 11894 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11895 11896multiclass STOPregister<string asm, string instr> { 11897 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11898 !cast<Instruction>(instr # "LB")>; 11899 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11900 !cast<Instruction>(instr # "LH")>; 11901 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11902 !cast<Instruction>(instr # "LW")>; 11903 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11904 !cast<Instruction>(instr # "LX")>; 11905 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11906 !cast<Instruction>(instr # "B")>; 11907 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11908 !cast<Instruction>(instr # "H")>; 11909 def : BaseSTOPregister<asm, GPR32, WZR, 11910 !cast<Instruction>(instr # "W")>; 11911 def : BaseSTOPregister<asm, GPR64, XZR, 11912 !cast<Instruction>(instr # "X")>; 11913} 11914 11915class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11916 dag iops, dag oops, list<dag> pat> 11917 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11918 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11919 bits<5> Rt; 11920 bits<5> Rn; 11921 let Inst{31-21} = 0b11111000001; 11922 let Inst{15} = 1; 11923 let Inst{14-12} = opc; 11924 let Inst{11-10} = 0b00; 11925 let Inst{9-5} = Rn; 11926 let Inst{4-0} = Rt; 11927 11928 let Predicates = [HasV8_7a]; 11929} 11930 11931class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 11932 list<dag> pat = []> 11933 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 11934 let Inst{20-16} = 0b11111; 11935} 11936 11937class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 11938 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 11939 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 11940 bits<5> Rs; 11941 let Inst{20-16} = Rs; 11942} 11943 11944class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 11945 bits<2> op2, string asm> 11946 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 11947 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 11948 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 11949 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 11950 Sched<[]> { 11951 bits<5> Rd; 11952 bits<5> Rs; 11953 bits<5> Rn; 11954 let Inst{31-27} = 0b00011; 11955 let Inst{26} = isMove; 11956 let Inst{25-24} = 0b01; 11957 let Inst{23-22} = opcode; 11958 let Inst{21} = 0b0; 11959 let Inst{20-16} = Rs; 11960 let Inst{15-14} = op2; 11961 let Inst{13-12} = op1; 11962 let Inst{11-10} = 0b01; 11963 let Inst{9-5} = Rn; 11964 let Inst{4-0} = Rd; 11965 11966 let DecoderMethod = "DecodeCPYMemOpInstruction"; 11967 let mayLoad = 1; 11968 let mayStore = 1; 11969} 11970 11971class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11972 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 11973 11974class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 11975 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 11976 11977class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 11978 string asm> 11979 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 11980 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 11981 asm, "\t[$Rd]!, $Rn!, $Rm", 11982 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 11983 Sched<[]> { 11984 bits<5> Rd; 11985 bits<5> Rn; 11986 bits<5> Rm; 11987 let Inst{31-27} = 0b00011; 11988 let Inst{26} = isTagging; 11989 let Inst{25-21} = 0b01110; 11990 let Inst{20-16} = Rm; 11991 let Inst{15-14} = opcode; 11992 let Inst{13} = op2; 11993 let Inst{12} = op1; 11994 let Inst{11-10} = 0b01; 11995 let Inst{9-5} = Rn; 11996 let Inst{4-0} = Rd; 11997 11998 let DecoderMethod = "DecodeSETMemOpInstruction"; 11999 let mayLoad = 0; 12000 let mayStore = 1; 12001} 12002 12003class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 12004 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 12005 12006class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 12007 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 12008 12009multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 12010 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 12011 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 12012 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 12013 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 12014 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 12015 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 12016 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 12017 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 12018 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 12019 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 12020 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 12021 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 12022 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 12023 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 12024 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 12025 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 12026} 12027 12028multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 12029 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 12030 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 12031 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 12032 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 12033 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 12034 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 12035 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 12036 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 12037 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 12038 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 12039 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 12040 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 12041 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 12042 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 12043 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 12044 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 12045} 12046 12047multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 12048 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 12049 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 12050 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 12051 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 12052} 12053 12054multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 12055 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 12056 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 12057 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 12058 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 12059} 12060 12061//---------------------------------------------------------------------------- 12062// 2022 Armv8.9/Armv9.4 Extensions 12063//---------------------------------------------------------------------------- 12064 12065//--- 12066// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC) 12067//--- 12068 12069class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc, 12070 RegisterClass regtype, ImmLeaf immtype, string asm, 12071 SDPatternOperator OpNode> 12072 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm), 12073 asm, "\t$Rd, $Rn, $imm", "", 12074 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> { 12075 bits<5> Rd; 12076 bits<5> Rn; 12077 bits<8> imm; 12078 12079 let Inst{31} = sf; 12080 let Inst{30} = Op; 12081 let Inst{29} = S; 12082 let Inst{28-22} = 0b1000111; 12083 let Inst{21-18} = opc; 12084 let Inst{17-10} = imm; 12085 let Inst{9-5} = Rn; 12086 let Inst{4-0} = Rd; 12087} 12088 12089class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin, 12090 RegisterClass regtype, string asm, 12091 SDPatternOperator OpNode> 12092 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>, 12093 Sched<[WriteI]> { 12094 let Inst{11} = isMin; 12095 let Inst{10} = isUnsigned; 12096 let mayLoad = 0; 12097 let mayStore = 0; 12098 let hasSideEffects = 0; 12099} 12100 12101class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin, 12102 RegisterClass regtype, ImmLeaf immtype, string asm, 12103 SDPatternOperator OpNode> 12104 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm, 12105 OpNode>, 12106 Sched<[]> { 12107 let Inst{19} = isMin; 12108 let Inst{18} = isUnsigned; 12109 let mayLoad = 0; 12110 let mayStore = 0; 12111 let hasSideEffects = 0; 12112} 12113 12114multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm, 12115 SDPatternOperator OpNode = null_frag> { 12116 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>; 12117 12118 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32, 12119 !cond(isUnsigned : uimm8_32b, 12120 !not(isUnsigned) : simm8_32b), asm, OpNode>; 12121 12122 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>; 12123 12124 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64, 12125 !cond(isUnsigned : uimm8_64b, 12126 !not(isUnsigned) : simm8_64b), asm, OpNode>; 12127} 12128 12129//--- 12130// RCPC instructions (FEAT_LRCPC3) 12131//--- 12132 12133class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops, 12134 string asm, string operands, string cstr = ""> 12135 : I<oops, iops, asm, operands, cstr, []>, 12136 Sched<[WriteAtomic]> { 12137 bits<5> Rt; 12138 bits<5> Rn; 12139 let Inst{31-30} = size; 12140 let Inst{29-24} = {0,1,1,V,0,1}; 12141 let Inst{23-22} = opc; 12142 let Inst{21} = 0b0; 12143 // Inst{20-12} 12144 let Inst{11-10} = 0b10; 12145 let Inst{9-5} = Rn; 12146 let Inst{4-0} = Rt; 12147 12148 let mayLoad = Inst{22}; 12149 let mayStore = !not(Inst{22}); 12150 let hasSideEffects = 0; 12151} 12152 12153class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2, 12154 dag oops, dag iops, string asm, 12155 string operands, string cstr> 12156 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12157 bits<5> Rt2; 12158 let Inst{20-16} = Rt2; 12159 let Inst{15-12} = opc2; 12160} 12161 12162class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops, 12163 string asm, string operands, string cstr> 12164 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12165 let Inst{20-12} = 0b000000000; // imm9 12166} 12167 12168multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype, 12169 dag oops, dag iops, string asm> { 12170 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> { 12171 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 12172 let Inst{20-12} = simm; 12173 } 12174 12175 def a : InstAlias<asm # "\t$Rt, [$Rn]", 12176 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 12177} 12178 12179class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst> 12180 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm, 12181 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>, 12182 Sched<[]> { 12183 bit Q; 12184 let Inst{31} = 0; 12185 let Inst{30} = Q; 12186 let Inst{23} = 0; 12187 let Inst{20-16} = 0b00001; 12188 let Inst{12} = 0; // S 12189 let Inst{11-10} = 0b01; // size 12190 12191 let mayLoad = L; 12192 let mayStore = !not(L); 12193 let hasSideEffects = 1; 12194} 12195 12196//--- 12197// Instrumentation Extension (FEAT_ITE) 12198//--- 12199 12200let Predicates = [HasITE] in 12201def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> { 12202 let Inst{20-19} = 0b01; 12203 let Inst{18-16} = 0b011; 12204 let Inst{15-12} = 0b0111; 12205 let Inst{11-8} = 0b0010; 12206 let Inst{7-5} = 0b111; 12207} 12208 12209// * RCWCAS family 12210// * RCW<OP> family 12211 12212//-------------------------------------------------------------------- 12213// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?) 12214 12215// Instruction encoding: 12216// 12217// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0 12218// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12219// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12220// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12221// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12222 12223// Instruction syntax: 12224// 12225// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 12226// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>] 12227 12228class BaseRCWCASEncoding<dag oops, dag iops, string asm> 12229 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>, 12230 Sched<[]> { 12231 bit Acq; 12232 bit Rel; 12233 bit SC; 12234 bit Pair; 12235 bits<5> Rs; 12236 bits<5> Rn; 12237 bits<5> Rt; 12238 let Inst{31} = 0b0; 12239 let Inst{30} = SC; 12240 let Inst{29-24} = 0b011001; 12241 let Inst{23} = Acq; 12242 let Inst{22} = Rel; 12243 let Inst{21} = 0b1; 12244 let Inst{20-16} = Rs; 12245 let Inst{15-13} = 0b000; 12246 let Inst{12-11} = 0b01; 12247 let Inst{10} = Pair; 12248 let Inst{9-5} = Rn; 12249 let Inst{4-0} = Rt; 12250 let mayLoad = 1; 12251 let mayStore = 1; 12252 let hasSideEffects = 1; 12253 let Defs = [NZCV]; 12254} 12255 12256multiclass BaseRCWCAS<dag oops, dag iops, string prefix> { 12257 let Acq = 0b0, Rel = 0b0 in 12258 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">; 12259 let Acq = 0b1, Rel = 0b0 in 12260 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">; 12261 let Acq = 0b0, Rel = 0b1 in 12262 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">; 12263 let Acq = 0b1, Rel = 0b1 in 12264 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">; 12265} 12266 12267multiclass ReadCheckWriteCompareAndSwap { 12268 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in 12269 defm CAS : BaseRCWCAS<(outs GPR64:$out), 12270 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >; 12271 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in 12272 defm SCAS : BaseRCWCAS<(outs GPR64:$out), 12273 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">; 12274 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12275 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12276 (ins XSeqPairClassOperand:$Rs, 12277 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12278 "rcwcasp">; 12279 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12280 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12281 (ins XSeqPairClassOperand:$Rs, 12282 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12283 "rcwscasp">; 12284} 12285 12286//------------------------------------------------------------------ 12287// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?) 12288 12289// Instruction encoding: 12290// 12291// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12292// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12293// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12294// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12295// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12296// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12297// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12298 12299// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12300// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12301// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12302// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12303// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12304// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12305// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12306 12307// Instruction syntax: 12308// 12309// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 12310// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>] 12311 12312class BaseRCWOPEncoding<string asm> 12313 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm, 12314 "\t$Rs, $Rt, [$Rn]", "", []>, 12315 Sched<[]> { 12316 bit Acq; 12317 bit Rel; 12318 bit SC; 12319 bits<3> opc; 12320 bits<5> Rs; 12321 bits<5> Rn; 12322 bits<5> Rt; 12323 let Inst{31} = 0b0; 12324 let Inst{30} = SC; 12325 let Inst{29-24} = 0b111000; 12326 let Inst{23} = Acq; 12327 let Inst{22} = Rel; 12328 let Inst{21} = 0b1; 12329 let Inst{20-16} = Rs; 12330 let Inst{15} = 0b1; 12331 let Inst{14-12} = opc; 12332 let Inst{11-10} = 0b00; 12333 let Inst{9-5} = Rn; 12334 let Inst{4-0} = Rt; 12335 let mayLoad = 1; 12336 let mayStore = 1; 12337 let hasSideEffects = 1; 12338 let Defs = [NZCV]; 12339 let Predicates = [HasTHE]; 12340} 12341 12342class BaseRCWOPPEncoding<string asm> 12343 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12344 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm, 12345 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12346 Sched<[]> { 12347 bit Acq; 12348 bit Rel; 12349 bit SC; 12350 bits<3> opc; 12351 bits<5> Rt2; 12352 bits<5> Rn; 12353 bits<5> Rt; 12354 let Inst{31} = 0b0; 12355 let Inst{30} = SC; 12356 let Inst{29-24} = 0b011001; 12357 let Inst{23} = Acq; 12358 let Inst{22} = Rel; 12359 let Inst{21} = 0b1; 12360 let Inst{20-16} = Rt2; 12361 let Inst{15} = 0b1; 12362 let Inst{14-12} = opc; 12363 let Inst{11-10} = 0b00; 12364 let Inst{9-5} = Rn; 12365 let Inst{4-0} = Rt; 12366 let mayLoad = 1; 12367 let mayStore = 1; 12368 let hasSideEffects = 1; 12369 let Defs = [NZCV]; 12370 let Predicates = [HasTHE, HasD128]; 12371} 12372 12373multiclass BaseRCWOP<string prefix> { 12374 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">; 12375 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">; 12376 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">; 12377 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">; 12378 12379 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">; 12380 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">; 12381 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">; 12382 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">; 12383} 12384 12385multiclass ReadCheckWriteOperation<bits<3> opc, string op> { 12386 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>; 12387 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >; 12388} 12389 12390//--- 12391// 128-bit atomic instructions (FEAT_LSE128) 12392//--- 12393 12394let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in 12395class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm> 12396: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12397 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), 12398 asm, "\t$Rt, $Rt2, [$Rn]", 12399 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12400 Sched<[]> { 12401 bits<5> Rt; 12402 bits<5> Rt2; 12403 bits<5> Rn; 12404 let Inst{31-24} = 0b00011001; 12405 let Inst{23-22} = AR; 12406 let Inst{21} = 0b1; 12407 let Inst{20-16} = Rt2; 12408 let Inst{15} = o3; 12409 let Inst{14-12} = op0; 12410 let Inst{11-10} = 0b00; 12411 let Inst{9-5} = Rn; 12412 let Inst{4-0} = Rt; 12413} 12414 12415//--- 12416// 128-bit System Instructions (FEAT_SYSINSTR128) 12417//--- 12418 12419// Instruction encoding: 12420// 12421// 31 19|18 16|15 12|11 8|7 5|4 0 12422// SYSP 1101010101001| op1| Cn| Cm|op2| Rt 12423 12424// Instruction syntax: 12425// 12426// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>} 12427 12428class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> : 12429 RtSystemI<L, oops, iops, asm, operands, pattern> { 12430 let Inst{22} = 0b1; // override BaseSystemI 12431} 12432 12433class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs> 12434 : RtSystemI128<L, outputs, inputs, asm, operands> { 12435 bits<3> op1; 12436 bits<4> Cn; 12437 bits<4> Cm; 12438 bits<3> op2; 12439 let Inst{20-19} = 0b01; 12440 let Inst{18-16} = op1; 12441 let Inst{15-12} = Cn; 12442 let Inst{11-8} = Cm; 12443 let Inst{7-5} = op2; 12444} 12445class SystemPXtI<bit L, string asm> : 12446 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs), 12447 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>; 12448 12449 12450//---------------------------------------------------------------------------- 12451// Allow the size specifier tokens to be upper case, not just lower. 12452def : TokenAlias<".4B", ".4b">; // Add dot product 12453def : TokenAlias<".8B", ".8b">; 12454def : TokenAlias<".4H", ".4h">; 12455def : TokenAlias<".2S", ".2s">; 12456def : TokenAlias<".1D", ".1d">; 12457def : TokenAlias<".16B", ".16b">; 12458def : TokenAlias<".8H", ".8h">; 12459def : TokenAlias<".4S", ".4s">; 12460def : TokenAlias<".2D", ".2d">; 12461def : TokenAlias<".1Q", ".1q">; 12462def : TokenAlias<".2H", ".2h">; 12463def : TokenAlias<".B", ".b">; 12464def : TokenAlias<".H", ".h">; 12465def : TokenAlias<".S", ".s">; 12466def : TokenAlias<".D", ".d">; 12467def : TokenAlias<".Q", ".q">; 12468