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// v9.5-A FEAT_PAuth_LR 2372 2373class SignAuthFixedRegs<bits<5> opcode2, bits<6> opcode, string asm> 2374 : I<(outs), (ins), asm, "", "", []>, 2375 Sched<[WriteI, ReadI]> { 2376 let Inst{31} = 0b1; // sf 2377 let Inst{30} = 0b1; 2378 let Inst{29} = 0b0; // S 2379 let Inst{28-21} = 0b11010110; 2380 let Inst{20-16} = opcode2; 2381 let Inst{15-10} = opcode; 2382 let Inst{9-5} = 0b11111; // Rn 2383 let Inst{4-0} = 0b11110; // Rd 2384} 2385 2386def PAuthPCRelLabel16Operand : PCRelLabel<16> { 2387 let Name = "PAuthPCRelLabel16"; 2388 let PredicateMethod = "isPAuthPCRelLabel16Operand"; 2389} 2390def am_pauth_pcrel : Operand<OtherVT> { 2391 let EncoderMethod = "getPAuthPCRelOpValue"; 2392 let DecoderMethod = "DecodePCRelLabel16"; 2393 let PrintMethod = "printAlignedLabel"; 2394 let ParserMatchClass = PAuthPCRelLabel16Operand; 2395 let OperandType = "OPERAND_PCREL"; 2396} 2397 2398class SignAuthPCRel<bits<2> opc, string asm> 2399 : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>, 2400 Sched<[]> { 2401 bits<16> label; 2402 let Inst{31} = 0b1; // sf 2403 let Inst{30-23} = 0b11100111; 2404 let Inst{22-21} = opc; 2405 let Inst{20-5} = label; // imm 2406 let Inst{4-0} = 0b11111; // Rd 2407} 2408 2409class SignAuthOneReg<bits<5> opcode2, bits<6> opcode, string asm> 2410 : I<(outs), (ins GPR64:$Rn), asm, "\t$Rn", "", []>, 2411 Sched<[]> { 2412 bits<5> Rn; 2413 let Inst{31} = 0b1; // sf 2414 let Inst{30} = 0b1; 2415 let Inst{29} = 0b0; // S 2416 let Inst{28-21} = 0b11010110; 2417 let Inst{20-16} = opcode2; 2418 let Inst{15-10} = opcode; 2419 let Inst{9-5} = Rn; 2420 let Inst{4-0} = 0b11110; // Rd 2421} 2422 2423class SignAuthReturnPCRel<bits<3> opc, bits<5> op2, string asm> 2424 : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>, 2425 Sched<[WriteAtomic]> { 2426 bits<16> label; 2427 let Inst{31-24} = 0b01010101; 2428 let Inst{23-21} = opc; 2429 let Inst{20-5} = label; // imm16 2430 let Inst{4-0} = op2; 2431} 2432 2433class SignAuthReturnReg<bits<6> op3, string asm> 2434 : I<(outs), (ins GPR64common:$Rm), asm, "\t$Rm", "", []>, 2435 Sched<[WriteAtomic]> { 2436 bits<5> Rm; 2437 let Inst{31-25} = 0b1101011; 2438 let Inst{24-21} = 0b0010; // opc 2439 let Inst{20-16} = 0b11111; // op2 2440 let Inst{15-10} = op3; 2441 let Inst{9-5} = 0b11111; // Rn 2442 let Inst{4-0} = Rm; // op4 (Rm) 2443} 2444 2445// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 2446class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 2447 : I<(outs), iops, asm, ops, "", []>, 2448 Sched<[WriteI, ReadI, ReadI]> { 2449 let Uses = [NZCV]; 2450 let Defs = [NZCV]; 2451 bits<5> Rn; 2452 let Inst{31} = sf; 2453 let Inst{30-15} = 0b0111010000000000; 2454 let Inst{14} = sz; 2455 let Inst{13-10} = 0b0010; 2456 let Inst{9-5} = Rn; 2457 let Inst{4-0} = 0b01101; 2458} 2459 2460class FlagRotate<dag iops, string asm, string ops> 2461 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 2462 bits<6> imm; 2463 bits<4> mask; 2464 let Inst{20-15} = imm; 2465 let Inst{13-10} = 0b0001; 2466 let Inst{4} = 0b0; 2467 let Inst{3-0} = mask; 2468} 2469 2470//--- 2471// Basic two-operand data processing instructions. 2472//--- 2473class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2474 list<dag> pattern> 2475 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2476 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2477 Sched<[WriteI, ReadI, ReadI]> { 2478 let Uses = [NZCV]; 2479 bits<5> Rd; 2480 bits<5> Rn; 2481 bits<5> Rm; 2482 let Inst{30} = isSub; 2483 let Inst{28-21} = 0b11010000; 2484 let Inst{20-16} = Rm; 2485 let Inst{15-10} = 0; 2486 let Inst{9-5} = Rn; 2487 let Inst{4-0} = Rd; 2488} 2489 2490class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 2491 SDNode OpNode> 2492 : BaseBaseAddSubCarry<isSub, regtype, asm, 2493 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 2494 2495class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 2496 SDNode OpNode> 2497 : BaseBaseAddSubCarry<isSub, regtype, asm, 2498 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 2499 (implicit NZCV)]> { 2500 let Defs = [NZCV]; 2501} 2502 2503multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 2504 SDNode OpNode, SDNode OpNode_setflags> { 2505 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 2506 let Inst{31} = 0; 2507 let Inst{29} = 0; 2508 } 2509 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 2510 let Inst{31} = 1; 2511 let Inst{29} = 0; 2512 } 2513 2514 // Sets flags. 2515 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 2516 OpNode_setflags> { 2517 let Inst{31} = 0; 2518 let Inst{29} = 1; 2519 } 2520 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 2521 OpNode_setflags> { 2522 let Inst{31} = 1; 2523 let Inst{29} = 1; 2524 } 2525} 2526 2527class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype, 2528 string asm, SDPatternOperator OpNode, 2529 RegisterClass in1regtype = regtype, 2530 RegisterClass in2regtype = regtype> 2531 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 2532 asm, "\t$Rd, $Rn, $Rm", "", 2533 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 2534 bits<5> Rd; 2535 bits<5> Rn; 2536 bits<5> Rm; 2537 let Inst{31} = sf; 2538 let Inst{30} = 0b0; 2539 let Inst{29} = S; 2540 let Inst{28-21} = 0b11010110; 2541 let Inst{20-16} = Rm; 2542 let Inst{15-10} = opc; 2543 let Inst{9-5} = Rn; 2544 let Inst{4-0} = Rd; 2545} 2546 2547class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm, 2548 SDPatternOperator OpNode> 2549 : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> { 2550 let Inst{10} = isSigned; 2551} 2552 2553multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 2554 def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>, 2555 Sched<[WriteID32, ReadID, ReadID]>; 2556 2557 def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>, 2558 Sched<[WriteID64, ReadID, ReadID]>; 2559} 2560 2561class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm, 2562 SDPatternOperator OpNode = null_frag> 2563 : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>, 2564 Sched<[WriteIS, ReadI]> { 2565 let Inst{11-10} = shift_type; 2566} 2567 2568multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 2569 def Wr : BaseShift<0b0, shift_type, GPR32, asm>; 2570 2571 def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>; 2572 2573 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 2574 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 2575 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 2576 2577 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 2578 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2579 2580 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 2581 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2582 2583 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 2584 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 2585 2586 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 2587 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2588 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2589 2590 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 2591 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 2592 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 2593} 2594 2595class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 2596 : InstAlias<asm#"\t$dst, $src1, $src2", 2597 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 2598 2599class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 2600 RegisterClass addtype, string asm, 2601 list<dag> pattern> 2602 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 2603 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 2604 bits<5> Rd; 2605 bits<5> Rn; 2606 bits<5> Rm; 2607 bits<5> Ra; 2608 let Inst{30-24} = 0b0011011; 2609 let Inst{23-21} = opc; 2610 let Inst{20-16} = Rm; 2611 let Inst{15} = isSub; 2612 let Inst{14-10} = Ra; 2613 let Inst{9-5} = Rn; 2614 let Inst{4-0} = Rd; 2615} 2616 2617multiclass MulAccum<bit isSub, string asm> { 2618 // MADD/MSUB generation is decided by MachineCombiner.cpp 2619 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>, 2620 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2621 let Inst{31} = 0; 2622 } 2623 2624 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>, 2625 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 2626 let Inst{31} = 1; 2627 } 2628} 2629 2630class WideMulAccum<bit isSub, bits<3> opc, string asm, 2631 SDNode AccNode, SDNode ExtNode> 2632 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 2633 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 2634 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 2635 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 2636 let Inst{31} = 1; 2637} 2638 2639class MulHi<bits<3> opc, string asm, SDNode OpNode> 2640 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 2641 asm, "\t$Rd, $Rn, $Rm", "", 2642 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 2643 Sched<[WriteIM64, ReadIM, ReadIM]> { 2644 bits<5> Rd; 2645 bits<5> Rn; 2646 bits<5> Rm; 2647 let Inst{31-24} = 0b10011011; 2648 let Inst{23-21} = opc; 2649 let Inst{20-16} = Rm; 2650 let Inst{15} = 0; 2651 let Inst{9-5} = Rn; 2652 let Inst{4-0} = Rd; 2653 2654 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 2655 // (i.e. all bits 1) but is ignored by the processor. 2656 let PostEncoderMethod = "fixMulHigh"; 2657} 2658 2659class MulAccumWAlias<string asm, Instruction inst> 2660 : InstAlias<asm#"\t$dst, $src1, $src2", 2661 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 2662class MulAccumXAlias<string asm, Instruction inst> 2663 : InstAlias<asm#"\t$dst, $src1, $src2", 2664 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 2665class WideMulAccumAlias<string asm, Instruction inst> 2666 : InstAlias<asm#"\t$dst, $src1, $src2", 2667 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 2668 2669class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 2670 SDPatternOperator OpNode, string asm> 2671 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 2672 asm, "\t$Rd, $Rn, $Rm", "", 2673 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 2674 Sched<[WriteISReg, ReadI, ReadISReg]> { 2675 bits<5> Rd; 2676 bits<5> Rn; 2677 bits<5> Rm; 2678 2679 let Inst{31} = sf; 2680 let Inst{30-21} = 0b0011010110; 2681 let Inst{20-16} = Rm; 2682 let Inst{15-13} = 0b010; 2683 let Inst{12} = C; 2684 let Inst{11-10} = sz; 2685 let Inst{9-5} = Rn; 2686 let Inst{4-0} = Rd; 2687 let Predicates = [HasCRC]; 2688} 2689 2690//--- 2691// Address generation. 2692//--- 2693 2694class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 2695 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 2696 pattern>, 2697 Sched<[WriteI]> { 2698 bits<5> Xd; 2699 bits<21> label; 2700 let Inst{31} = page; 2701 let Inst{30-29} = label{1-0}; 2702 let Inst{28-24} = 0b10000; 2703 let Inst{23-5} = label{20-2}; 2704 let Inst{4-0} = Xd; 2705 2706 let DecoderMethod = "DecodeAdrInstruction"; 2707} 2708 2709//--- 2710// Move immediate. 2711//--- 2712 2713def movimm32_imm : Operand<i32> { 2714 let ParserMatchClass = AsmImmRange<0, 65535>; 2715 let EncoderMethod = "getMoveWideImmOpValue"; 2716 let PrintMethod = "printImm"; 2717} 2718def movimm32_shift : Operand<i32> { 2719 let PrintMethod = "printShifter"; 2720 let ParserMatchClass = MovImm32ShifterOperand; 2721} 2722def movimm64_shift : Operand<i32> { 2723 let PrintMethod = "printShifter"; 2724 let ParserMatchClass = MovImm64ShifterOperand; 2725} 2726 2727let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2728class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2729 string asm> 2730 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2731 asm, "\t$Rd, $imm$shift", "", []>, 2732 Sched<[WriteImm]> { 2733 bits<5> Rd; 2734 bits<16> imm; 2735 bits<6> shift; 2736 let Inst{30-29} = opc; 2737 let Inst{28-23} = 0b100101; 2738 let Inst{22-21} = shift{5-4}; 2739 let Inst{20-5} = imm; 2740 let Inst{4-0} = Rd; 2741 2742 let DecoderMethod = "DecodeMoveImmInstruction"; 2743} 2744 2745multiclass MoveImmediate<bits<2> opc, string asm> { 2746 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2747 let Inst{31} = 0; 2748 } 2749 2750 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2751 let Inst{31} = 1; 2752 } 2753} 2754 2755let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2756class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2757 string asm> 2758 : I<(outs regtype:$Rd), 2759 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2760 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2761 Sched<[WriteI, ReadI]> { 2762 bits<5> Rd; 2763 bits<16> imm; 2764 bits<6> shift; 2765 let Inst{30-29} = opc; 2766 let Inst{28-23} = 0b100101; 2767 let Inst{22-21} = shift{5-4}; 2768 let Inst{20-5} = imm; 2769 let Inst{4-0} = Rd; 2770 2771 let DecoderMethod = "DecodeMoveImmInstruction"; 2772} 2773 2774multiclass InsertImmediate<bits<2> opc, string asm> { 2775 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2776 let Inst{31} = 0; 2777 } 2778 2779 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2780 let Inst{31} = 1; 2781 } 2782} 2783 2784//--- 2785// Add/Subtract 2786//--- 2787 2788class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2789 string asm_inst, string asm_ops, 2790 dag inputs, dag pattern> 2791 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2792 Sched<[WriteI, ReadI]> { 2793 bits<5> Rd; 2794 bits<5> Rn; 2795 let Inst{30} = isSub; 2796 let Inst{29} = setFlags; 2797 let Inst{28-24} = 0b10001; 2798 let Inst{9-5} = Rn; 2799 let Inst{4-0} = Rd; 2800} 2801 2802class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2803 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2804 string asm_inst, SDPatternOperator OpNode> 2805 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2806 (ins srcRegtype:$Rn, immtype:$imm), 2807 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2808 bits<14> imm; 2809 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2810 let Inst{21-10} = imm{11-0}; 2811 let DecoderMethod = "DecodeAddSubImmShift"; 2812} 2813 2814class BaseAddSubRegPseudo<RegisterClass regtype, 2815 SDPatternOperator OpNode> 2816 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2817 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2818 Sched<[WriteI, ReadI, ReadI]>; 2819 2820class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2821 arith_shifted_reg shifted_regtype, string asm, 2822 SDPatternOperator OpNode> 2823 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 2824 asm, "\t$Rd, $Rn, $Rm_and_shift", "", 2825 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>, 2826 Sched<[WriteISReg, ReadI, ReadISReg]> { 2827 bits<5> Rd; 2828 bits<5> Rn; 2829 bits<5> Rm; 2830 bits<8> shift; 2831 let Inst{30} = isSub; 2832 let Inst{29} = setFlags; 2833 let Inst{28-24} = 0b01011; 2834 let Inst{23-22} = shift{7-6}; 2835 let Inst{21} = 0; 2836 let Inst{20-16} = Rm; 2837 let Inst{15-10} = shift{5-0}; 2838 let Inst{9-5} = Rn; 2839 let Inst{4-0} = Rd; 2840 2841 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2842} 2843 2844class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2845 RegisterClass src1Regtype, Operand src2Regtype, 2846 string asm, SDPatternOperator OpNode> 2847 : I<(outs dstRegtype:$Rd), 2848 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend), 2849 asm, "\t$Rd, $Rn, $Rm_and_extend", "", 2850 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>, 2851 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2852 bits<5> Rd; 2853 bits<5> Rn; 2854 bits<5> Rm; 2855 bits<6> extend; 2856 let Inst{30} = isSub; 2857 let Inst{29} = setFlags; 2858 let Inst{28-24} = 0b01011; 2859 let Inst{23-21} = 0b001; 2860 let Inst{20-16} = Rm; 2861 let Inst{15-13} = extend{5-3}; 2862 let Inst{12-10} = extend{2-0}; 2863 let Inst{9-5} = Rn; 2864 let Inst{4-0} = Rd; 2865 2866 let DecoderMethod = "DecodeAddSubERegInstruction"; 2867} 2868 2869let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2870class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2871 RegisterClass src1Regtype, RegisterClass src2Regtype, 2872 Operand ext_op, string asm> 2873 : I<(outs dstRegtype:$Rd), 2874 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2875 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2876 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2877 bits<5> Rd; 2878 bits<5> Rn; 2879 bits<5> Rm; 2880 bits<6> ext; 2881 let Inst{30} = isSub; 2882 let Inst{29} = setFlags; 2883 let Inst{28-24} = 0b01011; 2884 let Inst{23-21} = 0b001; 2885 let Inst{20-16} = Rm; 2886 let Inst{15} = ext{5}; 2887 let Inst{12-10} = ext{2-0}; 2888 let Inst{9-5} = Rn; 2889 let Inst{4-0} = Rd; 2890 2891 let DecoderMethod = "DecodeAddSubERegInstruction"; 2892} 2893 2894// Aliases for register+register add/subtract. 2895class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2896 RegisterClass src1Regtype, RegisterClass src2Regtype, 2897 int shiftExt> 2898 : InstAlias<asm#"\t$dst, $src1, $src2", 2899 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2900 shiftExt)>; 2901 2902multiclass AddSub<bit isSub, string mnemonic, string alias, 2903 SDPatternOperator OpNode = null_frag> { 2904 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2905 // Add/Subtract immediate 2906 // Increase the weight of the immediate variant to try to match it before 2907 // the extended register variant. 2908 // We used to match the register variant before the immediate when the 2909 // register argument could be implicitly zero-extended. 2910 let AddedComplexity = 6 in 2911 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2912 mnemonic, OpNode> { 2913 let Inst{31} = 0; 2914 } 2915 let AddedComplexity = 6 in 2916 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2917 mnemonic, OpNode> { 2918 let Inst{31} = 1; 2919 } 2920 2921 // Add/Subtract register - Only used for CodeGen 2922 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2923 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2924 2925 // Add/Subtract shifted register 2926 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2927 OpNode> { 2928 let Inst{31} = 0; 2929 } 2930 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2931 OpNode> { 2932 let Inst{31} = 1; 2933 } 2934 } 2935 2936 // Add/Subtract extended register 2937 let AddedComplexity = 1, hasSideEffects = 0 in { 2938 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2939 arith_extended_reg32_i32, mnemonic, OpNode> { 2940 let Inst{31} = 0; 2941 } 2942 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2943 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2944 let Inst{31} = 1; 2945 } 2946 } 2947 2948 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2949 arith_extendlsl64, mnemonic> { 2950 // UXTX and SXTX only. 2951 let Inst{14-13} = 0b11; 2952 let Inst{31} = 1; 2953 } 2954 2955 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2956 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2957 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2958 addsub_shifted_imm32_neg:$imm), 0>; 2959 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2960 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2961 addsub_shifted_imm64_neg:$imm), 0>; 2962 2963 // Register/register aliases with no shift when SP is not used. 2964 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2965 GPR32, GPR32, GPR32, 0>; 2966 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2967 GPR64, GPR64, GPR64, 0>; 2968 2969 // Register/register aliases with no shift when either the destination or 2970 // first source register is SP. 2971 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2972 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2973 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2974 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2975 def : AddSubRegAlias<mnemonic, 2976 !cast<Instruction>(NAME#"Xrx64"), 2977 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2978 def : AddSubRegAlias<mnemonic, 2979 !cast<Instruction>(NAME#"Xrx64"), 2980 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2981} 2982 2983multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2984 string alias, string cmpAlias> { 2985 let isCompare = 1, Defs = [NZCV] in { 2986 // Add/Subtract immediate 2987 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2988 mnemonic, OpNode> { 2989 let Inst{31} = 0; 2990 } 2991 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2992 mnemonic, OpNode> { 2993 let Inst{31} = 1; 2994 } 2995 2996 // Add/Subtract register 2997 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2998 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2999 3000 // Add/Subtract shifted register 3001 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 3002 OpNode> { 3003 let Inst{31} = 0; 3004 } 3005 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 3006 OpNode> { 3007 let Inst{31} = 1; 3008 } 3009 3010 // Add/Subtract extended register 3011 let AddedComplexity = 1 in { 3012 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 3013 arith_extended_reg32_i32, mnemonic, OpNode> { 3014 let Inst{31} = 0; 3015 } 3016 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 3017 arith_extended_reg32_i64, mnemonic, OpNode> { 3018 let Inst{31} = 1; 3019 } 3020 } 3021 3022 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 3023 arith_extendlsl64, mnemonic> { 3024 // UXTX and SXTX only. 3025 let Inst{14-13} = 0b11; 3026 let Inst{31} = 1; 3027 } 3028 } // Defs = [NZCV] 3029 3030 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 3031 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3032 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 3033 addsub_shifted_imm32_neg:$imm), 0>; 3034 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3035 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 3036 addsub_shifted_imm64_neg:$imm), 0>; 3037 3038 // Compare aliases 3039 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 3040 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 3041 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 3042 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 3043 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 3044 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 3045 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 3046 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 3047 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 3048 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 3049 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 3050 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 3051 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 3052 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 3053 3054 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 3055 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 3056 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 3057 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 3058 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 3059 3060 // Compare shorthands 3061 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 3062 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 3063 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 3064 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 3065 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 3066 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 3067 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 3068 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 3069 3070 // Register/register aliases with no shift when SP is not used. 3071 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 3072 GPR32, GPR32, GPR32, 0>; 3073 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 3074 GPR64, GPR64, GPR64, 0>; 3075 3076 // Register/register aliases with no shift when the first source register 3077 // is SP. 3078 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 3079 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 3080 def : AddSubRegAlias<mnemonic, 3081 !cast<Instruction>(NAME#"Xrx64"), 3082 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 3083} 3084 3085class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 3086 : BaseAddSubImm< 3087 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 3088 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 3089 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 3090 bits<6> imm6; 3091 bits<4> imm4; 3092 let Inst{31} = 1; 3093 let Inst{23-22} = 0b10; 3094 let Inst{21-16} = imm6; 3095 let Inst{15-14} = 0b00; 3096 let Inst{13-10} = imm4; 3097 let Unpredictable{15-14} = 0b11; 3098} 3099 3100class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 3101 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode, 3102 GPR64sp, GPR64sp>; 3103 3104//--- 3105// Extract 3106//--- 3107def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 3108 SDTCisPtrTy<3>]>; 3109def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 3110 3111class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 3112 list<dag> patterns> 3113 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 3114 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 3115 Sched<[WriteExtr, ReadExtrHi]> { 3116 bits<5> Rd; 3117 bits<5> Rn; 3118 bits<5> Rm; 3119 bits<6> imm; 3120 3121 let Inst{30-23} = 0b00100111; 3122 let Inst{21} = 0; 3123 let Inst{20-16} = Rm; 3124 let Inst{15-10} = imm; 3125 let Inst{9-5} = Rn; 3126 let Inst{4-0} = Rd; 3127} 3128 3129multiclass ExtractImm<string asm> { 3130 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 3131 [(set GPR32:$Rd, 3132 (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 3133 let Inst{31} = 0; 3134 let Inst{22} = 0; 3135 // imm<5> must be zero. 3136 let imm{5} = 0; 3137 } 3138 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 3139 [(set GPR64:$Rd, 3140 (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 3141 3142 let Inst{31} = 1; 3143 let Inst{22} = 1; 3144 } 3145} 3146 3147//--- 3148// Bitfield 3149//--- 3150 3151let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3152class BaseBitfieldImm<bits<2> opc, 3153 RegisterClass regtype, Operand imm_type, string asm> 3154 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 3155 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 3156 Sched<[WriteIS, ReadI]> { 3157 bits<5> Rd; 3158 bits<5> Rn; 3159 bits<6> immr; 3160 bits<6> imms; 3161 3162 let Inst{30-29} = opc; 3163 let Inst{28-23} = 0b100110; 3164 let Inst{21-16} = immr; 3165 let Inst{15-10} = imms; 3166 let Inst{9-5} = Rn; 3167 let Inst{4-0} = Rd; 3168} 3169 3170multiclass BitfieldImm<bits<2> opc, string asm> { 3171 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 3172 let Inst{31} = 0; 3173 let Inst{22} = 0; 3174 // imms<5> and immr<5> must be zero, else ReservedValue(). 3175 let Inst{21} = 0; 3176 let Inst{15} = 0; 3177 } 3178 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 3179 let Inst{31} = 1; 3180 let Inst{22} = 1; 3181 } 3182} 3183 3184let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3185class BaseBitfieldImmWith2RegArgs<bits<2> opc, 3186 RegisterClass regtype, Operand imm_type, string asm> 3187 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 3188 imm_type:$imms), 3189 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 3190 Sched<[WriteIS, ReadI]> { 3191 bits<5> Rd; 3192 bits<5> Rn; 3193 bits<6> immr; 3194 bits<6> imms; 3195 3196 let Inst{30-29} = opc; 3197 let Inst{28-23} = 0b100110; 3198 let Inst{21-16} = immr; 3199 let Inst{15-10} = imms; 3200 let Inst{9-5} = Rn; 3201 let Inst{4-0} = Rd; 3202} 3203 3204multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 3205 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 3206 let Inst{31} = 0; 3207 let Inst{22} = 0; 3208 // imms<5> and immr<5> must be zero, else ReservedValue(). 3209 let Inst{21} = 0; 3210 let Inst{15} = 0; 3211 } 3212 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 3213 let Inst{31} = 1; 3214 let Inst{22} = 1; 3215 } 3216} 3217 3218//--- 3219// Logical 3220//--- 3221 3222// Logical (immediate) 3223class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 3224 RegisterClass sregtype, Operand imm_type, string asm, 3225 list<dag> pattern> 3226 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 3227 asm, "\t$Rd, $Rn, $imm", "", pattern>, 3228 Sched<[WriteI, ReadI]> { 3229 bits<5> Rd; 3230 bits<5> Rn; 3231 bits<13> imm; 3232 let Inst{30-29} = opc; 3233 let Inst{28-23} = 0b100100; 3234 let Inst{22} = imm{12}; 3235 let Inst{21-16} = imm{11-6}; 3236 let Inst{15-10} = imm{5-0}; 3237 let Inst{9-5} = Rn; 3238 let Inst{4-0} = Rd; 3239 3240 let DecoderMethod = "DecodeLogicalImmInstruction"; 3241} 3242 3243// Logical (shifted register) 3244class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 3245 logical_shifted_reg shifted_regtype, string asm, 3246 list<dag> pattern> 3247 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 3248 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>, 3249 Sched<[WriteISReg, ReadI, ReadISReg]> { 3250 bits<5> Rd; 3251 bits<5> Rn; 3252 bits<5> Rm; 3253 bits<8> shift; 3254 let Inst{30-29} = opc; 3255 let Inst{28-24} = 0b01010; 3256 let Inst{23-22} = shift{7-6}; 3257 let Inst{21} = N; 3258 let Inst{20-16} = Rm; 3259 let Inst{15-10} = shift{5-0}; 3260 let Inst{9-5} = Rn; 3261 let Inst{4-0} = Rd; 3262 3263 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 3264} 3265 3266// Aliases for register+register logical instructions. 3267class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 3268 : InstAlias<asm#"\t$dst, $src1, $src2", 3269 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 3270 3271multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 3272 string Alias> { 3273 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3274 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 3275 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 3276 logical_imm32:$imm))]> { 3277 let Inst{31} = 0; 3278 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3279 } 3280 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3281 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 3282 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 3283 logical_imm64:$imm))]> { 3284 let Inst{31} = 1; 3285 } 3286 3287 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3288 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 3289 logical_imm32_not:$imm), 0>; 3290 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3291 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 3292 logical_imm64_not:$imm), 0>; 3293} 3294 3295multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 3296 string Alias> { 3297 let isCompare = 1, Defs = [NZCV] in { 3298 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 3299 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 3300 let Inst{31} = 0; 3301 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3302 } 3303 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 3304 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 3305 let Inst{31} = 1; 3306 } 3307 } // end Defs = [NZCV] 3308 3309 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3310 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 3311 logical_imm32_not:$imm), 0>; 3312 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3313 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 3314 logical_imm64_not:$imm), 0>; 3315} 3316 3317class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 3318 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3319 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 3320 Sched<[WriteI, ReadI, ReadI]>; 3321 3322// Split from LogicalImm as not all instructions have both. 3323multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 3324 SDPatternOperator OpNode, int AddedComplexityVal = 0> { 3325 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in { 3326 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3327 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3328 } 3329 3330 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3331 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3332 logical_shifted_reg32:$Rm_and_shift))]> { 3333 let Inst{31} = 0; 3334 } 3335 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3336 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3337 logical_shifted_reg64:$Rm_and_shift))]> { 3338 let Inst{31} = 1; 3339 } 3340 3341 def : LogicalRegAlias<mnemonic, 3342 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3343 def : LogicalRegAlias<mnemonic, 3344 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3345} 3346 3347// Split from LogicalReg to allow setting NZCV Defs 3348multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3349 SDPatternOperator OpNode = null_frag> { 3350 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3351 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3352 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3353 3354 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3355 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> { 3356 let Inst{31} = 0; 3357 } 3358 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3359 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> { 3360 let Inst{31} = 1; 3361 } 3362 } // Defs = [NZCV] 3363 3364 def : LogicalRegAlias<mnemonic, 3365 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3366 def : LogicalRegAlias<mnemonic, 3367 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3368} 3369 3370//--- 3371// Conditionally set flags 3372//--- 3373 3374let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3375class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3376 string mnemonic, SDNode OpNode> 3377 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3378 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3379 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3380 (i32 imm:$cond), NZCV))]>, 3381 Sched<[WriteI, ReadI]> { 3382 let Uses = [NZCV]; 3383 let Defs = [NZCV]; 3384 3385 bits<5> Rn; 3386 bits<5> imm; 3387 bits<4> nzcv; 3388 bits<4> cond; 3389 3390 let Inst{30} = op; 3391 let Inst{29-21} = 0b111010010; 3392 let Inst{20-16} = imm; 3393 let Inst{15-12} = cond; 3394 let Inst{11-10} = 0b10; 3395 let Inst{9-5} = Rn; 3396 let Inst{4} = 0b0; 3397 let Inst{3-0} = nzcv; 3398} 3399 3400let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3401class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3402 SDNode OpNode> 3403 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3404 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3405 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3406 (i32 imm:$cond), NZCV))]>, 3407 Sched<[WriteI, ReadI, ReadI]> { 3408 let Uses = [NZCV]; 3409 let Defs = [NZCV]; 3410 3411 bits<5> Rn; 3412 bits<5> Rm; 3413 bits<4> nzcv; 3414 bits<4> cond; 3415 3416 let Inst{30} = op; 3417 let Inst{29-21} = 0b111010010; 3418 let Inst{20-16} = Rm; 3419 let Inst{15-12} = cond; 3420 let Inst{11-10} = 0b00; 3421 let Inst{9-5} = Rn; 3422 let Inst{4} = 0b0; 3423 let Inst{3-0} = nzcv; 3424} 3425 3426multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3427 // immediate operand variants 3428 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3429 let Inst{31} = 0; 3430 } 3431 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3432 let Inst{31} = 1; 3433 } 3434 // register operand variants 3435 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3436 let Inst{31} = 0; 3437 } 3438 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3439 let Inst{31} = 1; 3440 } 3441} 3442 3443//--- 3444// Conditional select 3445//--- 3446 3447class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3448 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3449 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3450 [(set regtype:$Rd, 3451 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3452 Sched<[WriteI, ReadI, ReadI]> { 3453 let Uses = [NZCV]; 3454 3455 bits<5> Rd; 3456 bits<5> Rn; 3457 bits<5> Rm; 3458 bits<4> cond; 3459 3460 let Inst{30} = op; 3461 let Inst{29-21} = 0b011010100; 3462 let Inst{20-16} = Rm; 3463 let Inst{15-12} = cond; 3464 let Inst{11-10} = op2; 3465 let Inst{9-5} = Rn; 3466 let Inst{4-0} = Rd; 3467} 3468 3469multiclass CondSelect<bit op, bits<2> op2, string asm> { 3470 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3471 let Inst{31} = 0; 3472 } 3473 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3474 let Inst{31} = 1; 3475 } 3476} 3477 3478class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3479 PatFrag frag> 3480 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3481 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3482 [(set regtype:$Rd, 3483 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3484 (i32 imm:$cond), NZCV))]>, 3485 Sched<[WriteI, ReadI, ReadI]> { 3486 let Uses = [NZCV]; 3487 3488 bits<5> Rd; 3489 bits<5> Rn; 3490 bits<5> Rm; 3491 bits<4> cond; 3492 3493 let Inst{30} = op; 3494 let Inst{29-21} = 0b011010100; 3495 let Inst{20-16} = Rm; 3496 let Inst{15-12} = cond; 3497 let Inst{11-10} = op2; 3498 let Inst{9-5} = Rn; 3499 let Inst{4-0} = Rd; 3500} 3501 3502def inv_cond_XFORM : SDNodeXForm<imm, [{ 3503 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3504 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3505 MVT::i32); 3506}]>; 3507 3508multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3509 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3510 let Inst{31} = 0; 3511 } 3512 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3513 let Inst{31} = 1; 3514 } 3515 3516 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3517 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3518 (inv_cond_XFORM imm:$cond))>; 3519 3520 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3521 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3522 (inv_cond_XFORM imm:$cond))>; 3523} 3524 3525//--- 3526// Special Mask Value 3527//--- 3528def maski8_or_more : Operand<i32>, 3529 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3530} 3531def maski16_or_more : Operand<i32>, 3532 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3533} 3534 3535 3536//--- 3537// Load/store 3538//--- 3539 3540// (unsigned immediate) 3541// Indexed for 8-bit registers. offset is in range [0,4095]. 3542def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3543def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3544def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3545def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3546def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3547 3548// (unsigned immediate) 3549// Indexed for 8-bit registers. offset is in range [0,63]. 3550def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3551def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3552def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3553def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3554 3555def gi_am_indexed8 : 3556 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3557 GIComplexPatternEquiv<am_indexed8>; 3558def gi_am_indexed16 : 3559 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3560 GIComplexPatternEquiv<am_indexed16>; 3561def gi_am_indexed32 : 3562 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3563 GIComplexPatternEquiv<am_indexed32>; 3564def gi_am_indexed64 : 3565 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3566 GIComplexPatternEquiv<am_indexed64>; 3567def gi_am_indexed128 : 3568 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3569 GIComplexPatternEquiv<am_indexed128>; 3570 3571class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3572 let Name = "UImm12Offset" # Scale; 3573 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3574 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3575 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3576} 3577 3578def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3579def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3580def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3581def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3582def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3583 3584class uimm12_scaled<int Scale> : Operand<i64> { 3585 let ParserMatchClass 3586 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3587 let EncoderMethod 3588 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3589 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3590} 3591 3592def uimm12s1 : uimm12_scaled<1>; 3593def uimm12s2 : uimm12_scaled<2>; 3594def uimm12s4 : uimm12_scaled<4>; 3595def uimm12s8 : uimm12_scaled<8>; 3596def uimm12s16 : uimm12_scaled<16>; 3597 3598class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3599 string asm, list<dag> pattern> 3600 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3601 bits<5> Rt; 3602 3603 bits<5> Rn; 3604 bits<12> offset; 3605 3606 let Inst{31-30} = sz; 3607 let Inst{29-27} = 0b111; 3608 let Inst{26} = V; 3609 let Inst{25-24} = 0b01; 3610 let Inst{23-22} = opc; 3611 let Inst{21-10} = offset; 3612 let Inst{9-5} = Rn; 3613 let Inst{4-0} = Rt; 3614 3615 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3616} 3617 3618multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3619 Operand indextype, string asm, list<dag> pattern> { 3620 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3621 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3622 (ins GPR64sp:$Rn, indextype:$offset), 3623 asm, pattern>, 3624 Sched<[WriteLD]>; 3625 3626 def : InstAlias<asm # "\t$Rt, [$Rn]", 3627 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3628} 3629 3630multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3631 Operand indextype, string asm, list<dag> pattern> { 3632 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3633 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3634 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3635 asm, pattern>, 3636 Sched<[WriteST]>; 3637 3638 def : InstAlias<asm # "\t$Rt, [$Rn]", 3639 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3640} 3641 3642// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3643// substitute zero-registers automatically. 3644// 3645// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3646// into StoreUI. 3647multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3648 Operand indextype, string asm, list<dag> pattern> { 3649 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3650 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3651 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3652 asm, pattern>, 3653 Sched<[WriteST]>; 3654 3655 def : InstAlias<asm # "\t$Rt, [$Rn]", 3656 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3657} 3658 3659def PrefetchOperand : AsmOperandClass { 3660 let Name = "Prefetch"; 3661 let ParserMethod = "tryParsePrefetch"; 3662} 3663def prfop : Operand<i32> { 3664 let PrintMethod = "printPrefetchOp"; 3665 let ParserMatchClass = PrefetchOperand; 3666} 3667 3668let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3669class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3670 : BaseLoadStoreUI<sz, V, opc, 3671 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3672 asm, pat>, 3673 Sched<[WriteLD]>; 3674 3675//--- 3676// Load literal 3677//--- 3678 3679// Load literal address: 19-bit immediate. The low two bits of the target 3680// offset are implied zero and so are not part of the immediate. 3681def am_ldrlit : Operand<iPTR> { 3682 let EncoderMethod = "getLoadLiteralOpValue"; 3683 let DecoderMethod = "DecodePCRelLabel19"; 3684 let PrintMethod = "printAlignedLabel"; 3685 let ParserMatchClass = PCRelLabel19Operand; 3686 let OperandType = "OPERAND_PCREL"; 3687} 3688 3689let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3690class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3691 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3692 asm, "\t$Rt, $label", "", pat>, 3693 Sched<[WriteLD]> { 3694 bits<5> Rt; 3695 bits<19> label; 3696 let Inst{31-30} = opc; 3697 let Inst{29-27} = 0b011; 3698 let Inst{26} = V; 3699 let Inst{25-24} = 0b00; 3700 let Inst{23-5} = label; 3701 let Inst{4-0} = Rt; 3702} 3703 3704let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3705class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3706 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3707 asm, "\t$Rt, $label", "", pat>, 3708 Sched<[WriteLD]> { 3709 bits<5> Rt; 3710 bits<19> label; 3711 let Inst{31-30} = opc; 3712 let Inst{29-27} = 0b011; 3713 let Inst{26} = V; 3714 let Inst{25-24} = 0b00; 3715 let Inst{23-5} = label; 3716 let Inst{4-0} = Rt; 3717} 3718 3719//--- 3720// Load/store register offset 3721//--- 3722 3723def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3724def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3725def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3726def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3727def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3728 3729def gi_ro_Xindexed8 : 3730 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3731 GIComplexPatternEquiv<ro_Xindexed8>; 3732def gi_ro_Xindexed16 : 3733 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3734 GIComplexPatternEquiv<ro_Xindexed16>; 3735def gi_ro_Xindexed32 : 3736 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3737 GIComplexPatternEquiv<ro_Xindexed32>; 3738def gi_ro_Xindexed64 : 3739 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3740 GIComplexPatternEquiv<ro_Xindexed64>; 3741def gi_ro_Xindexed128 : 3742 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3743 GIComplexPatternEquiv<ro_Xindexed128>; 3744 3745def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3746def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3747def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3748def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3749def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3750 3751def gi_ro_Windexed8 : 3752 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3753 GIComplexPatternEquiv<ro_Windexed8>; 3754def gi_ro_Windexed16 : 3755 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3756 GIComplexPatternEquiv<ro_Windexed16>; 3757def gi_ro_Windexed32 : 3758 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3759 GIComplexPatternEquiv<ro_Windexed32>; 3760def gi_ro_Windexed64 : 3761 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3762 GIComplexPatternEquiv<ro_Windexed64>; 3763def gi_ro_Windexed128 : 3764 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3765 GIComplexPatternEquiv<ro_Windexed128>; 3766 3767class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3768 let Name = "Mem" # Reg # "Extend" # Width; 3769 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3770 let RenderMethod = "addMemExtendOperands"; 3771 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3772} 3773 3774def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3775 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3776 // the trivial shift. 3777 let RenderMethod = "addMemExtend8Operands"; 3778} 3779def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3780def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3781def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3782def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3783 3784def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3785 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3786 // the trivial shift. 3787 let RenderMethod = "addMemExtend8Operands"; 3788} 3789def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3790def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3791def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3792def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3793 3794class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3795 : Operand<i32> { 3796 let ParserMatchClass = ParserClass; 3797 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3798 let DecoderMethod = "DecodeMemExtend"; 3799 let EncoderMethod = "getMemExtendOpValue"; 3800 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3801} 3802 3803def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3804def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3805def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3806def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3807def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3808 3809def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3810def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3811def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3812def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3813def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3814 3815class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3816 Operand wextend, Operand xextend> { 3817 // CodeGen-level pattern covering the entire addressing mode. 3818 ComplexPattern Wpat = windex; 3819 ComplexPattern Xpat = xindex; 3820 3821 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3822 Operand Wext = wextend; 3823 Operand Xext = xextend; 3824} 3825 3826def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3827def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3828def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3829def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3830def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3831 ro_Xextend128>; 3832 3833class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3834 dag outs, list<dag> pat> 3835 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3836 bits<5> Rt; 3837 bits<5> Rn; 3838 bits<5> Rm; 3839 bits<2> extend; 3840 let Inst{31-30} = sz; 3841 let Inst{29-27} = 0b111; 3842 let Inst{26} = V; 3843 let Inst{25-24} = 0b00; 3844 let Inst{23-22} = opc; 3845 let Inst{21} = 1; 3846 let Inst{20-16} = Rm; 3847 let Inst{15} = extend{1}; // sign extend Rm? 3848 let Inst{14} = 1; 3849 let Inst{12} = extend{0}; // do shift? 3850 let Inst{11-10} = 0b10; 3851 let Inst{9-5} = Rn; 3852 let Inst{4-0} = Rt; 3853} 3854 3855class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3856 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3857 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3858 3859multiclass Load8RO<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 : LoadStore8RO<sz, V, opc, asm, 3863 (outs regtype:$Rt), 3864 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3865 [(set (Ty regtype:$Rt), 3866 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3867 ro_Wextend8:$extend)))]>, 3868 Sched<[WriteLDIdx, ReadAdrBase]> { 3869 let Inst{13} = 0b0; 3870 } 3871 3872 let AddedComplexity = 10 in 3873 def roX : LoadStore8RO<sz, V, opc, asm, 3874 (outs regtype:$Rt), 3875 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3876 [(set (Ty regtype:$Rt), 3877 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3878 ro_Xextend8:$extend)))]>, 3879 Sched<[WriteLDIdx, ReadAdrBase]> { 3880 let Inst{13} = 0b1; 3881 } 3882 3883 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3884} 3885 3886multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3887 string asm, ValueType Ty, SDPatternOperator storeop> { 3888 let AddedComplexity = 10 in 3889 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3890 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3891 [(storeop (Ty regtype:$Rt), 3892 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3893 ro_Wextend8:$extend))]>, 3894 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3895 let Inst{13} = 0b0; 3896 } 3897 3898 let AddedComplexity = 10 in 3899 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3900 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3901 [(storeop (Ty regtype:$Rt), 3902 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3903 ro_Xextend8:$extend))]>, 3904 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3905 let Inst{13} = 0b1; 3906 } 3907 3908 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3909} 3910 3911class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3912 dag outs, list<dag> pat> 3913 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3914 bits<5> Rt; 3915 bits<5> Rn; 3916 bits<5> Rm; 3917 bits<2> extend; 3918 let Inst{31-30} = sz; 3919 let Inst{29-27} = 0b111; 3920 let Inst{26} = V; 3921 let Inst{25-24} = 0b00; 3922 let Inst{23-22} = opc; 3923 let Inst{21} = 1; 3924 let Inst{20-16} = Rm; 3925 let Inst{15} = extend{1}; // sign extend Rm? 3926 let Inst{14} = 1; 3927 let Inst{12} = extend{0}; // do shift? 3928 let Inst{11-10} = 0b10; 3929 let Inst{9-5} = Rn; 3930 let Inst{4-0} = Rt; 3931} 3932 3933multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3934 string asm, ValueType Ty, SDPatternOperator loadop> { 3935 let AddedComplexity = 10 in 3936 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3937 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3938 [(set (Ty regtype:$Rt), 3939 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3940 ro_Wextend16:$extend)))]>, 3941 Sched<[WriteLDIdx, ReadAdrBase]> { 3942 let Inst{13} = 0b0; 3943 } 3944 3945 let AddedComplexity = 10 in 3946 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3947 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3948 [(set (Ty regtype:$Rt), 3949 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3950 ro_Xextend16:$extend)))]>, 3951 Sched<[WriteLDIdx, ReadAdrBase]> { 3952 let Inst{13} = 0b1; 3953 } 3954 3955 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3956} 3957 3958multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3959 string asm, ValueType Ty, SDPatternOperator storeop> { 3960 let AddedComplexity = 10 in 3961 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3962 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3963 [(storeop (Ty regtype:$Rt), 3964 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3965 ro_Wextend16:$extend))]>, 3966 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3967 let Inst{13} = 0b0; 3968 } 3969 3970 let AddedComplexity = 10 in 3971 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3972 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3973 [(storeop (Ty regtype:$Rt), 3974 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3975 ro_Xextend16:$extend))]>, 3976 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3977 let Inst{13} = 0b1; 3978 } 3979 3980 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3981} 3982 3983class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3984 dag outs, list<dag> pat> 3985 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3986 bits<5> Rt; 3987 bits<5> Rn; 3988 bits<5> Rm; 3989 bits<2> extend; 3990 let Inst{31-30} = sz; 3991 let Inst{29-27} = 0b111; 3992 let Inst{26} = V; 3993 let Inst{25-24} = 0b00; 3994 let Inst{23-22} = opc; 3995 let Inst{21} = 1; 3996 let Inst{20-16} = Rm; 3997 let Inst{15} = extend{1}; // sign extend Rm? 3998 let Inst{14} = 1; 3999 let Inst{12} = extend{0}; // do shift? 4000 let Inst{11-10} = 0b10; 4001 let Inst{9-5} = Rn; 4002 let Inst{4-0} = Rt; 4003} 4004 4005multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4006 string asm, ValueType Ty, SDPatternOperator loadop> { 4007 let AddedComplexity = 10 in 4008 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 4009 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 4010 [(set (Ty regtype:$Rt), 4011 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 4012 ro_Wextend32:$extend)))]>, 4013 Sched<[WriteLDIdx, ReadAdrBase]> { 4014 let Inst{13} = 0b0; 4015 } 4016 4017 let AddedComplexity = 10 in 4018 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 4019 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 4020 [(set (Ty regtype:$Rt), 4021 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 4022 ro_Xextend32:$extend)))]>, 4023 Sched<[WriteLDIdx, ReadAdrBase]> { 4024 let Inst{13} = 0b1; 4025 } 4026 4027 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4028} 4029 4030multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4031 string asm, ValueType Ty, SDPatternOperator storeop> { 4032 let AddedComplexity = 10 in 4033 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 4034 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 4035 [(storeop (Ty regtype:$Rt), 4036 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 4037 ro_Wextend32:$extend))]>, 4038 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4039 let Inst{13} = 0b0; 4040 } 4041 4042 let AddedComplexity = 10 in 4043 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 4044 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 4045 [(storeop (Ty regtype:$Rt), 4046 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 4047 ro_Xextend32:$extend))]>, 4048 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4049 let Inst{13} = 0b1; 4050 } 4051 4052 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4053} 4054 4055class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4056 dag outs, list<dag> pat> 4057 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4058 bits<5> Rt; 4059 bits<5> Rn; 4060 bits<5> Rm; 4061 bits<2> extend; 4062 let Inst{31-30} = sz; 4063 let Inst{29-27} = 0b111; 4064 let Inst{26} = V; 4065 let Inst{25-24} = 0b00; 4066 let Inst{23-22} = opc; 4067 let Inst{21} = 1; 4068 let Inst{20-16} = Rm; 4069 let Inst{15} = extend{1}; // sign extend Rm? 4070 let Inst{14} = 1; 4071 let Inst{12} = extend{0}; // do shift? 4072 let Inst{11-10} = 0b10; 4073 let Inst{9-5} = Rn; 4074 let Inst{4-0} = Rt; 4075} 4076 4077multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4078 string asm, ValueType Ty, SDPatternOperator loadop> { 4079 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4080 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4081 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4082 [(set (Ty regtype:$Rt), 4083 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4084 ro_Wextend64:$extend)))]>, 4085 Sched<[WriteLDIdx, ReadAdrBase]> { 4086 let Inst{13} = 0b0; 4087 } 4088 4089 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4090 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4091 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4092 [(set (Ty regtype:$Rt), 4093 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4094 ro_Xextend64:$extend)))]>, 4095 Sched<[WriteLDIdx, ReadAdrBase]> { 4096 let Inst{13} = 0b1; 4097 } 4098 4099 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4100} 4101 4102multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4103 string asm, ValueType Ty, SDPatternOperator storeop> { 4104 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4105 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 4106 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4107 [(storeop (Ty regtype:$Rt), 4108 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4109 ro_Wextend64:$extend))]>, 4110 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4111 let Inst{13} = 0b0; 4112 } 4113 4114 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4115 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 4116 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4117 [(storeop (Ty regtype:$Rt), 4118 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4119 ro_Xextend64:$extend))]>, 4120 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4121 let Inst{13} = 0b1; 4122 } 4123 4124 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4125} 4126 4127class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4128 dag outs, list<dag> pat> 4129 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4130 bits<5> Rt; 4131 bits<5> Rn; 4132 bits<5> Rm; 4133 bits<2> extend; 4134 let Inst{31-30} = sz; 4135 let Inst{29-27} = 0b111; 4136 let Inst{26} = V; 4137 let Inst{25-24} = 0b00; 4138 let Inst{23-22} = opc; 4139 let Inst{21} = 1; 4140 let Inst{20-16} = Rm; 4141 let Inst{15} = extend{1}; // sign extend Rm? 4142 let Inst{14} = 1; 4143 let Inst{12} = extend{0}; // do shift? 4144 let Inst{11-10} = 0b10; 4145 let Inst{9-5} = Rn; 4146 let Inst{4-0} = Rt; 4147} 4148 4149multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4150 string asm, ValueType Ty, SDPatternOperator loadop> { 4151 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4152 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4153 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4154 [(set (Ty regtype:$Rt), 4155 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 4156 ro_Wextend128:$extend)))]>, 4157 Sched<[WriteLDIdx, ReadAdrBase]> { 4158 let Inst{13} = 0b0; 4159 } 4160 4161 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4162 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4163 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4164 [(set (Ty regtype:$Rt), 4165 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 4166 ro_Xextend128:$extend)))]>, 4167 Sched<[WriteLDIdx, ReadAdrBase]> { 4168 let Inst{13} = 0b1; 4169 } 4170 4171 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4172} 4173 4174multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4175 string asm> { 4176 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4177 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 4178 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4179 []>, 4180 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4181 let Inst{13} = 0b0; 4182 } 4183 4184 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4185 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 4186 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4187 []>, 4188 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4189 let Inst{13} = 0b1; 4190 } 4191 4192 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4193} 4194 4195let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4196class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 4197 string asm, list<dag> pat> 4198 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 4199 Sched<[WriteLD]> { 4200 bits<5> Rt; 4201 bits<5> Rn; 4202 bits<5> Rm; 4203 bits<2> extend; 4204 let Inst{31-30} = sz; 4205 let Inst{29-27} = 0b111; 4206 let Inst{26} = V; 4207 let Inst{25-24} = 0b00; 4208 let Inst{23-22} = opc; 4209 let Inst{21} = 1; 4210 let Inst{20-16} = Rm; 4211 let Inst{15} = extend{1}; // sign extend Rm? 4212 let Inst{14} = 1; 4213 let Inst{12} = extend{0}; // do shift? 4214 let Inst{11-10} = 0b10; 4215 let Inst{9-5} = Rn; 4216 let Inst{4-0} = Rt; 4217 let DecoderMethod = "DecodePRFMRegInstruction"; 4218 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When 4219 // the decoder method returns Fail, the decoder should attempt to decode the 4220 // instruction as RPRFM. 4221 let hasCompleteDecoder = 0; 4222} 4223 4224multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 4225 def roW : BasePrefetchRO<sz, V, opc, (outs), 4226 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4227 asm, [(AArch64Prefetch timm:$Rt, 4228 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4229 ro_Wextend64:$extend))]> { 4230 let Inst{13} = 0b0; 4231 } 4232 4233 def roX : BasePrefetchRO<sz, V, opc, (outs), 4234 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4235 asm, [(AArch64Prefetch timm:$Rt, 4236 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4237 ro_Xextend64:$extend))]> { 4238 let Inst{13} = 0b1; 4239 } 4240 4241 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 4242 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 4243 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 4244} 4245 4246//--- 4247// Load/store unscaled immediate 4248//--- 4249 4250def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 4251def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 4252def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 4253def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 4254def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 4255 4256def gi_am_unscaled8 : 4257 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 4258 GIComplexPatternEquiv<am_unscaled8>; 4259def gi_am_unscaled16 : 4260 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 4261 GIComplexPatternEquiv<am_unscaled16>; 4262def gi_am_unscaled32 : 4263 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 4264 GIComplexPatternEquiv<am_unscaled32>; 4265def gi_am_unscaled64 : 4266 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 4267 GIComplexPatternEquiv<am_unscaled64>; 4268def gi_am_unscaled128 : 4269 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 4270 GIComplexPatternEquiv<am_unscaled128>; 4271 4272 4273class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4274 string asm, list<dag> pattern> 4275 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 4276 bits<5> Rt; 4277 bits<5> Rn; 4278 bits<9> offset; 4279 let Inst{31-30} = sz; 4280 let Inst{29-27} = 0b111; 4281 let Inst{26} = V; 4282 let Inst{25-24} = 0b00; 4283 let Inst{23-22} = opc; 4284 let Inst{21} = 0; 4285 let Inst{20-12} = offset; 4286 let Inst{11-10} = 0b00; 4287 let Inst{9-5} = Rn; 4288 let Inst{4-0} = Rt; 4289 4290 let DecoderMethod = "DecodeSignedLdStInstruction"; 4291} 4292 4293// Armv8.4 LDAPR & STLR with Immediate Offset instruction 4294multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4295 DAGOperand regtype > { 4296 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 4297 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 4298 Sched<[WriteST]> { 4299 let Inst{29} = 0; 4300 let Inst{24} = 1; 4301 } 4302 def : InstAlias<asm # "\t$Rt, [$Rn]", 4303 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4304} 4305 4306multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4307 DAGOperand regtype > { 4308 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 4309 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4310 asm, []>, 4311 Sched<[WriteST]> { 4312 let Inst{29} = 0; 4313 let Inst{24} = 1; 4314 } 4315 def : InstAlias<asm # "\t$Rt, [$Rn]", 4316 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4317} 4318 4319multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4320 string asm, list<dag> pattern> { 4321 let AddedComplexity = 1 in // try this before LoadUI 4322 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 4323 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 4324 Sched<[WriteLD]>; 4325 4326 def : InstAlias<asm # "\t$Rt, [$Rn]", 4327 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4328} 4329 4330multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4331 string asm, list<dag> pattern> { 4332 let AddedComplexity = 1 in // try this before StoreUI 4333 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4334 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4335 asm, pattern>, 4336 Sched<[WriteST]>; 4337 4338 def : InstAlias<asm # "\t$Rt, [$Rn]", 4339 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4340} 4341 4342multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4343 list<dag> pat> { 4344 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4345 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4346 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4347 asm, pat>, 4348 Sched<[WriteLD]>; 4349 4350 def : InstAlias<asm # "\t$Rt, [$Rn]", 4351 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4352} 4353 4354//--- 4355// Load/store unscaled immediate, unprivileged 4356//--- 4357 4358class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4359 dag oops, dag iops, string asm> 4360 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4361 bits<5> Rt; 4362 bits<5> Rn; 4363 bits<9> offset; 4364 let Inst{31-30} = sz; 4365 let Inst{29-27} = 0b111; 4366 let Inst{26} = V; 4367 let Inst{25-24} = 0b00; 4368 let Inst{23-22} = opc; 4369 let Inst{21} = 0; 4370 let Inst{20-12} = offset; 4371 let Inst{11-10} = 0b10; 4372 let Inst{9-5} = Rn; 4373 let Inst{4-0} = Rt; 4374 4375 let DecoderMethod = "DecodeSignedLdStInstruction"; 4376} 4377 4378multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4379 RegisterClass regtype, string asm> { 4380 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4381 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4382 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4383 Sched<[WriteLD]>; 4384 4385 def : InstAlias<asm # "\t$Rt, [$Rn]", 4386 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4387} 4388 4389multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4390 RegisterClass regtype, string asm> { 4391 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4392 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4393 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4394 asm>, 4395 Sched<[WriteST]>; 4396 4397 def : InstAlias<asm # "\t$Rt, [$Rn]", 4398 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4399} 4400 4401//--- 4402// Load/store pre-indexed 4403//--- 4404 4405class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4406 string asm, string cstr, list<dag> pat> 4407 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4408 bits<5> Rt; 4409 bits<5> Rn; 4410 bits<9> offset; 4411 let Inst{31-30} = sz; 4412 let Inst{29-27} = 0b111; 4413 let Inst{26} = V; 4414 let Inst{25-24} = 0; 4415 let Inst{23-22} = opc; 4416 let Inst{21} = 0; 4417 let Inst{20-12} = offset; 4418 let Inst{11-10} = 0b11; 4419 let Inst{9-5} = Rn; 4420 let Inst{4-0} = Rt; 4421 4422 let DecoderMethod = "DecodeSignedLdStInstruction"; 4423} 4424 4425let hasSideEffects = 0 in { 4426let mayStore = 0, mayLoad = 1 in 4427class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4428 string asm> 4429 : BaseLoadStorePreIdx<sz, V, opc, 4430 (outs GPR64sp:$wback, regtype:$Rt), 4431 (ins GPR64sp:$Rn, simm9:$offset), asm, 4432 "$Rn = $wback,@earlyclobber $wback", []>, 4433 Sched<[WriteAdr, WriteLD]>; 4434 4435let mayStore = 1, mayLoad = 0 in 4436class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4437 string asm, SDPatternOperator storeop, ValueType Ty> 4438 : BaseLoadStorePreIdx<sz, V, opc, 4439 (outs GPR64sp:$wback), 4440 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4441 asm, "$Rn = $wback,@earlyclobber $wback", 4442 [(set GPR64sp:$wback, 4443 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4444 Sched<[WriteAdr, WriteST]>; 4445} // hasSideEffects = 0 4446 4447//--- 4448// Load/store post-indexed 4449//--- 4450 4451class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4452 string asm, string cstr, list<dag> pat> 4453 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4454 bits<5> Rt; 4455 bits<5> Rn; 4456 bits<9> offset; 4457 let Inst{31-30} = sz; 4458 let Inst{29-27} = 0b111; 4459 let Inst{26} = V; 4460 let Inst{25-24} = 0b00; 4461 let Inst{23-22} = opc; 4462 let Inst{21} = 0b0; 4463 let Inst{20-12} = offset; 4464 let Inst{11-10} = 0b01; 4465 let Inst{9-5} = Rn; 4466 let Inst{4-0} = Rt; 4467 4468 let DecoderMethod = "DecodeSignedLdStInstruction"; 4469} 4470 4471let hasSideEffects = 0 in { 4472let mayStore = 0, mayLoad = 1 in 4473class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4474 string asm> 4475 : BaseLoadStorePostIdx<sz, V, opc, 4476 (outs GPR64sp:$wback, regtype:$Rt), 4477 (ins GPR64sp:$Rn, simm9:$offset), 4478 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4479 Sched<[WriteAdr, WriteLD]>; 4480 4481let mayStore = 1, mayLoad = 0 in 4482class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4483 string asm, SDPatternOperator storeop, ValueType Ty> 4484 : BaseLoadStorePostIdx<sz, V, opc, 4485 (outs GPR64sp:$wback), 4486 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4487 asm, "$Rn = $wback,@earlyclobber $wback", 4488 [(set GPR64sp:$wback, 4489 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4490 Sched<[WriteAdr, WriteST]>; 4491} // hasSideEffects = 0 4492 4493 4494//--- 4495// Load/store pair 4496//--- 4497 4498// (indexed, offset) 4499 4500class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4501 string asm> 4502 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4503 bits<5> Rt; 4504 bits<5> Rt2; 4505 bits<5> Rn; 4506 bits<7> offset; 4507 let Inst{31-30} = opc; 4508 let Inst{29-27} = 0b101; 4509 let Inst{26} = V; 4510 let Inst{25-23} = 0b010; 4511 let Inst{22} = L; 4512 let Inst{21-15} = offset; 4513 let Inst{14-10} = Rt2; 4514 let Inst{9-5} = Rn; 4515 let Inst{4-0} = Rt; 4516 4517 let DecoderMethod = "DecodePairLdStInstruction"; 4518} 4519 4520multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4521 Operand indextype, string asm> { 4522 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4523 def i : BaseLoadStorePairOffset<opc, V, 1, 4524 (outs regtype:$Rt, regtype:$Rt2), 4525 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4526 Sched<[WriteLD, WriteLDHi]>; 4527 4528 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4529 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4530 GPR64sp:$Rn, 0)>; 4531} 4532 4533 4534multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4535 Operand indextype, string asm> { 4536 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4537 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4538 (ins regtype:$Rt, regtype:$Rt2, 4539 GPR64sp:$Rn, indextype:$offset), 4540 asm>, 4541 Sched<[WriteSTP]>; 4542 4543 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4544 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4545 GPR64sp:$Rn, 0)>; 4546} 4547 4548// (pre-indexed) 4549class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4550 string asm> 4551 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4552 bits<5> Rt; 4553 bits<5> Rt2; 4554 bits<5> Rn; 4555 bits<7> offset; 4556 let Inst{31-30} = opc; 4557 let Inst{29-27} = 0b101; 4558 let Inst{26} = V; 4559 let Inst{25-23} = 0b011; 4560 let Inst{22} = L; 4561 let Inst{21-15} = offset; 4562 let Inst{14-10} = Rt2; 4563 let Inst{9-5} = Rn; 4564 let Inst{4-0} = Rt; 4565 4566 let DecoderMethod = "DecodePairLdStInstruction"; 4567} 4568 4569let hasSideEffects = 0 in { 4570let mayStore = 0, mayLoad = 1 in 4571class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4572 Operand indextype, string asm> 4573 : BaseLoadStorePairPreIdx<opc, V, 1, 4574 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4575 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4576 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4577 4578let mayStore = 1, mayLoad = 0 in 4579class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4580 Operand indextype, string asm> 4581 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4582 (ins regtype:$Rt, regtype:$Rt2, 4583 GPR64sp:$Rn, indextype:$offset), 4584 asm>, 4585 Sched<[WriteAdr, WriteSTP]>; 4586} // hasSideEffects = 0 4587 4588// (post-indexed) 4589 4590class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4591 string asm> 4592 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4593 bits<5> Rt; 4594 bits<5> Rt2; 4595 bits<5> Rn; 4596 bits<7> offset; 4597 let Inst{31-30} = opc; 4598 let Inst{29-27} = 0b101; 4599 let Inst{26} = V; 4600 let Inst{25-23} = 0b001; 4601 let Inst{22} = L; 4602 let Inst{21-15} = offset; 4603 let Inst{14-10} = Rt2; 4604 let Inst{9-5} = Rn; 4605 let Inst{4-0} = Rt; 4606 4607 let DecoderMethod = "DecodePairLdStInstruction"; 4608} 4609 4610let hasSideEffects = 0 in { 4611let mayStore = 0, mayLoad = 1 in 4612class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4613 Operand idxtype, string asm> 4614 : BaseLoadStorePairPostIdx<opc, V, 1, 4615 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4616 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4617 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4618 4619let mayStore = 1, mayLoad = 0 in 4620class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4621 Operand idxtype, string asm> 4622 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4623 (ins regtype:$Rt, regtype:$Rt2, 4624 GPR64sp:$Rn, idxtype:$offset), 4625 asm>, 4626 Sched<[WriteAdr, WriteSTP]>; 4627} // hasSideEffects = 0 4628 4629// (no-allocate) 4630 4631class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4632 string asm> 4633 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4634 bits<5> Rt; 4635 bits<5> Rt2; 4636 bits<5> Rn; 4637 bits<7> offset; 4638 let Inst{31-30} = opc; 4639 let Inst{29-27} = 0b101; 4640 let Inst{26} = V; 4641 let Inst{25-23} = 0b000; 4642 let Inst{22} = L; 4643 let Inst{21-15} = offset; 4644 let Inst{14-10} = Rt2; 4645 let Inst{9-5} = Rn; 4646 let Inst{4-0} = Rt; 4647 4648 let DecoderMethod = "DecodePairLdStInstruction"; 4649} 4650 4651multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4652 Operand indextype, string asm> { 4653 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4654 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4655 (outs regtype:$Rt, regtype:$Rt2), 4656 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4657 Sched<[WriteLD, WriteLDHi]>; 4658 4659 4660 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4661 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4662 GPR64sp:$Rn, 0)>; 4663} 4664 4665multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4666 Operand indextype, string asm> { 4667 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4668 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4669 (ins regtype:$Rt, regtype:$Rt2, 4670 GPR64sp:$Rn, indextype:$offset), 4671 asm>, 4672 Sched<[WriteSTP]>; 4673 4674 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4675 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4676 GPR64sp:$Rn, 0)>; 4677} 4678 4679//--- 4680// Load/store exclusive 4681//--- 4682 4683// True exclusive operations write to and/or read from the system's exclusive 4684// monitors, which as far as a compiler is concerned can be modelled as a 4685// random shared memory address. Hence LoadExclusive mayStore. 4686// 4687// Since these instructions have the undefined register bits set to 1 in 4688// their canonical form, we need a post encoder method to set those bits 4689// to 1 when encoding these instructions. We do this using the 4690// fixLoadStoreExclusive function. This function has template parameters: 4691// 4692// fixLoadStoreExclusive<int hasRs, int hasRt2> 4693// 4694// hasRs indicates that the instruction uses the Rs field, so we won't set 4695// it to 1 (and the same for Rt2). We don't need template parameters for 4696// the other register fields since Rt and Rn are always used. 4697// 4698let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4699class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4700 dag oops, dag iops, string asm, string operands> 4701 : I<oops, iops, asm, operands, "", []> { 4702 let Inst{31-30} = sz; 4703 let Inst{29-24} = 0b001000; 4704 let Inst{23} = o2; 4705 let Inst{22} = L; 4706 let Inst{21} = o1; 4707 let Inst{15} = o0; 4708 4709 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4710} 4711 4712// Neither Rs nor Rt2 operands. 4713class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4714 dag oops, dag iops, string asm, string operands> 4715 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4716 bits<5> Rt; 4717 bits<5> Rn; 4718 let Inst{20-16} = 0b11111; 4719 let Unpredictable{20-16} = 0b11111; 4720 let Inst{14-10} = 0b11111; 4721 let Unpredictable{14-10} = 0b11111; 4722 let Inst{9-5} = Rn; 4723 let Inst{4-0} = Rt; 4724 4725 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4726} 4727 4728// Simple load acquires don't set the exclusive monitor 4729let mayLoad = 1, mayStore = 0 in 4730class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4731 RegisterClass regtype, string asm> 4732 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4733 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4734 Sched<[WriteLD]>; 4735 4736class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4737 RegisterClass regtype, string asm> 4738 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4739 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4740 Sched<[WriteLD]>; 4741 4742class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4743 RegisterClass regtype, string asm> 4744 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4745 (outs regtype:$Rt, regtype:$Rt2), 4746 (ins GPR64sp0:$Rn), asm, 4747 "\t$Rt, $Rt2, [$Rn]">, 4748 Sched<[WriteLD, WriteLDHi]> { 4749 bits<5> Rt; 4750 bits<5> Rt2; 4751 bits<5> Rn; 4752 let Inst{14-10} = Rt2; 4753 let Inst{9-5} = Rn; 4754 let Inst{4-0} = Rt; 4755 4756 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4757} 4758 4759// Simple store release operations do not check the exclusive monitor. 4760let mayLoad = 0, mayStore = 1 in 4761class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4762 RegisterClass regtype, string asm> 4763 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4764 (ins regtype:$Rt, GPR64sp:$Rn), 4765 asm, "\t$Rt, [$Rn]">, 4766 Sched<[WriteST]>; 4767 4768let mayLoad = 1, mayStore = 1 in 4769class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4770 RegisterClass regtype, string asm> 4771 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4772 (ins regtype:$Rt, GPR64sp0:$Rn), 4773 asm, "\t$Ws, $Rt, [$Rn]">, 4774 Sched<[WriteSTX]> { 4775 bits<5> Ws; 4776 bits<5> Rt; 4777 bits<5> Rn; 4778 let Inst{20-16} = Ws; 4779 let Inst{9-5} = Rn; 4780 let Inst{4-0} = Rt; 4781 4782 let Constraints = "@earlyclobber $Ws"; 4783 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4784} 4785 4786class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4787 RegisterClass regtype, string asm> 4788 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4789 (outs GPR32:$Ws), 4790 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4791 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4792 Sched<[WriteSTX]> { 4793 bits<5> Ws; 4794 bits<5> Rt; 4795 bits<5> Rt2; 4796 bits<5> Rn; 4797 let Inst{20-16} = Ws; 4798 let Inst{14-10} = Rt2; 4799 let Inst{9-5} = Rn; 4800 let Inst{4-0} = Rt; 4801 4802 let Constraints = "@earlyclobber $Ws"; 4803} 4804 4805// Armv8.5-A Memory Tagging Extension 4806class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4807 string asm_opnds, string cstr, dag oops, dag iops> 4808 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4809 Sched<[]> { 4810 bits<5> Rn; 4811 4812 let Inst{31-24} = 0b11011001; 4813 let Inst{23-22} = opc1; 4814 let Inst{21} = 1; 4815 // Inst{20-12} defined by subclass 4816 let Inst{11-10} = opc2; 4817 let Inst{9-5} = Rn; 4818 // Inst{4-0} defined by subclass 4819} 4820 4821class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4822 dag oops, dag iops> 4823 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4824 "", oops, iops> { 4825 bits<5> Rt; 4826 4827 let Inst{20-12} = 0b000000000; 4828 let Inst{4-0} = Rt; 4829 4830 let mayLoad = Load; 4831} 4832 4833class MemTagLoad<string asm_insn, string asm_opnds> 4834 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4835 (outs GPR64:$wback), 4836 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4837 bits<5> Rt; 4838 bits<9> offset; 4839 4840 let Inst{20-12} = offset; 4841 let Inst{4-0} = Rt; 4842 4843 let mayLoad = 1; 4844} 4845 4846class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4847 string asm_opnds, string cstr, dag oops, dag iops> 4848 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4849 bits<5> Rt; 4850 bits<9> offset; 4851 4852 let Inst{20-12} = offset; 4853 let Inst{4-0} = Rt; 4854 4855 let mayStore = 1; 4856} 4857 4858multiclass MemTagStore<bits<2> opc1, string insn> { 4859 def i : 4860 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4861 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4862 def PreIndex : 4863 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4864 "$Rn = $wback", 4865 (outs GPR64sp:$wback), 4866 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4867 def PostIndex : 4868 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4869 "$Rn = $wback", 4870 (outs GPR64sp:$wback), 4871 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4872 4873 def : InstAlias<insn # "\t$Rt, [$Rn]", 4874 (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4875} 4876 4877//--- 4878// Exception generation 4879//--- 4880 4881let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4882class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4883 list<dag> pattern = []> 4884 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4885 Sched<[WriteSys]> { 4886 bits<16> imm; 4887 let Inst{31-24} = 0b11010100; 4888 let Inst{23-21} = op1; 4889 let Inst{20-5} = imm; 4890 let Inst{4-2} = 0b000; 4891 let Inst{1-0} = ll; 4892} 4893 4894//--- 4895// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4896//-- 4897let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4898class UDFType<bits<16> opc, string asm> 4899 : I<(outs), (ins uimm16:$imm), 4900 asm, "\t$imm", "", []>, 4901 Sched<[]> { 4902 bits<16> imm; 4903 let Inst{31-16} = opc; 4904 let Inst{15-0} = imm; 4905} 4906} 4907let Predicates = [HasFPARMv8] in { 4908 4909//--- 4910// Floating point to integer conversion 4911//--- 4912 4913let mayRaiseFPException = 1, Uses = [FPCR] in 4914class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4915 RegisterClass srcType, RegisterClass dstType, 4916 string asm, list<dag> pattern> 4917 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4918 asm, "\t$Rd, $Rn", "", pattern>, 4919 Sched<[WriteFCvt]> { 4920 bits<5> Rd; 4921 bits<5> Rn; 4922 let Inst{30-29} = 0b00; 4923 let Inst{28-24} = 0b11110; 4924 let Inst{23-22} = type; 4925 let Inst{21} = 1; 4926 let Inst{20-19} = rmode; 4927 let Inst{18-16} = opcode; 4928 let Inst{15-10} = 0; 4929 let Inst{9-5} = Rn; 4930 let Inst{4-0} = Rd; 4931} 4932 4933let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4934class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4935 RegisterClass srcType, RegisterClass dstType, 4936 Operand immType, string asm, list<dag> pattern> 4937 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4938 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4939 Sched<[WriteFCvt]> { 4940 bits<5> Rd; 4941 bits<5> Rn; 4942 bits<6> scale; 4943 let Inst{30-29} = 0b00; 4944 let Inst{28-24} = 0b11110; 4945 let Inst{23-22} = type; 4946 let Inst{21} = 0; 4947 let Inst{20-19} = rmode; 4948 let Inst{18-16} = opcode; 4949 let Inst{15-10} = scale; 4950 let Inst{9-5} = Rn; 4951 let Inst{4-0} = Rd; 4952} 4953 4954multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4955 SDPatternOperator OpN> { 4956 // Unscaled half-precision to 32-bit 4957 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4958 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4959 let Inst{31} = 0; // 32-bit GPR flag 4960 let Predicates = [HasFullFP16]; 4961 } 4962 4963 // Unscaled half-precision to 64-bit 4964 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4965 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4966 let Inst{31} = 1; // 64-bit GPR flag 4967 let Predicates = [HasFullFP16]; 4968 } 4969 4970 // Unscaled single-precision to 32-bit 4971 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4972 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4973 let Inst{31} = 0; // 32-bit GPR flag 4974 } 4975 4976 // Unscaled single-precision to 64-bit 4977 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4978 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4979 let Inst{31} = 1; // 64-bit GPR flag 4980 } 4981 4982 // Unscaled double-precision to 32-bit 4983 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4984 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4985 let Inst{31} = 0; // 32-bit GPR flag 4986 } 4987 4988 // Unscaled double-precision to 64-bit 4989 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4990 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4991 let Inst{31} = 1; // 64-bit GPR flag 4992 } 4993} 4994 4995multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4996 SDPatternOperator OpN> { 4997 // Scaled half-precision to 32-bit 4998 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4999 fixedpoint_f16_i32, asm, 5000 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 5001 fixedpoint_f16_i32:$scale)))]> { 5002 let Inst{31} = 0; // 32-bit GPR flag 5003 let scale{5} = 1; 5004 let Predicates = [HasFullFP16]; 5005 } 5006 5007 // Scaled half-precision to 64-bit 5008 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 5009 fixedpoint_f16_i64, asm, 5010 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 5011 fixedpoint_f16_i64:$scale)))]> { 5012 let Inst{31} = 1; // 64-bit GPR flag 5013 let Predicates = [HasFullFP16]; 5014 } 5015 5016 // Scaled single-precision to 32-bit 5017 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 5018 fixedpoint_f32_i32, asm, 5019 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 5020 fixedpoint_f32_i32:$scale)))]> { 5021 let Inst{31} = 0; // 32-bit GPR flag 5022 let scale{5} = 1; 5023 } 5024 5025 // Scaled single-precision to 64-bit 5026 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 5027 fixedpoint_f32_i64, asm, 5028 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 5029 fixedpoint_f32_i64:$scale)))]> { 5030 let Inst{31} = 1; // 64-bit GPR flag 5031 } 5032 5033 // Scaled double-precision to 32-bit 5034 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 5035 fixedpoint_f64_i32, asm, 5036 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 5037 fixedpoint_f64_i32:$scale)))]> { 5038 let Inst{31} = 0; // 32-bit GPR flag 5039 let scale{5} = 1; 5040 } 5041 5042 // Scaled double-precision to 64-bit 5043 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 5044 fixedpoint_f64_i64, asm, 5045 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 5046 fixedpoint_f64_i64:$scale)))]> { 5047 let Inst{31} = 1; // 64-bit GPR flag 5048 } 5049} 5050 5051//--- 5052// Integer to floating point conversion 5053//--- 5054 5055let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5056class BaseIntegerToFP<bit isUnsigned, 5057 RegisterClass srcType, RegisterClass dstType, 5058 Operand immType, string asm, list<dag> pattern> 5059 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 5060 asm, "\t$Rd, $Rn, $scale", "", pattern>, 5061 Sched<[WriteFCvt]> { 5062 bits<5> Rd; 5063 bits<5> Rn; 5064 bits<6> scale; 5065 let Inst{30-24} = 0b0011110; 5066 let Inst{21-17} = 0b00001; 5067 let Inst{16} = isUnsigned; 5068 let Inst{15-10} = scale; 5069 let Inst{9-5} = Rn; 5070 let Inst{4-0} = Rd; 5071} 5072 5073let mayRaiseFPException = 1, Uses = [FPCR] in 5074class BaseIntegerToFPUnscaled<bit isUnsigned, 5075 RegisterClass srcType, RegisterClass dstType, 5076 ValueType dvt, string asm, SDPatternOperator node> 5077 : I<(outs dstType:$Rd), (ins srcType:$Rn), 5078 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 5079 Sched<[WriteFCvt]> { 5080 bits<5> Rd; 5081 bits<5> Rn; 5082 bits<6> scale; 5083 let Inst{30-24} = 0b0011110; 5084 let Inst{21-17} = 0b10001; 5085 let Inst{16} = isUnsigned; 5086 let Inst{15-10} = 0b000000; 5087 let Inst{9-5} = Rn; 5088 let Inst{4-0} = Rd; 5089} 5090 5091multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 5092 // Unscaled 5093 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 5094 let Inst{31} = 0; // 32-bit GPR flag 5095 let Inst{23-22} = 0b11; // 16-bit FPR flag 5096 let Predicates = [HasFullFP16]; 5097 } 5098 5099 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 5100 let Inst{31} = 0; // 32-bit GPR flag 5101 let Inst{23-22} = 0b00; // 32-bit FPR flag 5102 } 5103 5104 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 5105 let Inst{31} = 0; // 32-bit GPR flag 5106 let Inst{23-22} = 0b01; // 64-bit FPR flag 5107 } 5108 5109 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 5110 let Inst{31} = 1; // 64-bit GPR flag 5111 let Inst{23-22} = 0b11; // 16-bit FPR flag 5112 let Predicates = [HasFullFP16]; 5113 } 5114 5115 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 5116 let Inst{31} = 1; // 64-bit GPR flag 5117 let Inst{23-22} = 0b00; // 32-bit FPR flag 5118 } 5119 5120 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 5121 let Inst{31} = 1; // 64-bit GPR flag 5122 let Inst{23-22} = 0b01; // 64-bit FPR flag 5123 } 5124 5125 // Scaled 5126 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_recip_f16_i32, asm, 5127 [(set (f16 FPR16:$Rd), 5128 (fmul (node GPR32:$Rn), 5129 fixedpoint_recip_f16_i32:$scale))]> { 5130 let Inst{31} = 0; // 32-bit GPR flag 5131 let Inst{23-22} = 0b11; // 16-bit FPR flag 5132 let scale{5} = 1; 5133 let Predicates = [HasFullFP16]; 5134 } 5135 5136 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_recip_f32_i32, asm, 5137 [(set FPR32:$Rd, 5138 (fmul (node GPR32:$Rn), 5139 fixedpoint_recip_f32_i32:$scale))]> { 5140 let Inst{31} = 0; // 32-bit GPR flag 5141 let Inst{23-22} = 0b00; // 32-bit FPR flag 5142 let scale{5} = 1; 5143 } 5144 5145 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_recip_f64_i32, asm, 5146 [(set FPR64:$Rd, 5147 (fmul (node GPR32:$Rn), 5148 fixedpoint_recip_f64_i32:$scale))]> { 5149 let Inst{31} = 0; // 32-bit GPR flag 5150 let Inst{23-22} = 0b01; // 64-bit FPR flag 5151 let scale{5} = 1; 5152 } 5153 5154 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_recip_f16_i64, asm, 5155 [(set (f16 FPR16:$Rd), 5156 (fmul (node GPR64:$Rn), 5157 fixedpoint_recip_f16_i64:$scale))]> { 5158 let Inst{31} = 1; // 64-bit GPR flag 5159 let Inst{23-22} = 0b11; // 16-bit FPR flag 5160 let Predicates = [HasFullFP16]; 5161 } 5162 5163 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_recip_f32_i64, asm, 5164 [(set FPR32:$Rd, 5165 (fmul (node GPR64:$Rn), 5166 fixedpoint_recip_f32_i64:$scale))]> { 5167 let Inst{31} = 1; // 64-bit GPR flag 5168 let Inst{23-22} = 0b00; // 32-bit FPR flag 5169 } 5170 5171 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_recip_f64_i64, asm, 5172 [(set FPR64:$Rd, 5173 (fmul (node GPR64:$Rn), 5174 fixedpoint_recip_f64_i64:$scale))]> { 5175 let Inst{31} = 1; // 64-bit GPR flag 5176 let Inst{23-22} = 0b01; // 64-bit FPR flag 5177 } 5178} 5179 5180//--- 5181// Unscaled integer <-> floating point conversion (i.e. FMOV) 5182//--- 5183 5184let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5185class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 5186 RegisterClass srcType, RegisterClass dstType, 5187 string asm> 5188 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 5189 // We use COPY_TO_REGCLASS for these bitconvert operations. 5190 // copyPhysReg() expands the resultant COPY instructions after 5191 // regalloc is done. This gives greater freedom for the allocator 5192 // and related passes (coalescing, copy propagation, et. al.) to 5193 // be more effective. 5194 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 5195 Sched<[WriteFCopy]> { 5196 bits<5> Rd; 5197 bits<5> Rn; 5198 let Inst{30-24} = 0b0011110; 5199 let Inst{21} = 1; 5200 let Inst{20-19} = rmode; 5201 let Inst{18-16} = opcode; 5202 let Inst{15-10} = 0b000000; 5203 let Inst{9-5} = Rn; 5204 let Inst{4-0} = Rd; 5205} 5206 5207let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5208class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 5209 RegisterClass srcType, RegisterOperand dstType, string asm, 5210 string kind> 5211 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5212 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 5213 Sched<[WriteFCopy]> { 5214 bits<5> Rd; 5215 bits<5> Rn; 5216 let Inst{30-23} = 0b00111101; 5217 let Inst{21} = 1; 5218 let Inst{20-19} = rmode; 5219 let Inst{18-16} = opcode; 5220 let Inst{15-10} = 0b000000; 5221 let Inst{9-5} = Rn; 5222 let Inst{4-0} = Rd; 5223 5224 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5225} 5226 5227let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5228class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 5229 RegisterOperand srcType, RegisterClass dstType, string asm, 5230 string kind> 5231 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5232 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 5233 Sched<[WriteFCopy]> { 5234 bits<5> Rd; 5235 bits<5> Rn; 5236 let Inst{30-23} = 0b00111101; 5237 let Inst{21} = 1; 5238 let Inst{20-19} = rmode; 5239 let Inst{18-16} = opcode; 5240 let Inst{15-10} = 0b000000; 5241 let Inst{9-5} = Rn; 5242 let Inst{4-0} = Rd; 5243 5244 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5245} 5246 5247 5248multiclass UnscaledConversion<string asm> { 5249 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 5250 let Inst{31} = 0; // 32-bit GPR flag 5251 let Inst{23-22} = 0b11; // 16-bit FPR flag 5252 let Predicates = [HasFullFP16]; 5253 } 5254 5255 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 5256 let Inst{31} = 1; // 64-bit GPR flag 5257 let Inst{23-22} = 0b11; // 16-bit FPR flag 5258 let Predicates = [HasFullFP16]; 5259 } 5260 5261 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 5262 let Inst{31} = 0; // 32-bit GPR flag 5263 let Inst{23-22} = 0b00; // 32-bit FPR flag 5264 } 5265 5266 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 5267 let Inst{31} = 1; // 64-bit GPR flag 5268 let Inst{23-22} = 0b01; // 64-bit FPR flag 5269 } 5270 5271 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 5272 let Inst{31} = 0; // 32-bit GPR flag 5273 let Inst{23-22} = 0b11; // 16-bit FPR flag 5274 let Predicates = [HasFullFP16]; 5275 } 5276 5277 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 5278 let Inst{31} = 1; // 64-bit GPR flag 5279 let Inst{23-22} = 0b11; // 16-bit FPR flag 5280 let Predicates = [HasFullFP16]; 5281 } 5282 5283 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 5284 let Inst{31} = 0; // 32-bit GPR flag 5285 let Inst{23-22} = 0b00; // 32-bit FPR flag 5286 } 5287 5288 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 5289 let Inst{31} = 1; // 64-bit GPR flag 5290 let Inst{23-22} = 0b01; // 64-bit FPR flag 5291 } 5292 5293 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 5294 asm, ".d"> { 5295 let Inst{31} = 1; 5296 let Inst{22} = 0; 5297 } 5298 5299 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 5300 asm, ".d"> { 5301 let Inst{31} = 1; 5302 let Inst{22} = 0; 5303 } 5304} 5305 5306//--- 5307// Floating point conversion 5308//--- 5309 5310let mayRaiseFPException = 1, Uses = [FPCR] in 5311class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 5312 RegisterClass srcType, string asm, list<dag> pattern> 5313 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 5314 Sched<[WriteFCvt]> { 5315 bits<5> Rd; 5316 bits<5> Rn; 5317 let Inst{31-24} = 0b00011110; 5318 let Inst{23-22} = type; 5319 let Inst{21-17} = 0b10001; 5320 let Inst{16-15} = opcode; 5321 let Inst{14-10} = 0b10000; 5322 let Inst{9-5} = Rn; 5323 let Inst{4-0} = Rd; 5324} 5325 5326multiclass FPConversion<string asm> { 5327 // Double-precision to Half-precision 5328 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 5329 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 5330 5331 // Double-precision to Single-precision 5332 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 5333 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5334 5335 // Half-precision to Double-precision 5336 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5337 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5338 5339 // Half-precision to Single-precision 5340 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5341 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5342 5343 // Single-precision to Double-precision 5344 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5345 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5346 5347 // Single-precision to Half-precision 5348 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5349 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5350} 5351 5352//--- 5353// Single operand floating point data processing 5354//--- 5355 5356let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5357class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5358 ValueType vt, string asm, SDPatternOperator node> 5359 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5360 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5361 Sched<[WriteF]> { 5362 bits<5> Rd; 5363 bits<5> Rn; 5364 let Inst{31-24} = 0b00011110; 5365 let Inst{21} = 0b1; 5366 let Inst{20-15} = opcode; 5367 let Inst{14-10} = 0b10000; 5368 let Inst{9-5} = Rn; 5369 let Inst{4-0} = Rd; 5370} 5371 5372multiclass SingleOperandFPData<bits<4> opcode, string asm, 5373 SDPatternOperator node = null_frag, 5374 int fpexceptions = 1> { 5375 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 5376 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5377 let Inst{23-22} = 0b11; // 16-bit size flag 5378 let Predicates = [HasFullFP16]; 5379 } 5380 5381 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5382 let Inst{23-22} = 0b00; // 32-bit size flag 5383 } 5384 5385 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5386 let Inst{23-22} = 0b01; // 64-bit size flag 5387 } 5388 } 5389} 5390 5391multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5392 SDPatternOperator node = null_frag> 5393 : SingleOperandFPData<opcode, asm, node, 0>; 5394 5395let mayRaiseFPException = 1, Uses = [FPCR] in 5396multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5397 SDPatternOperator node = null_frag>{ 5398 5399 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5400 let Inst{23-22} = 0b00; // 32-bit registers 5401 } 5402 5403 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5404 let Inst{23-22} = 0b01; // 64-bit registers 5405 } 5406} 5407 5408// FRInt[32|64][Z|N] instructions 5409multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5410 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5411 5412//--- 5413// Two operand floating point data processing 5414//--- 5415 5416let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5417class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5418 string asm, list<dag> pat> 5419 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5420 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5421 Sched<[WriteF]> { 5422 bits<5> Rd; 5423 bits<5> Rn; 5424 bits<5> Rm; 5425 let Inst{31-24} = 0b00011110; 5426 let Inst{21} = 1; 5427 let Inst{20-16} = Rm; 5428 let Inst{15-12} = opcode; 5429 let Inst{11-10} = 0b10; 5430 let Inst{9-5} = Rn; 5431 let Inst{4-0} = Rd; 5432} 5433 5434multiclass TwoOperandFPData<bits<4> opcode, string asm, 5435 SDPatternOperator node = null_frag> { 5436 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5437 [(set (f16 FPR16:$Rd), 5438 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5439 let Inst{23-22} = 0b11; // 16-bit size flag 5440 let Predicates = [HasFullFP16]; 5441 } 5442 5443 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5444 [(set (f32 FPR32:$Rd), 5445 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5446 let Inst{23-22} = 0b00; // 32-bit size flag 5447 } 5448 5449 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5450 [(set (f64 FPR64:$Rd), 5451 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5452 let Inst{23-22} = 0b01; // 64-bit size flag 5453 } 5454} 5455 5456multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5457 SDPatternOperator node> { 5458 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5459 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5460 let Inst{23-22} = 0b11; // 16-bit size flag 5461 let Predicates = [HasFullFP16]; 5462 } 5463 5464 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5465 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5466 let Inst{23-22} = 0b00; // 32-bit size flag 5467 } 5468 5469 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5470 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5471 let Inst{23-22} = 0b01; // 64-bit size flag 5472 } 5473} 5474 5475 5476//--- 5477// Three operand floating point data processing 5478//--- 5479 5480let mayRaiseFPException = 1, Uses = [FPCR] in 5481class BaseThreeOperandFPData<bit isNegated, bit isSub, 5482 RegisterClass regtype, string asm, list<dag> pat> 5483 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5484 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5485 Sched<[WriteFMul]> { 5486 bits<5> Rd; 5487 bits<5> Rn; 5488 bits<5> Rm; 5489 bits<5> Ra; 5490 let Inst{31-24} = 0b00011111; 5491 let Inst{21} = isNegated; 5492 let Inst{20-16} = Rm; 5493 let Inst{15} = isSub; 5494 let Inst{14-10} = Ra; 5495 let Inst{9-5} = Rn; 5496 let Inst{4-0} = Rd; 5497} 5498 5499multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5500 SDPatternOperator node> { 5501 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5502 [(set (f16 FPR16:$Rd), 5503 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5504 let Inst{23-22} = 0b11; // 16-bit size flag 5505 let Predicates = [HasFullFP16]; 5506 } 5507 5508 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5509 [(set FPR32:$Rd, 5510 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5511 let Inst{23-22} = 0b00; // 32-bit size flag 5512 } 5513 5514 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5515 [(set FPR64:$Rd, 5516 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5517 let Inst{23-22} = 0b01; // 64-bit size flag 5518 } 5519 5520 let Predicates = [HasFullFP16] in { 5521 def : Pat<(f16 (node (f16 FPR16:$Rn), 5522 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))), 5523 (f16 FPR16:$Ra))), 5524 (!cast<Instruction>(NAME # Hrrr) 5525 FPR16:$Rn, (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>; 5526 5527 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))), 5528 (f16 FPR16:$Rm), 5529 (f16 FPR16:$Ra))), 5530 (!cast<Instruction>(NAME # Hrrr) 5531 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>; 5532 } 5533 5534 def : Pat<(f32 (node (f32 FPR32:$Rn), 5535 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))), 5536 (f32 FPR32:$Ra))), 5537 (!cast<Instruction>(NAME # Srrr) 5538 FPR32:$Rn, (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>; 5539 5540 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))), 5541 (f32 FPR32:$Rm), 5542 (f32 FPR32:$Ra))), 5543 (!cast<Instruction>(NAME # Srrr) 5544 (EXTRACT_SUBREG V128:$Rn, ssub), FPR32:$Rm, FPR32:$Ra)>; 5545 5546 def : Pat<(f64 (node (f64 FPR64:$Rn), 5547 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))), 5548 (f64 FPR64:$Ra))), 5549 (!cast<Instruction>(NAME # Drrr) 5550 FPR64:$Rn, (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>; 5551 5552 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))), 5553 (f64 FPR64:$Rm), 5554 (f64 FPR64:$Ra))), 5555 (!cast<Instruction>(NAME # Drrr) 5556 (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>; 5557} 5558 5559//--- 5560// Floating point data comparisons 5561//--- 5562 5563let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5564class BaseOneOperandFPComparison<bit signalAllNans, 5565 RegisterClass regtype, string asm, 5566 list<dag> pat> 5567 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5568 Sched<[WriteFCmp]> { 5569 bits<5> Rn; 5570 let Inst{31-24} = 0b00011110; 5571 let Inst{21} = 1; 5572 5573 let Inst{15-10} = 0b001000; 5574 let Inst{9-5} = Rn; 5575 let Inst{4} = signalAllNans; 5576 let Inst{3-0} = 0b1000; 5577 5578 // Rm should be 0b00000 canonically, but we need to accept any value. 5579 let PostEncoderMethod = "fixOneOperandFPComparison"; 5580} 5581 5582let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5583class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5584 string asm, list<dag> pat> 5585 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5586 Sched<[WriteFCmp]> { 5587 bits<5> Rm; 5588 bits<5> Rn; 5589 let Inst{31-24} = 0b00011110; 5590 let Inst{21} = 1; 5591 let Inst{20-16} = Rm; 5592 let Inst{15-10} = 0b001000; 5593 let Inst{9-5} = Rn; 5594 let Inst{4} = signalAllNans; 5595 let Inst{3-0} = 0b0000; 5596} 5597 5598multiclass FPComparison<bit signalAllNans, string asm, 5599 SDPatternOperator OpNode = null_frag> { 5600 let Defs = [NZCV] in { 5601 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5602 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5603 let Inst{23-22} = 0b11; 5604 let Predicates = [HasFullFP16]; 5605 } 5606 5607 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5608 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5609 let Inst{23-22} = 0b11; 5610 let Predicates = [HasFullFP16]; 5611 } 5612 5613 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5614 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5615 let Inst{23-22} = 0b00; 5616 } 5617 5618 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5619 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5620 let Inst{23-22} = 0b00; 5621 } 5622 5623 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5624 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5625 let Inst{23-22} = 0b01; 5626 } 5627 5628 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5629 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5630 let Inst{23-22} = 0b01; 5631 } 5632 } // Defs = [NZCV] 5633} 5634 5635//--- 5636// Floating point conditional comparisons 5637//--- 5638 5639let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5640class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5641 string mnemonic, list<dag> pat> 5642 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5643 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5644 Sched<[WriteFCmp]> { 5645 let Uses = [NZCV]; 5646 let Defs = [NZCV]; 5647 5648 bits<5> Rn; 5649 bits<5> Rm; 5650 bits<4> nzcv; 5651 bits<4> cond; 5652 5653 let Inst{31-24} = 0b00011110; 5654 let Inst{21} = 1; 5655 let Inst{20-16} = Rm; 5656 let Inst{15-12} = cond; 5657 let Inst{11-10} = 0b01; 5658 let Inst{9-5} = Rn; 5659 let Inst{4} = signalAllNans; 5660 let Inst{3-0} = nzcv; 5661} 5662 5663multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5664 SDPatternOperator OpNode = null_frag> { 5665 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5666 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5667 (i32 imm:$cond), NZCV))]> { 5668 let Inst{23-22} = 0b11; 5669 let Predicates = [HasFullFP16]; 5670 } 5671 5672 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5673 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5674 (i32 imm:$cond), NZCV))]> { 5675 let Inst{23-22} = 0b00; 5676 } 5677 5678 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5679 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5680 (i32 imm:$cond), NZCV))]> { 5681 let Inst{23-22} = 0b01; 5682 } 5683} 5684 5685//--- 5686// Floating point conditional select 5687//--- 5688 5689class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5690 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5691 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5692 [(set regtype:$Rd, 5693 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5694 (i32 imm:$cond), NZCV))]>, 5695 Sched<[WriteF]> { 5696 bits<5> Rd; 5697 bits<5> Rn; 5698 bits<5> Rm; 5699 bits<4> cond; 5700 5701 let Inst{31-24} = 0b00011110; 5702 let Inst{21} = 1; 5703 let Inst{20-16} = Rm; 5704 let Inst{15-12} = cond; 5705 let Inst{11-10} = 0b11; 5706 let Inst{9-5} = Rn; 5707 let Inst{4-0} = Rd; 5708} 5709 5710multiclass FPCondSelect<string asm> { 5711 let Uses = [NZCV] in { 5712 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5713 let Inst{23-22} = 0b11; 5714 let Predicates = [HasFullFP16]; 5715 } 5716 5717 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5718 let Inst{23-22} = 0b00; 5719 } 5720 5721 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5722 let Inst{23-22} = 0b01; 5723 } 5724 } // Uses = [NZCV] 5725} 5726 5727//--- 5728// Floating move immediate 5729//--- 5730 5731class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5732 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5733 [(set regtype:$Rd, fpimmtype:$imm)]>, 5734 Sched<[WriteFImm]> { 5735 bits<5> Rd; 5736 bits<8> imm; 5737 let Inst{31-24} = 0b00011110; 5738 let Inst{21} = 1; 5739 let Inst{20-13} = imm; 5740 let Inst{12-5} = 0b10000000; 5741 let Inst{4-0} = Rd; 5742} 5743 5744multiclass FPMoveImmediate<string asm> { 5745 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5746 let Inst{23-22} = 0b11; 5747 let Predicates = [HasFullFP16]; 5748 } 5749 5750 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5751 let Inst{23-22} = 0b00; 5752 } 5753 5754 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5755 let Inst{23-22} = 0b01; 5756 } 5757} 5758} // end of 'let Predicates = [HasFPARMv8]' 5759 5760//---------------------------------------------------------------------------- 5761// AdvSIMD 5762//---------------------------------------------------------------------------- 5763 5764let Predicates = [HasNEON] in { 5765 5766//---------------------------------------------------------------------------- 5767// AdvSIMD three register vector instructions 5768//---------------------------------------------------------------------------- 5769 5770let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5771class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5772 RegisterOperand regtype, string asm, string kind, 5773 list<dag> pattern> 5774 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5775 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5776 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5777 Sched<[!if(Q, WriteVq, WriteVd)]> { 5778 bits<5> Rd; 5779 bits<5> Rn; 5780 bits<5> Rm; 5781 let Inst{31} = 0; 5782 let Inst{30} = Q; 5783 let Inst{29} = U; 5784 let Inst{28-24} = 0b01110; 5785 let Inst{23-21} = size; 5786 let Inst{20-16} = Rm; 5787 let Inst{15-11} = opcode; 5788 let Inst{10} = 1; 5789 let Inst{9-5} = Rn; 5790 let Inst{4-0} = Rd; 5791} 5792 5793let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5794class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5795 RegisterOperand regtype, string asm, string kind, 5796 list<dag> pattern> 5797 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5798 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5799 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5800 Sched<[!if(Q, WriteVq, WriteVd)]> { 5801 bits<5> Rd; 5802 bits<5> Rn; 5803 bits<5> Rm; 5804 let Inst{31} = 0; 5805 let Inst{30} = Q; 5806 let Inst{29} = U; 5807 let Inst{28-24} = 0b01110; 5808 let Inst{23-21} = size; 5809 let Inst{20-16} = Rm; 5810 let Inst{15-11} = opcode; 5811 let Inst{10} = 1; 5812 let Inst{9-5} = Rn; 5813 let Inst{4-0} = Rd; 5814} 5815 5816let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5817class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5818 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5819 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5820 5821multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5822 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5823 [(set (v8i8 V64:$dst), 5824 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5825 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5826 [(set (v16i8 V128:$dst), 5827 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5828 (v16i8 V128:$Rm)))]>; 5829 5830 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5831 (v4i16 V64:$RHS))), 5832 (!cast<Instruction>(NAME#"v8i8") 5833 V64:$LHS, V64:$MHS, V64:$RHS)>; 5834 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5835 (v2i32 V64:$RHS))), 5836 (!cast<Instruction>(NAME#"v8i8") 5837 V64:$LHS, V64:$MHS, V64:$RHS)>; 5838 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5839 (v1i64 V64:$RHS))), 5840 (!cast<Instruction>(NAME#"v8i8") 5841 V64:$LHS, V64:$MHS, V64:$RHS)>; 5842 5843 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5844 (v8i16 V128:$RHS))), 5845 (!cast<Instruction>(NAME#"v16i8") 5846 V128:$LHS, V128:$MHS, V128:$RHS)>; 5847 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5848 (v4i32 V128:$RHS))), 5849 (!cast<Instruction>(NAME#"v16i8") 5850 V128:$LHS, V128:$MHS, V128:$RHS)>; 5851 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5852 (v2i64 V128:$RHS))), 5853 (!cast<Instruction>(NAME#"v16i8") 5854 V128:$LHS, V128:$MHS, V128:$RHS)>; 5855} 5856 5857// All operand sizes distinguished in the encoding. 5858multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5859 SDPatternOperator OpNode> { 5860 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5861 asm, ".8b", 5862 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5863 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5864 asm, ".16b", 5865 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5866 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5867 asm, ".4h", 5868 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5869 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5870 asm, ".8h", 5871 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5872 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5873 asm, ".2s", 5874 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5875 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5876 asm, ".4s", 5877 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5878 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5879 asm, ".2d", 5880 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5881} 5882 5883multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5884 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5885 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5886 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5887 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5888 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5889 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5890 5891 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5892 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5893 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5894 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5895 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5896 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5897 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5898 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5899} 5900 5901// As above, but D sized elements unsupported. 5902multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5903 SDPatternOperator OpNode> { 5904 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5905 asm, ".8b", 5906 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5907 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5908 asm, ".16b", 5909 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5910 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5911 asm, ".4h", 5912 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5913 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5914 asm, ".8h", 5915 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5916 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5917 asm, ".2s", 5918 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5919 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5920 asm, ".4s", 5921 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5922} 5923 5924multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5925 SDPatternOperator OpNode> { 5926 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5927 asm, ".8b", 5928 [(set (v8i8 V64:$dst), 5929 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5930 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5931 asm, ".16b", 5932 [(set (v16i8 V128:$dst), 5933 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5934 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5935 asm, ".4h", 5936 [(set (v4i16 V64:$dst), 5937 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5938 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5939 asm, ".8h", 5940 [(set (v8i16 V128:$dst), 5941 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5942 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5943 asm, ".2s", 5944 [(set (v2i32 V64:$dst), 5945 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5946 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5947 asm, ".4s", 5948 [(set (v4i32 V128:$dst), 5949 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5950} 5951 5952// As above, but only B sized elements supported. 5953multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5954 SDPatternOperator OpNode> { 5955 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5956 asm, ".8b", 5957 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5958 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5959 asm, ".16b", 5960 [(set (v16i8 V128:$Rd), 5961 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5962} 5963 5964// As above, but only floating point elements supported. 5965let mayRaiseFPException = 1, Uses = [FPCR] in 5966multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5967 string asm, SDPatternOperator OpNode> { 5968 let Predicates = [HasNEON, HasFullFP16] in { 5969 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5970 asm, ".4h", 5971 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5972 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5973 asm, ".8h", 5974 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5975 } // Predicates = [HasNEON, HasFullFP16] 5976 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5977 asm, ".2s", 5978 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5979 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5980 asm, ".4s", 5981 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5982 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5983 asm, ".2d", 5984 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5985} 5986 5987let mayRaiseFPException = 1, Uses = [FPCR] in 5988multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5989 string asm, 5990 SDPatternOperator OpNode> { 5991 let Predicates = [HasNEON, HasFullFP16] in { 5992 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5993 asm, ".4h", 5994 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5995 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5996 asm, ".8h", 5997 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5998 } // Predicates = [HasNEON, HasFullFP16] 5999 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 6000 asm, ".2s", 6001 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6002 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 6003 asm, ".4s", 6004 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6005 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 6006 asm, ".2d", 6007 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6008} 6009 6010let mayRaiseFPException = 1, Uses = [FPCR] in 6011multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 6012 string asm, SDPatternOperator OpNode> { 6013 let Predicates = [HasNEON, HasFullFP16] in { 6014 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 6015 asm, ".4h", 6016 [(set (v4f16 V64:$dst), 6017 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 6018 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 6019 asm, ".8h", 6020 [(set (v8f16 V128:$dst), 6021 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 6022 } // Predicates = [HasNEON, HasFullFP16] 6023 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 6024 asm, ".2s", 6025 [(set (v2f32 V64:$dst), 6026 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6027 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 6028 asm, ".4s", 6029 [(set (v4f32 V128:$dst), 6030 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6031 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 6032 asm, ".2d", 6033 [(set (v2f64 V128:$dst), 6034 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6035} 6036 6037// As above, but D and B sized elements unsupported. 6038let mayRaiseFPException = 1, Uses = [FPCR] in 6039multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 6040 SDPatternOperator OpNode> { 6041 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 6042 asm, ".4h", 6043 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6044 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 6045 asm, ".8h", 6046 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6047 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 6048 asm, ".2s", 6049 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6050 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 6051 asm, ".4s", 6052 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6053} 6054 6055// Logical three vector ops share opcode bits, and only use B sized elements. 6056multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 6057 SDPatternOperator OpNode = null_frag> { 6058 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 6059 asm, ".8b", 6060 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 6061 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 6062 asm, ".16b", 6063 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 6064 6065 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 6066 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6067 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 6068 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6069 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 6070 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6071 6072 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 6073 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6074 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 6075 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6076 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 6077 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6078} 6079 6080multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 6081 string asm, SDPatternOperator OpNode = null_frag> { 6082 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 6083 asm, ".8b", 6084 [(set (v8i8 V64:$dst), 6085 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6086 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 6087 asm, ".16b", 6088 [(set (v16i8 V128:$dst), 6089 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 6090 (v16i8 V128:$Rm)))]>; 6091 6092 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 6093 (v4i16 V64:$RHS))), 6094 (!cast<Instruction>(NAME#"v8i8") 6095 V64:$LHS, V64:$MHS, V64:$RHS)>; 6096 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 6097 (v2i32 V64:$RHS))), 6098 (!cast<Instruction>(NAME#"v8i8") 6099 V64:$LHS, V64:$MHS, V64:$RHS)>; 6100 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 6101 (v1i64 V64:$RHS))), 6102 (!cast<Instruction>(NAME#"v8i8") 6103 V64:$LHS, V64:$MHS, V64:$RHS)>; 6104 6105 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 6106 (v8i16 V128:$RHS))), 6107 (!cast<Instruction>(NAME#"v16i8") 6108 V128:$LHS, V128:$MHS, V128:$RHS)>; 6109 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 6110 (v4i32 V128:$RHS))), 6111 (!cast<Instruction>(NAME#"v16i8") 6112 V128:$LHS, V128:$MHS, V128:$RHS)>; 6113 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 6114 (v2i64 V128:$RHS))), 6115 (!cast<Instruction>(NAME#"v16i8") 6116 V128:$LHS, V128:$MHS, V128:$RHS)>; 6117} 6118 6119// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 6120// bytes from S-sized elements. 6121class BaseSIMDThreeSameVectorDot<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 6122 string kind1, string kind2, RegisterOperand RegType, 6123 ValueType AccumType, ValueType InputType, 6124 SDPatternOperator OpNode> : 6125 BaseSIMDThreeSameVectorTied<Q, U, {sz, 0b0}, {0b1, opc}, RegType, asm, kind1, 6126 [(set (AccumType RegType:$dst), 6127 (OpNode (AccumType RegType:$Rd), 6128 (InputType RegType:$Rn), 6129 (InputType RegType:$Rm)))]> { 6130 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6131} 6132 6133multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 6134 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, 0b10, {0b001, Mixed}, asm, ".2s", ".8b", V64, 6135 v2i32, v8i8, OpNode>; 6136 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, 0b10, {0b001, Mixed}, asm, ".4s", ".16b", V128, 6137 v4i32, v16i8, OpNode>; 6138} 6139 6140// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 6141// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 6142// 8H to 4S, when Q=1). 6143let mayRaiseFPException = 1, Uses = [FPCR] in 6144class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 6145 string kind2, RegisterOperand RegType, 6146 ValueType AccumType, ValueType InputType, 6147 SDPatternOperator OpNode> : 6148 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 6149 [(set (AccumType RegType:$dst), 6150 (OpNode (AccumType RegType:$Rd), 6151 (InputType RegType:$Rn), 6152 (InputType RegType:$Rm)))]> { 6153 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6154 let Inst{13} = b13; 6155} 6156 6157multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 6158 SDPatternOperator OpNode> { 6159 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 6160 v2f32, v4f16, OpNode>; 6161 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 6162 v4f32, v8f16, OpNode>; 6163} 6164 6165multiclass SIMDThreeSameVectorMLA<bit Q, string asm>{ 6166 def v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b", 6167 V128, v8f16, v16i8, null_frag>; 6168} 6169 6170multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm>{ 6171 def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b", 6172 V128, v4f32, v16i8, null_frag>; 6173} 6174 6175// FP8 assembly/disassembly classes 6176 6177//---------------------------------------------------------------------------- 6178// FP8 Advanced SIMD three-register extension 6179//---------------------------------------------------------------------------- 6180class BaseSIMDThreeVectors<bit Q, bit U, bits<2> size, bits<4> op, 6181 RegisterOperand regtype1, 6182 RegisterOperand regtype2, string asm, 6183 string kind1, string kind2> 6184 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, regtype2:$Rm), asm, 6185 "\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2, "", []>, Sched<[]> { 6186 bits<5> Rd; 6187 bits<5> Rn; 6188 bits<5> Rm; 6189 let Inst{31} = 0; 6190 let Inst{30} = Q; 6191 let Inst{29} = U; 6192 let Inst{28-24} = 0b01110; 6193 let Inst{23-22} = size; 6194 let Inst{21} = 0b0; 6195 let Inst{20-16} = Rm; 6196 let Inst{15} = 0b1; 6197 let Inst{14-11} = op; 6198 let Inst{10} = 0b1; 6199 let Inst{9-5} = Rn; 6200 let Inst{4-0} = Rd; 6201} 6202 6203 6204// FCVTN (FP16 to FP8) 6205multiclass SIMDThreeSameSizeVectorCvt<string asm> { 6206 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b01, 0b1110, V64, V64, asm, ".8b",".4h">; 6207 def v16f8 : BaseSIMDThreeVectors<0b1, 0b0, 0b01, 0b1110, V128, V128, asm, ".16b", ".8h">; 6208} 6209 6210// TODO : Create v16f8 value type 6211// FCVTN, FCVTN2 (FP32 to FP8) 6212multiclass SIMDThreeVectorCvt<string asm> { 6213 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b00, 0b1110, V64, V128, asm, ".8b", ".4s">; 6214 def 2v16f8 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1110, asm#2, ".16b", ".4s", 6215 V128, v16i8, v4f32, null_frag>; 6216} 6217 6218// TODO: Create a new Value Type v8f8 and v16f8 6219multiclass SIMDThreeSameVectorDOT2<string asm> { 6220 def v4f16 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b01, 0b1111, asm, ".4h", ".8b", 6221 V64, v4f16, v8i8, null_frag>; 6222 def v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1111, asm, ".8h", ".16b", 6223 V128, v8f16, v16i8, null_frag>; 6224} 6225 6226multiclass SIMDThreeSameVectorDOT4<string asm> { 6227 def v2f32 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b00, 0b1111, asm, ".2s", ".8b", 6228 V64, v2f32, v8i8, null_frag>; 6229 def v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1111, asm, ".4s", ".16b", 6230 V128, v4f32, v16i8, null_frag>; 6231} 6232 6233//---------------------------------------------------------------------------- 6234// AdvSIMD two register vector instructions. 6235//---------------------------------------------------------------------------- 6236 6237let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6238class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6239 bits<2> size2, RegisterOperand regtype, string asm, 6240 string dstkind, string srckind, list<dag> pattern> 6241 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6242 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6243 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 6244 Sched<[!if(Q, WriteVq, WriteVd)]> { 6245 bits<5> Rd; 6246 bits<5> Rn; 6247 let Inst{31} = 0; 6248 let Inst{30} = Q; 6249 let Inst{29} = U; 6250 let Inst{28-24} = 0b01110; 6251 let Inst{23-22} = size; 6252 let Inst{21} = 0b1; 6253 let Inst{20-19} = size2; 6254 let Inst{18-17} = 0b00; 6255 let Inst{16-12} = opcode; 6256 let Inst{11-10} = 0b10; 6257 let Inst{9-5} = Rn; 6258 let Inst{4-0} = Rd; 6259} 6260 6261let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6262class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6263 bits<2> size2, RegisterOperand regtype, 6264 string asm, string dstkind, string srckind, 6265 list<dag> pattern> 6266 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 6267 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6268 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6269 Sched<[!if(Q, WriteVq, WriteVd)]> { 6270 bits<5> Rd; 6271 bits<5> Rn; 6272 let Inst{31} = 0; 6273 let Inst{30} = Q; 6274 let Inst{29} = U; 6275 let Inst{28-24} = 0b01110; 6276 let Inst{23-22} = size; 6277 let Inst{21} = 0b1; 6278 let Inst{20-19} = size2; 6279 let Inst{18-17} = 0b00; 6280 let Inst{16-12} = opcode; 6281 let Inst{11-10} = 0b10; 6282 let Inst{9-5} = Rn; 6283 let Inst{4-0} = Rd; 6284} 6285 6286// Supports B, H, and S element sizes. 6287multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 6288 SDPatternOperator OpNode> { 6289 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6290 asm, ".8b", ".8b", 6291 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6292 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6293 asm, ".16b", ".16b", 6294 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6295 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6296 asm, ".4h", ".4h", 6297 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6298 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6299 asm, ".8h", ".8h", 6300 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6301 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6302 asm, ".2s", ".2s", 6303 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6304 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6305 asm, ".4s", ".4s", 6306 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6307} 6308 6309class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 6310 RegisterOperand regtype, string asm, string dstkind, 6311 string srckind, string amount> 6312 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 6313 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 6314 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 6315 Sched<[WriteVq]> { 6316 bits<5> Rd; 6317 bits<5> Rn; 6318 let Inst{31} = 0; 6319 let Inst{30} = Q; 6320 let Inst{29-24} = 0b101110; 6321 let Inst{23-22} = size; 6322 let Inst{21-10} = 0b100001001110; 6323 let Inst{9-5} = Rn; 6324 let Inst{4-0} = Rd; 6325} 6326 6327multiclass SIMDVectorLShiftLongBySizeBHS { 6328 let hasSideEffects = 0 in { 6329 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 6330 "shll", ".8h", ".8b", "8">; 6331 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 6332 "shll2", ".8h", ".16b", "8">; 6333 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 6334 "shll", ".4s", ".4h", "16">; 6335 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 6336 "shll2", ".4s", ".8h", "16">; 6337 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 6338 "shll", ".2d", ".2s", "32">; 6339 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 6340 "shll2", ".2d", ".4s", "32">; 6341 } 6342} 6343 6344// Supports all element sizes. 6345multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 6346 SDPatternOperator OpNode> { 6347 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6348 asm, ".4h", ".8b", 6349 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6350 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6351 asm, ".8h", ".16b", 6352 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6353 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6354 asm, ".2s", ".4h", 6355 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6356 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6357 asm, ".4s", ".8h", 6358 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6359 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6360 asm, ".1d", ".2s", 6361 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6362 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6363 asm, ".2d", ".4s", 6364 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6365} 6366 6367multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 6368 SDPatternOperator OpNode> { 6369 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6370 asm, ".4h", ".8b", 6371 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 6372 (v8i8 V64:$Rn)))]>; 6373 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6374 asm, ".8h", ".16b", 6375 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 6376 (v16i8 V128:$Rn)))]>; 6377 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6378 asm, ".2s", ".4h", 6379 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 6380 (v4i16 V64:$Rn)))]>; 6381 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6382 asm, ".4s", ".8h", 6383 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 6384 (v8i16 V128:$Rn)))]>; 6385 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6386 asm, ".1d", ".2s", 6387 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 6388 (v2i32 V64:$Rn)))]>; 6389 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6390 asm, ".2d", ".4s", 6391 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 6392 (v4i32 V128:$Rn)))]>; 6393} 6394 6395// Supports all element sizes, except 1xD. 6396multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 6397 SDPatternOperator OpNode> { 6398 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6399 asm, ".8b", ".8b", 6400 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 6401 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6402 asm, ".16b", ".16b", 6403 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 6404 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6405 asm, ".4h", ".4h", 6406 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 6407 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6408 asm, ".8h", ".8h", 6409 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 6410 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6411 asm, ".2s", ".2s", 6412 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 6413 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6414 asm, ".4s", ".4s", 6415 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 6416 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 6417 asm, ".2d", ".2d", 6418 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 6419} 6420 6421multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 6422 SDPatternOperator OpNode = null_frag> { 6423 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6424 asm, ".8b", ".8b", 6425 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6426 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6427 asm, ".16b", ".16b", 6428 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6429 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6430 asm, ".4h", ".4h", 6431 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6432 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6433 asm, ".8h", ".8h", 6434 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6435 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6436 asm, ".2s", ".2s", 6437 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6438 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6439 asm, ".4s", ".4s", 6440 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6441 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6442 asm, ".2d", ".2d", 6443 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6444} 6445 6446 6447// Supports only B element sizes. 6448multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6449 SDPatternOperator OpNode> { 6450 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6451 asm, ".8b", ".8b", 6452 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6453 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6454 asm, ".16b", ".16b", 6455 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6456 6457} 6458 6459// Supports only B and H element sizes. 6460multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6461 SDPatternOperator OpNode> { 6462 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6463 asm, ".8b", ".8b", 6464 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6465 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6466 asm, ".16b", ".16b", 6467 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6468 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6469 asm, ".4h", ".4h", 6470 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6471 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6472 asm, ".8h", ".8h", 6473 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6474} 6475 6476// Supports H, S and D element sizes, uses high bit of the size field 6477// as an extra opcode bit. 6478multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6479 SDPatternOperator OpNode, 6480 int fpexceptions = 1> { 6481 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 6482 let Predicates = [HasNEON, HasFullFP16] in { 6483 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6484 asm, ".4h", ".4h", 6485 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6486 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6487 asm, ".8h", ".8h", 6488 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6489 } // Predicates = [HasNEON, HasFullFP16] 6490 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6491 asm, ".2s", ".2s", 6492 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6493 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6494 asm, ".4s", ".4s", 6495 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6496 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6497 asm, ".2d", ".2d", 6498 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6499 } 6500} 6501 6502multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6503 SDPatternOperator OpNode> 6504 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6505 6506// Supports only S and D element sizes 6507let mayRaiseFPException = 1, Uses = [FPCR] in 6508multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6509 SDPatternOperator OpNode = null_frag> { 6510 6511 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6512 asm, ".2s", ".2s", 6513 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6514 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6515 asm, ".4s", ".4s", 6516 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6517 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6518 asm, ".2d", ".2d", 6519 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6520} 6521 6522multiclass FRIntNNTVector<bit U, bit op, string asm, 6523 SDPatternOperator OpNode = null_frag> : 6524 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6525 6526// Supports only S element size. 6527multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6528 SDPatternOperator OpNode> { 6529 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6530 asm, ".2s", ".2s", 6531 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6532 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6533 asm, ".4s", ".4s", 6534 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6535} 6536 6537let mayRaiseFPException = 1, Uses = [FPCR] in 6538multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6539 SDPatternOperator OpNode> { 6540 let Predicates = [HasNEON, HasFullFP16] in { 6541 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6542 asm, ".4h", ".4h", 6543 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6544 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6545 asm, ".8h", ".8h", 6546 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6547 } // Predicates = [HasNEON, HasFullFP16] 6548 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6549 asm, ".2s", ".2s", 6550 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6551 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6552 asm, ".4s", ".4s", 6553 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6554 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6555 asm, ".2d", ".2d", 6556 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6557} 6558 6559let mayRaiseFPException = 1, Uses = [FPCR] in 6560multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6561 SDPatternOperator OpNode> { 6562 let Predicates = [HasNEON, HasFullFP16] in { 6563 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6564 asm, ".4h", ".4h", 6565 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6566 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6567 asm, ".8h", ".8h", 6568 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6569 } // Predicates = [HasNEON, HasFullFP16] 6570 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6571 asm, ".2s", ".2s", 6572 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6573 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6574 asm, ".4s", ".4s", 6575 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6576 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6577 asm, ".2d", ".2d", 6578 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6579} 6580 6581let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6582class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6583 RegisterOperand inreg, RegisterOperand outreg, 6584 string asm, string outkind, string inkind, 6585 list<dag> pattern> 6586 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6587 "{\t$Rd" # outkind # ", $Rn" # inkind # 6588 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6589 Sched<[WriteVq]> { 6590 bits<5> Rd; 6591 bits<5> Rn; 6592 let Inst{31} = 0; 6593 let Inst{30} = Q; 6594 let Inst{29} = U; 6595 let Inst{28-24} = 0b01110; 6596 let Inst{23-22} = size; 6597 let Inst{21-17} = 0b10000; 6598 let Inst{16-12} = opcode; 6599 let Inst{11-10} = 0b10; 6600 let Inst{9-5} = Rn; 6601 let Inst{4-0} = Rd; 6602} 6603 6604let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6605class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6606 RegisterOperand inreg, RegisterOperand outreg, 6607 string asm, string outkind, string inkind, 6608 list<dag> pattern> 6609 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6610 "{\t$Rd" # outkind # ", $Rn" # inkind # 6611 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6612 Sched<[WriteVq]> { 6613 bits<5> Rd; 6614 bits<5> Rn; 6615 let Inst{31} = 0; 6616 let Inst{30} = Q; 6617 let Inst{29} = U; 6618 let Inst{28-24} = 0b01110; 6619 let Inst{23-22} = size; 6620 let Inst{21-17} = 0b10000; 6621 let Inst{16-12} = opcode; 6622 let Inst{11-10} = 0b10; 6623 let Inst{9-5} = Rn; 6624 let Inst{4-0} = Rd; 6625} 6626 6627multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6628 SDPatternOperator OpNode> { 6629 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6630 asm, ".8b", ".8h", 6631 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6632 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6633 asm#"2", ".16b", ".8h", []>; 6634 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6635 asm, ".4h", ".4s", 6636 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6637 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6638 asm#"2", ".8h", ".4s", []>; 6639 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6640 asm, ".2s", ".2d", 6641 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6642 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6643 asm#"2", ".4s", ".2d", []>; 6644 6645 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6646 (!cast<Instruction>(NAME # "v16i8") 6647 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6648 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6649 (!cast<Instruction>(NAME # "v8i16") 6650 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6651 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6652 (!cast<Instruction>(NAME # "v4i32") 6653 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6654} 6655 6656//---------------------------------------------------------------------------- 6657// FP8 Advanced SIMD two-register miscellaneous 6658//---------------------------------------------------------------------------- 6659multiclass SIMDMixedTwoVectorFP8<bits<2>sz, string asm> { 6660 def v8f16 : BaseSIMDMixedTwoVector<0b0, 0b1, sz, 0b10111, V64, V128, 6661 asm, ".8h", ".8b", []>; 6662 def 2v8f16 : BaseSIMDMixedTwoVector<0b1, 0b1, sz, 0b10111, V128, V128, 6663 asm#2, ".8h", ".16b", []>; 6664} 6665 6666class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6667 bits<5> opcode, RegisterOperand regtype, string asm, 6668 string kind, string zero, ValueType dty, 6669 ValueType sty, SDNode OpNode> 6670 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6671 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6672 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6673 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6674 Sched<[!if(Q, WriteVq, WriteVd)]> { 6675 bits<5> Rd; 6676 bits<5> Rn; 6677 let Inst{31} = 0; 6678 let Inst{30} = Q; 6679 let Inst{29} = U; 6680 let Inst{28-24} = 0b01110; 6681 let Inst{23-22} = size; 6682 let Inst{21} = 0b1; 6683 let Inst{20-19} = size2; 6684 let Inst{18-17} = 0b00; 6685 let Inst{16-12} = opcode; 6686 let Inst{11-10} = 0b10; 6687 let Inst{9-5} = Rn; 6688 let Inst{4-0} = Rd; 6689} 6690 6691// Comparisons support all element sizes, except 1xD. 6692multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6693 SDNode OpNode> { 6694 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6695 asm, ".8b", "0", 6696 v8i8, v8i8, OpNode>; 6697 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6698 asm, ".16b", "0", 6699 v16i8, v16i8, OpNode>; 6700 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6701 asm, ".4h", "0", 6702 v4i16, v4i16, OpNode>; 6703 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6704 asm, ".8h", "0", 6705 v8i16, v8i16, OpNode>; 6706 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6707 asm, ".2s", "0", 6708 v2i32, v2i32, OpNode>; 6709 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6710 asm, ".4s", "0", 6711 v4i32, v4i32, OpNode>; 6712 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6713 asm, ".2d", "0", 6714 v2i64, v2i64, OpNode>; 6715} 6716 6717// FP Comparisons support only S and D element sizes (and H for v8.2a). 6718multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6719 string asm, SDNode OpNode> { 6720 6721 let mayRaiseFPException = 1, Uses = [FPCR] in { 6722 let Predicates = [HasNEON, HasFullFP16] in { 6723 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6724 asm, ".4h", "0.0", 6725 v4i16, v4f16, OpNode>; 6726 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6727 asm, ".8h", "0.0", 6728 v8i16, v8f16, OpNode>; 6729 } // Predicates = [HasNEON, HasFullFP16] 6730 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6731 asm, ".2s", "0.0", 6732 v2i32, v2f32, OpNode>; 6733 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6734 asm, ".4s", "0.0", 6735 v4i32, v4f32, OpNode>; 6736 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6737 asm, ".2d", "0.0", 6738 v2i64, v2f64, OpNode>; 6739 } 6740 6741 let Predicates = [HasNEON, HasFullFP16] in { 6742 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6743 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6744 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6745 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6746 } 6747 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6748 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6749 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6750 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6751 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6752 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6753 let Predicates = [HasNEON, HasFullFP16] in { 6754 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6755 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6756 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6757 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6758 } 6759 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6760 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6761 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6762 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6763 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6764 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6765} 6766 6767let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6768class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6769 RegisterOperand outtype, RegisterOperand intype, 6770 string asm, string VdTy, string VnTy, 6771 list<dag> pattern> 6772 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6773 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6774 Sched<[WriteVq]> { 6775 bits<5> Rd; 6776 bits<5> Rn; 6777 let Inst{31} = 0; 6778 let Inst{30} = Q; 6779 let Inst{29} = U; 6780 let Inst{28-24} = 0b01110; 6781 let Inst{23-22} = size; 6782 let Inst{21-17} = 0b10000; 6783 let Inst{16-12} = opcode; 6784 let Inst{11-10} = 0b10; 6785 let Inst{9-5} = Rn; 6786 let Inst{4-0} = Rd; 6787} 6788 6789let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6790class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6791 RegisterOperand outtype, RegisterOperand intype, 6792 string asm, string VdTy, string VnTy, 6793 list<dag> pattern> 6794 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6795 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6796 Sched<[WriteVq]> { 6797 bits<5> Rd; 6798 bits<5> Rn; 6799 let Inst{31} = 0; 6800 let Inst{30} = Q; 6801 let Inst{29} = U; 6802 let Inst{28-24} = 0b01110; 6803 let Inst{23-22} = size; 6804 let Inst{21-17} = 0b10000; 6805 let Inst{16-12} = opcode; 6806 let Inst{11-10} = 0b10; 6807 let Inst{9-5} = Rn; 6808 let Inst{4-0} = Rd; 6809} 6810 6811multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6812 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6813 asm, ".4s", ".4h", []>; 6814 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6815 asm#"2", ".4s", ".8h", []>; 6816 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6817 asm, ".2d", ".2s", []>; 6818 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6819 asm#"2", ".2d", ".4s", []>; 6820} 6821 6822multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6823 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6824 asm, ".4h", ".4s", []>; 6825 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6826 asm#"2", ".8h", ".4s", []>; 6827 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6828 asm, ".2s", ".2d", []>; 6829 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6830 asm#"2", ".4s", ".2d", []>; 6831} 6832 6833multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6834 Intrinsic OpNode> { 6835 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6836 asm, ".2s", ".2d", 6837 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6838 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6839 asm#"2", ".4s", ".2d", []>; 6840 6841 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6842 (!cast<Instruction>(NAME # "v4f32") 6843 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6844} 6845 6846//---------------------------------------------------------------------------- 6847// AdvSIMD three register different-size vector instructions. 6848//---------------------------------------------------------------------------- 6849 6850let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6851class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6852 RegisterOperand outtype, RegisterOperand intype1, 6853 RegisterOperand intype2, string asm, 6854 string outkind, string inkind1, string inkind2, 6855 list<dag> pattern> 6856 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6857 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6858 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6859 Sched<[WriteVq]> { 6860 bits<5> Rd; 6861 bits<5> Rn; 6862 bits<5> Rm; 6863 let Inst{31} = 0; 6864 let Inst{30} = size{0}; 6865 let Inst{29} = U; 6866 let Inst{28-24} = 0b01110; 6867 let Inst{23-22} = size{2-1}; 6868 let Inst{21} = 1; 6869 let Inst{20-16} = Rm; 6870 let Inst{15-12} = opcode; 6871 let Inst{11-10} = 0b00; 6872 let Inst{9-5} = Rn; 6873 let Inst{4-0} = Rd; 6874} 6875 6876let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6877class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6878 RegisterOperand outtype, RegisterOperand intype1, 6879 RegisterOperand intype2, string asm, 6880 string outkind, string inkind1, string inkind2, 6881 list<dag> pattern> 6882 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6883 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6884 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6885 Sched<[WriteVq]> { 6886 bits<5> Rd; 6887 bits<5> Rn; 6888 bits<5> Rm; 6889 let Inst{31} = 0; 6890 let Inst{30} = size{0}; 6891 let Inst{29} = U; 6892 let Inst{28-24} = 0b01110; 6893 let Inst{23-22} = size{2-1}; 6894 let Inst{21} = 1; 6895 let Inst{20-16} = Rm; 6896 let Inst{15-12} = opcode; 6897 let Inst{11-10} = 0b00; 6898 let Inst{9-5} = Rn; 6899 let Inst{4-0} = Rd; 6900} 6901 6902// FIXME: TableGen doesn't know how to deal with expanded types that also 6903// change the element count (in this case, placing the results in 6904// the high elements of the result register rather than the low 6905// elements). Until that's fixed, we can't code-gen those. 6906multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6907 Intrinsic IntOp> { 6908 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6909 V64, V128, V128, 6910 asm, ".8b", ".8h", ".8h", 6911 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6912 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6913 V128, V128, V128, 6914 asm#"2", ".16b", ".8h", ".8h", 6915 []>; 6916 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6917 V64, V128, V128, 6918 asm, ".4h", ".4s", ".4s", 6919 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6920 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6921 V128, V128, V128, 6922 asm#"2", ".8h", ".4s", ".4s", 6923 []>; 6924 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6925 V64, V128, V128, 6926 asm, ".2s", ".2d", ".2d", 6927 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6928 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6929 V128, V128, V128, 6930 asm#"2", ".4s", ".2d", ".2d", 6931 []>; 6932 6933 6934 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6935 // a version attached to an instruction. 6936 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6937 (v8i16 V128:$Rm))), 6938 (!cast<Instruction>(NAME # "v8i16_v16i8") 6939 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6940 V128:$Rn, V128:$Rm)>; 6941 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6942 (v4i32 V128:$Rm))), 6943 (!cast<Instruction>(NAME # "v4i32_v8i16") 6944 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6945 V128:$Rn, V128:$Rm)>; 6946 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6947 (v2i64 V128:$Rm))), 6948 (!cast<Instruction>(NAME # "v2i64_v4i32") 6949 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6950 V128:$Rn, V128:$Rm)>; 6951} 6952 6953multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6954 SDPatternOperator OpNode> { 6955 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6956 V128, V64, V64, 6957 asm, ".8h", ".8b", ".8b", 6958 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6959 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6960 V128, V128, V128, 6961 asm#"2", ".8h", ".16b", ".16b", []>; 6962 let Predicates = [HasAES] in { 6963 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6964 V128, V64, V64, 6965 asm, ".1q", ".1d", ".1d", 6966 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>; 6967 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6968 V128, V128, V128, 6969 asm#"2", ".1q", ".2d", ".2d", 6970 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)), 6971 (extract_high_v2i64 (v2i64 V128:$Rm))))]>; 6972 } 6973 6974 def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6975 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6976 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6977} 6978 6979multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6980 SDPatternOperator OpNode> { 6981 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6982 V128, V64, V64, 6983 asm, ".4s", ".4h", ".4h", 6984 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6985 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6986 V128, V128, V128, 6987 asm#"2", ".4s", ".8h", ".8h", 6988 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6989 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6990 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6991 V128, V64, V64, 6992 asm, ".2d", ".2s", ".2s", 6993 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6994 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6995 V128, V128, V128, 6996 asm#"2", ".2d", ".4s", ".4s", 6997 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6998 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 6999} 7000 7001multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 7002 SDPatternOperator OpNode = null_frag> { 7003 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7004 V128, V64, V64, 7005 asm, ".8h", ".8b", ".8b", 7006 [(set (v8i16 V128:$Rd), 7007 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 7008 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7009 V128, V128, V128, 7010 asm#"2", ".8h", ".16b", ".16b", 7011 [(set (v8i16 V128:$Rd), 7012 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7013 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 7014 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7015 V128, V64, V64, 7016 asm, ".4s", ".4h", ".4h", 7017 [(set (v4i32 V128:$Rd), 7018 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 7019 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7020 V128, V128, V128, 7021 asm#"2", ".4s", ".8h", ".8h", 7022 [(set (v4i32 V128:$Rd), 7023 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7024 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7025 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7026 V128, V64, V64, 7027 asm, ".2d", ".2s", ".2s", 7028 [(set (v2i64 V128:$Rd), 7029 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 7030 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7031 V128, V128, V128, 7032 asm#"2", ".2d", ".4s", ".4s", 7033 [(set (v2i64 V128:$Rd), 7034 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7035 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7036} 7037 7038multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 7039 string asm, 7040 SDPatternOperator OpNode> { 7041 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7042 V128, V64, V64, 7043 asm, ".8h", ".8b", ".8b", 7044 [(set (v8i16 V128:$dst), 7045 (add (v8i16 V128:$Rd), 7046 (zext (v8i8 (OpNode (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 (add (v8i16 V128:$Rd), 7052 (zext (v8i8 (OpNode (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 (add (v4i32 V128:$Rd), 7059 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 7060 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7061 V128, V128, V128, 7062 asm#"2", ".4s", ".8h", ".8h", 7063 [(set (v4i32 V128:$dst), 7064 (add (v4i32 V128:$Rd), 7065 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7066 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 7067 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7068 V128, V64, V64, 7069 asm, ".2d", ".2s", ".2s", 7070 [(set (v2i64 V128:$dst), 7071 (add (v2i64 V128:$Rd), 7072 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 7073 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7074 V128, V128, V128, 7075 asm#"2", ".2d", ".4s", ".4s", 7076 [(set (v2i64 V128:$dst), 7077 (add (v2i64 V128:$Rd), 7078 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7079 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 7080} 7081 7082multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 7083 SDPatternOperator OpNode = null_frag> { 7084 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7085 V128, V64, V64, 7086 asm, ".8h", ".8b", ".8b", 7087 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7088 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7089 V128, V128, V128, 7090 asm#"2", ".8h", ".16b", ".16b", 7091 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7092 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7093 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7094 V128, V64, V64, 7095 asm, ".4s", ".4h", ".4h", 7096 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7097 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7098 V128, V128, V128, 7099 asm#"2", ".4s", ".8h", ".8h", 7100 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7101 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7102 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7103 V128, V64, V64, 7104 asm, ".2d", ".2s", ".2s", 7105 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7106 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7107 V128, V128, V128, 7108 asm#"2", ".2d", ".4s", ".4s", 7109 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7110 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7111} 7112 7113multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 7114 string asm, 7115 SDPatternOperator OpNode> { 7116 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7117 V128, V64, V64, 7118 asm, ".8h", ".8b", ".8b", 7119 [(set (v8i16 V128:$dst), 7120 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7121 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7122 V128, V128, V128, 7123 asm#"2", ".8h", ".16b", ".16b", 7124 [(set (v8i16 V128:$dst), 7125 (OpNode (v8i16 V128:$Rd), 7126 (extract_high_v16i8 (v16i8 V128:$Rn)), 7127 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7128 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7129 V128, V64, V64, 7130 asm, ".4s", ".4h", ".4h", 7131 [(set (v4i32 V128:$dst), 7132 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7133 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7134 V128, V128, V128, 7135 asm#"2", ".4s", ".8h", ".8h", 7136 [(set (v4i32 V128:$dst), 7137 (OpNode (v4i32 V128:$Rd), 7138 (extract_high_v8i16 (v8i16 V128:$Rn)), 7139 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7140 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7141 V128, V64, V64, 7142 asm, ".2d", ".2s", ".2s", 7143 [(set (v2i64 V128:$dst), 7144 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7145 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7146 V128, V128, V128, 7147 asm#"2", ".2d", ".4s", ".4s", 7148 [(set (v2i64 V128:$dst), 7149 (OpNode (v2i64 V128:$Rd), 7150 (extract_high_v4i32 (v4i32 V128:$Rn)), 7151 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7152} 7153 7154multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 7155 SDPatternOperator Accum> { 7156 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7157 V128, V64, V64, 7158 asm, ".4s", ".4h", ".4h", 7159 [(set (v4i32 V128:$dst), 7160 (Accum (v4i32 V128:$Rd), 7161 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 7162 (v4i16 V64:$Rm)))))]>; 7163 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7164 V128, V128, V128, 7165 asm#"2", ".4s", ".8h", ".8h", 7166 [(set (v4i32 V128:$dst), 7167 (Accum (v4i32 V128:$Rd), 7168 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 7169 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7170 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7171 V128, V64, V64, 7172 asm, ".2d", ".2s", ".2s", 7173 [(set (v2i64 V128:$dst), 7174 (Accum (v2i64 V128:$Rd), 7175 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 7176 (v2i32 V64:$Rm)))))]>; 7177 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7178 V128, V128, V128, 7179 asm#"2", ".2d", ".4s", ".4s", 7180 [(set (v2i64 V128:$dst), 7181 (Accum (v2i64 V128:$Rd), 7182 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 7183 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7184} 7185 7186multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 7187 SDPatternOperator OpNode> { 7188 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7189 V128, V128, V64, 7190 asm, ".8h", ".8h", ".8b", 7191 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 7192 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7193 V128, V128, V128, 7194 asm#"2", ".8h", ".8h", ".16b", 7195 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7196 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7197 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7198 V128, V128, V64, 7199 asm, ".4s", ".4s", ".4h", 7200 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 7201 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7202 V128, V128, V128, 7203 asm#"2", ".4s", ".4s", ".8h", 7204 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7205 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7206 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7207 V128, V128, V64, 7208 asm, ".2d", ".2d", ".2s", 7209 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 7210 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7211 V128, V128, V128, 7212 asm#"2", ".2d", ".2d", ".4s", 7213 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7214 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7215} 7216 7217//---------------------------------------------------------------------------- 7218// AdvSIMD bitwise extract from vector 7219//---------------------------------------------------------------------------- 7220 7221class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 7222 string asm, string kind> 7223 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 7224 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 7225 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 7226 [(set (vty regtype:$Rd), 7227 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 7228 Sched<[!if(size, WriteVq, WriteVd)]> { 7229 bits<5> Rd; 7230 bits<5> Rn; 7231 bits<5> Rm; 7232 bits<4> imm; 7233 let Inst{31} = 0; 7234 let Inst{30} = size; 7235 let Inst{29-21} = 0b101110000; 7236 let Inst{20-16} = Rm; 7237 let Inst{15} = 0; 7238 let Inst{14-11} = imm; 7239 let Inst{10} = 0; 7240 let Inst{9-5} = Rn; 7241 let Inst{4-0} = Rd; 7242} 7243 7244 7245multiclass SIMDBitwiseExtract<string asm> { 7246 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 7247 let imm{3} = 0; 7248 } 7249 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 7250} 7251 7252//---------------------------------------------------------------------------- 7253// AdvSIMD zip vector 7254//---------------------------------------------------------------------------- 7255 7256class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 7257 string asm, string kind, SDNode OpNode, ValueType valty> 7258 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7259 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 7260 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 7261 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 7262 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 7263 bits<5> Rd; 7264 bits<5> Rn; 7265 bits<5> Rm; 7266 let Inst{31} = 0; 7267 let Inst{30} = size{0}; 7268 let Inst{29-24} = 0b001110; 7269 let Inst{23-22} = size{2-1}; 7270 let Inst{21} = 0; 7271 let Inst{20-16} = Rm; 7272 let Inst{15} = 0; 7273 let Inst{14-12} = opc; 7274 let Inst{11-10} = 0b10; 7275 let Inst{9-5} = Rn; 7276 let Inst{4-0} = Rd; 7277} 7278 7279multiclass SIMDZipVector<bits<3>opc, string asm, 7280 SDNode OpNode> { 7281 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 7282 asm, ".8b", OpNode, v8i8>; 7283 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 7284 asm, ".16b", OpNode, v16i8>; 7285 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 7286 asm, ".4h", OpNode, v4i16>; 7287 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 7288 asm, ".8h", OpNode, v8i16>; 7289 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 7290 asm, ".2s", OpNode, v2i32>; 7291 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 7292 asm, ".4s", OpNode, v4i32>; 7293 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 7294 asm, ".2d", OpNode, v2i64>; 7295 7296 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 7297 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7298 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)), 7299 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7300 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 7301 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7302 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)), 7303 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7304 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 7305 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 7306 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 7307 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 7308 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 7309 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 7310} 7311 7312//---------------------------------------------------------------------------- 7313// AdvSIMD three register scalar instructions 7314//---------------------------------------------------------------------------- 7315 7316let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7317class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 7318 RegisterClass regtype, string asm, 7319 list<dag> pattern> 7320 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7321 "\t$Rd, $Rn, $Rm", "", pattern>, 7322 Sched<[WriteVd]> { 7323 bits<5> Rd; 7324 bits<5> Rn; 7325 bits<5> Rm; 7326 let Inst{31-30} = 0b01; 7327 let Inst{29} = U; 7328 let Inst{28-24} = 0b11110; 7329 let Inst{23-21} = size; 7330 let Inst{20-16} = Rm; 7331 let Inst{15-11} = opcode; 7332 let Inst{10} = 1; 7333 let Inst{9-5} = Rn; 7334 let Inst{4-0} = Rd; 7335} 7336 7337let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7338class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 7339 dag oops, dag iops, string asm, 7340 list<dag> pattern> 7341 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 7342 Sched<[WriteVd]> { 7343 bits<5> Rd; 7344 bits<5> Rn; 7345 bits<5> Rm; 7346 let Inst{31-30} = 0b01; 7347 let Inst{29} = U; 7348 let Inst{28-24} = 0b11110; 7349 let Inst{23-22} = size; 7350 let Inst{21} = R; 7351 let Inst{20-16} = Rm; 7352 let Inst{15-11} = opcode; 7353 let Inst{10} = 1; 7354 let Inst{9-5} = Rn; 7355 let Inst{4-0} = Rd; 7356} 7357 7358multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 7359 SDPatternOperator OpNode> { 7360 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7361 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7362} 7363 7364multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 7365 SDPatternOperator OpNode> { 7366 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7367 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7368 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 7369 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7370 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 7371 7372 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 7373 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 7374 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 7375 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 7376} 7377 7378multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 7379 SDPatternOperator OpNode> { 7380 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 7381 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7382 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7383} 7384 7385multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 7386 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 7387 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 7388 asm, []>; 7389 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 7390 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 7391 asm, []>; 7392} 7393 7394multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 7395 SDPatternOperator OpNode = null_frag, 7396 Predicate pred = HasNEON> { 7397 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7398 let Predicates = [pred] in { 7399 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7400 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7401 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7402 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7403 } 7404 let Predicates = [pred, HasFullFP16] in { 7405 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7406 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 7407 } 7408 } 7409 7410 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7411 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7412} 7413 7414multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 7415 SDPatternOperator OpNode = null_frag> { 7416 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7417 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7418 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7419 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7420 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 7421 let Predicates = [HasNEON, HasFullFP16] in { 7422 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7423 []>; 7424 } // Predicates = [HasNEON, HasFullFP16] 7425 } 7426 7427 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7428 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7429} 7430 7431class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 7432 dag oops, dag iops, string asm, string cstr, list<dag> pat> 7433 : I<oops, iops, asm, 7434 "\t$Rd, $Rn, $Rm", cstr, pat>, 7435 Sched<[WriteVd]> { 7436 bits<5> Rd; 7437 bits<5> Rn; 7438 bits<5> Rm; 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} = 1; 7444 let Inst{20-16} = Rm; 7445 let Inst{15-11} = opcode; 7446 let Inst{10} = 0; 7447 let Inst{9-5} = Rn; 7448 let Inst{4-0} = Rd; 7449} 7450 7451let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7452multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 7453 SDPatternOperator OpNode = null_frag> { 7454 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7455 (outs FPR32:$Rd), 7456 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7457 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7458 (outs FPR64:$Rd), 7459 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7460 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7461} 7462 7463let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7464multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7465 SDPatternOperator OpNode = null_frag> { 7466 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7467 (outs FPR32:$dst), 7468 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7469 asm, "$Rd = $dst", []>; 7470 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7471 (outs FPR64:$dst), 7472 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7473 asm, "$Rd = $dst", 7474 [(set (i64 FPR64:$dst), 7475 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7476} 7477 7478//---------------------------------------------------------------------------- 7479// AdvSIMD two register scalar instructions 7480//---------------------------------------------------------------------------- 7481 7482let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7483class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7484 RegisterClass regtype, RegisterClass regtype2, 7485 string asm, list<dag> pat> 7486 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7487 "\t$Rd, $Rn", "", pat>, 7488 Sched<[WriteVd]> { 7489 bits<5> Rd; 7490 bits<5> Rn; 7491 let Inst{31-30} = 0b01; 7492 let Inst{29} = U; 7493 let Inst{28-24} = 0b11110; 7494 let Inst{23-22} = size; 7495 let Inst{21} = 0b1; 7496 let Inst{20-19} = size2; 7497 let Inst{18-17} = 0b00; 7498 let Inst{16-12} = opcode; 7499 let Inst{11-10} = 0b10; 7500 let Inst{9-5} = Rn; 7501 let Inst{4-0} = Rd; 7502} 7503 7504let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7505class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7506 RegisterClass regtype, RegisterClass regtype2, 7507 string asm, list<dag> pat> 7508 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7509 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7510 Sched<[WriteVd]> { 7511 bits<5> Rd; 7512 bits<5> Rn; 7513 let Inst{31-30} = 0b01; 7514 let Inst{29} = U; 7515 let Inst{28-24} = 0b11110; 7516 let Inst{23-22} = size; 7517 let Inst{21-17} = 0b10000; 7518 let Inst{16-12} = opcode; 7519 let Inst{11-10} = 0b10; 7520 let Inst{9-5} = Rn; 7521 let Inst{4-0} = Rd; 7522} 7523 7524 7525let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7526class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7527 RegisterClass regtype, string asm, string zero> 7528 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7529 "\t$Rd, $Rn, #" # zero, "", []>, 7530 Sched<[WriteVd]> { 7531 bits<5> Rd; 7532 bits<5> Rn; 7533 let Inst{31-30} = 0b01; 7534 let Inst{29} = U; 7535 let Inst{28-24} = 0b11110; 7536 let Inst{23-22} = size; 7537 let Inst{21} = 0b1; 7538 let Inst{20-19} = size2; 7539 let Inst{18-17} = 0b00; 7540 let Inst{16-12} = opcode; 7541 let Inst{11-10} = 0b10; 7542 let Inst{9-5} = Rn; 7543 let Inst{4-0} = Rd; 7544} 7545 7546let mayRaiseFPException = 1, Uses = [FPCR] in 7547class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7548 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7549 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 7550 Sched<[WriteVd]> { 7551 bits<5> Rd; 7552 bits<5> Rn; 7553 let Inst{31-17} = 0b011111100110000; 7554 let Inst{16-12} = opcode; 7555 let Inst{11-10} = 0b10; 7556 let Inst{9-5} = Rn; 7557 let Inst{4-0} = Rd; 7558} 7559 7560multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7561 SDPatternOperator OpNode> { 7562 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7563 7564 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7565 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7566} 7567 7568multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7569 SDPatternOperator OpNode> { 7570 let mayRaiseFPException = 1, Uses = [FPCR] in { 7571 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7572 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7573 let Predicates = [HasNEON, HasFullFP16] in { 7574 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7575 } 7576 } 7577 7578 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7579 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7580 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7581 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7582 let Predicates = [HasNEON, HasFullFP16] in { 7583 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7584 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7585 } 7586 7587 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7588 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7589} 7590 7591multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7592 SDPatternOperator OpNode = null_frag, 7593 list<Predicate> preds = []> { 7594 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7595 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7596 7597 let Predicates = preds in { 7598 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7599 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7600 } 7601} 7602 7603let mayRaiseFPException = 1, Uses = [FPCR] in 7604multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm, 7605 Predicate pred = HasNEON> { 7606 let Predicates = [pred] in { 7607 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 7608 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 7609 } 7610 let Predicates = [pred, HasFullFP16] in { 7611 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 7612 } 7613} 7614 7615let mayRaiseFPException = 1, Uses = [FPCR] in 7616multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 7617 SDPatternOperator OpNode> { 7618 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7619 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7620 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7621 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7622 let Predicates = [HasNEON, HasFullFP16] in { 7623 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7624 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7625 } 7626} 7627 7628multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7629 SDPatternOperator OpNode = null_frag> { 7630 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7631 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7632 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7633 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7634 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7635 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7636 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7637 } 7638 7639 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7640 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7641} 7642 7643multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7644 Intrinsic OpNode> { 7645 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7646 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7647 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7648 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7649 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7650 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7651 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7652 } 7653 7654 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7655 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7656} 7657 7658 7659 7660let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7661multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7662 SDPatternOperator OpNode = null_frag> { 7663 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7664 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>; 7665 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7666 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7667} 7668 7669//---------------------------------------------------------------------------- 7670// AdvSIMD scalar pairwise instructions 7671//---------------------------------------------------------------------------- 7672 7673let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7674class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7675 RegisterOperand regtype, RegisterOperand vectype, 7676 string asm, string kind> 7677 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7678 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7679 Sched<[WriteVd]> { 7680 bits<5> Rd; 7681 bits<5> Rn; 7682 let Inst{31-30} = 0b01; 7683 let Inst{29} = U; 7684 let Inst{28-24} = 0b11110; 7685 let Inst{23-22} = size; 7686 let Inst{21-17} = 0b11000; 7687 let Inst{16-12} = opcode; 7688 let Inst{11-10} = 0b10; 7689 let Inst{9-5} = Rn; 7690 let Inst{4-0} = Rd; 7691} 7692 7693multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7694 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7695 asm, ".2d">; 7696} 7697 7698let mayRaiseFPException = 1, Uses = [FPCR] in 7699multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7700 let Predicates = [HasNEON, HasFullFP16] in { 7701 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7702 asm, ".2h">; 7703 } 7704 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7705 asm, ".2s">; 7706 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7707 asm, ".2d">; 7708} 7709 7710//---------------------------------------------------------------------------- 7711// AdvSIMD across lanes instructions 7712//---------------------------------------------------------------------------- 7713 7714let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7715class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7716 RegisterClass regtype, RegisterOperand vectype, 7717 string asm, string kind, list<dag> pattern> 7718 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7719 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7720 Sched<[!if(Q, WriteVq, WriteVd)]> { 7721 bits<5> Rd; 7722 bits<5> Rn; 7723 let Inst{31} = 0; 7724 let Inst{30} = Q; 7725 let Inst{29} = U; 7726 let Inst{28-24} = 0b01110; 7727 let Inst{23-22} = size; 7728 let Inst{21-17} = 0b11000; 7729 let Inst{16-12} = opcode; 7730 let Inst{11-10} = 0b10; 7731 let Inst{9-5} = Rn; 7732 let Inst{4-0} = Rd; 7733} 7734 7735multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7736 string asm> { 7737 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7738 asm, ".8b", []>; 7739 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7740 asm, ".16b", []>; 7741 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7742 asm, ".4h", []>; 7743 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7744 asm, ".8h", []>; 7745 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7746 asm, ".4s", []>; 7747} 7748 7749multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7750 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7751 asm, ".8b", []>; 7752 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7753 asm, ".16b", []>; 7754 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7755 asm, ".4h", []>; 7756 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7757 asm, ".8h", []>; 7758 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7759 asm, ".4s", []>; 7760} 7761 7762let mayRaiseFPException = 1, Uses = [FPCR] in 7763multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7764 SDPatternOperator intOp> { 7765 let Predicates = [HasNEON, HasFullFP16] in { 7766 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7767 asm, ".4h", 7768 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7769 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7770 asm, ".8h", 7771 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7772 } // Predicates = [HasNEON, HasFullFP16] 7773 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7774 asm, ".4s", 7775 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7776} 7777 7778//---------------------------------------------------------------------------- 7779// AdvSIMD INS/DUP instructions 7780//---------------------------------------------------------------------------- 7781 7782// FIXME: There has got to be a better way to factor these. ugh. 7783 7784class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7785 string operands, string constraints, list<dag> pattern> 7786 : I<outs, ins, asm, operands, constraints, pattern>, 7787 Sched<[!if(Q, WriteVq, WriteVd)]> { 7788 bits<5> Rd; 7789 bits<5> Rn; 7790 let Inst{31} = 0; 7791 let Inst{30} = Q; 7792 let Inst{29} = op; 7793 let Inst{28-21} = 0b01110000; 7794 let Inst{15} = 0; 7795 let Inst{10} = 1; 7796 let Inst{9-5} = Rn; 7797 let Inst{4-0} = Rd; 7798} 7799 7800class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7801 RegisterOperand vecreg, RegisterClass regtype> 7802 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7803 "{\t$Rd" # size # ", $Rn" # 7804 "|" # size # "\t$Rd, $Rn}", "", 7805 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7806 let Inst{20-16} = imm5; 7807 let Inst{14-11} = 0b0001; 7808} 7809 7810class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7811 ValueType vectype, ValueType insreg, 7812 RegisterOperand vecreg, Operand idxtype, 7813 SDNode OpNode> 7814 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7815 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7816 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7817 [(set (vectype vecreg:$Rd), 7818 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7819 let Inst{14-11} = 0b0000; 7820} 7821 7822class SIMDDup64FromElement 7823 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7824 VectorIndexD, AArch64duplane64> { 7825 bits<1> idx; 7826 let Inst{20} = idx; 7827 let Inst{19-16} = 0b1000; 7828} 7829 7830class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7831 RegisterOperand vecreg> 7832 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7833 VectorIndexS, AArch64duplane32> { 7834 bits<2> idx; 7835 let Inst{20-19} = idx; 7836 let Inst{18-16} = 0b100; 7837} 7838 7839class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7840 RegisterOperand vecreg> 7841 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7842 VectorIndexH, AArch64duplane16> { 7843 bits<3> idx; 7844 let Inst{20-18} = idx; 7845 let Inst{17-16} = 0b10; 7846} 7847 7848class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7849 RegisterOperand vecreg> 7850 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7851 VectorIndexB, AArch64duplane8> { 7852 bits<4> idx; 7853 let Inst{20-17} = idx; 7854 let Inst{16} = 1; 7855} 7856 7857class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7858 Operand idxtype, string asm, list<dag> pattern> 7859 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7860 "{\t$Rd, $Rn" # size # "$idx" # 7861 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7862 let Inst{14-11} = imm4; 7863} 7864 7865class SIMDSMov<bit Q, string size, RegisterClass regtype, 7866 Operand idxtype> 7867 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7868class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7869 Operand idxtype> 7870 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7871 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7872 7873class SIMDMovAlias<string asm, string size, Instruction inst, 7874 RegisterClass regtype, Operand idxtype> 7875 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7876 "|" # size # "\t$dst, $src$idx}", 7877 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7878 7879multiclass SMov { 7880 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7881 // streaming mode. 7882 let Predicates = [HasNEONorSME] in { 7883 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7884 let Inst{20-16} = 0b00001; 7885 } 7886 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7887 let Inst{20-16} = 0b00001; 7888 } 7889 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7890 let Inst{20-16} = 0b00010; 7891 } 7892 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7893 let Inst{20-16} = 0b00010; 7894 } 7895 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7896 let Inst{20-16} = 0b00100; 7897 } 7898 } 7899 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7900 bits<4> idx; 7901 let Inst{20-17} = idx; 7902 let Inst{16} = 1; 7903 } 7904 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7905 bits<4> idx; 7906 let Inst{20-17} = idx; 7907 let Inst{16} = 1; 7908 } 7909 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7910 bits<3> idx; 7911 let Inst{20-18} = idx; 7912 let Inst{17-16} = 0b10; 7913 } 7914 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7915 bits<3> idx; 7916 let Inst{20-18} = idx; 7917 let Inst{17-16} = 0b10; 7918 } 7919 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7920 bits<2> idx; 7921 let Inst{20-19} = idx; 7922 let Inst{18-16} = 0b100; 7923 } 7924} 7925 7926multiclass UMov { 7927 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7928 // streaming mode. 7929 let Predicates = [HasNEONorSME] in { 7930 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7931 let Inst{20-16} = 0b00001; 7932 } 7933 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7934 let Inst{20-16} = 0b00010; 7935 } 7936 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7937 let Inst{20-16} = 0b00100; 7938 } 7939 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7940 let Inst{20-16} = 0b01000; 7941 } 7942 def : SIMDMovAlias<"mov", ".s", 7943 !cast<Instruction>(NAME # vi32_idx0), 7944 GPR32, VectorIndex0>; 7945 def : SIMDMovAlias<"mov", ".d", 7946 !cast<Instruction>(NAME # vi64_idx0), 7947 GPR64, VectorIndex0>; 7948 } 7949 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7950 bits<4> idx; 7951 let Inst{20-17} = idx; 7952 let Inst{16} = 1; 7953 } 7954 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7955 bits<3> idx; 7956 let Inst{20-18} = idx; 7957 let Inst{17-16} = 0b10; 7958 } 7959 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7960 bits<2> idx; 7961 let Inst{20-19} = idx; 7962 let Inst{18-16} = 0b100; 7963 } 7964 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7965 bits<1> idx; 7966 let Inst{20} = idx; 7967 let Inst{19-16} = 0b1000; 7968 } 7969 def : SIMDMovAlias<"mov", ".s", 7970 !cast<Instruction>(NAME#"vi32"), 7971 GPR32, VectorIndexS>; 7972 def : SIMDMovAlias<"mov", ".d", 7973 !cast<Instruction>(NAME#"vi64"), 7974 GPR64, VectorIndexD>; 7975} 7976 7977class SIMDInsFromMain<string size, ValueType vectype, 7978 RegisterClass regtype, Operand idxtype> 7979 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7980 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7981 "{\t$Rd" # size # "$idx, $Rn" # 7982 "|" # size # "\t$Rd$idx, $Rn}", 7983 "$Rd = $dst", 7984 [(set V128:$dst, 7985 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 7986 let Inst{14-11} = 0b0011; 7987} 7988 7989class SIMDInsFromElement<string size, ValueType vectype, 7990 ValueType elttype, Operand idxtype> 7991 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7992 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7993 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7994 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7995 "$Rd = $dst", 7996 [(set V128:$dst, 7997 (vector_insert 7998 (vectype V128:$Rd), 7999 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 8000 idxtype:$idx))]>; 8001 8002class SIMDInsMainMovAlias<string size, Instruction inst, 8003 RegisterClass regtype, Operand idxtype> 8004 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 8005 "|" # size #"\t$dst$idx, $src}", 8006 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 8007class SIMDInsElementMovAlias<string size, Instruction inst, 8008 Operand idxtype> 8009 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 8010 # "|" # size #"\t$dst$idx, $src$idx2}", 8011 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 8012 8013 8014multiclass SIMDIns { 8015 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 8016 bits<4> idx; 8017 let Inst{20-17} = idx; 8018 let Inst{16} = 1; 8019 } 8020 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 8021 bits<3> idx; 8022 let Inst{20-18} = idx; 8023 let Inst{17-16} = 0b10; 8024 } 8025 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 8026 bits<2> idx; 8027 let Inst{20-19} = idx; 8028 let Inst{18-16} = 0b100; 8029 } 8030 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 8031 bits<1> idx; 8032 let Inst{20} = idx; 8033 let Inst{19-16} = 0b1000; 8034 } 8035 8036 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 8037 bits<4> idx; 8038 bits<4> idx2; 8039 let Inst{20-17} = idx; 8040 let Inst{16} = 1; 8041 let Inst{14-11} = idx2; 8042 } 8043 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 8044 bits<3> idx; 8045 bits<3> idx2; 8046 let Inst{20-18} = idx; 8047 let Inst{17-16} = 0b10; 8048 let Inst{14-12} = idx2; 8049 let Inst{11} = {?}; 8050 } 8051 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 8052 bits<2> idx; 8053 bits<2> idx2; 8054 let Inst{20-19} = idx; 8055 let Inst{18-16} = 0b100; 8056 let Inst{14-13} = idx2; 8057 let Inst{12-11} = {?,?}; 8058 } 8059 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 8060 bits<1> idx; 8061 bits<1> idx2; 8062 let Inst{20} = idx; 8063 let Inst{19-16} = 0b1000; 8064 let Inst{14} = idx2; 8065 let Inst{13-11} = {?,?,?}; 8066 } 8067 8068 // For all forms of the INS instruction, the "mov" mnemonic is the 8069 // preferred alias. Why they didn't just call the instruction "mov" in 8070 // the first place is a very good question indeed... 8071 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 8072 GPR32, VectorIndexB>; 8073 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 8074 GPR32, VectorIndexH>; 8075 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 8076 GPR32, VectorIndexS>; 8077 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 8078 GPR64, VectorIndexD>; 8079 8080 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 8081 VectorIndexB>; 8082 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 8083 VectorIndexH>; 8084 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 8085 VectorIndexS>; 8086 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 8087 VectorIndexD>; 8088} 8089 8090//---------------------------------------------------------------------------- 8091// AdvSIMD TBL/TBX 8092//---------------------------------------------------------------------------- 8093 8094let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8095class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8096 RegisterOperand listtype, string asm, string kind> 8097 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 8098 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 8099 Sched<[!if(Q, WriteVq, WriteVd)]> { 8100 bits<5> Vd; 8101 bits<5> Vn; 8102 bits<5> Vm; 8103 let Inst{31} = 0; 8104 let Inst{30} = Q; 8105 let Inst{29-21} = 0b001110000; 8106 let Inst{20-16} = Vm; 8107 let Inst{15} = 0; 8108 let Inst{14-13} = len; 8109 let Inst{12} = op; 8110 let Inst{11-10} = 0b00; 8111 let Inst{9-5} = Vn; 8112 let Inst{4-0} = Vd; 8113} 8114 8115let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8116class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8117 RegisterOperand listtype, string asm, string kind> 8118 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 8119 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 8120 Sched<[!if(Q, WriteVq, WriteVd)]> { 8121 bits<5> Vd; 8122 bits<5> Vn; 8123 bits<5> Vm; 8124 let Inst{31} = 0; 8125 let Inst{30} = Q; 8126 let Inst{29-21} = 0b001110000; 8127 let Inst{20-16} = Vm; 8128 let Inst{15} = 0; 8129 let Inst{14-13} = len; 8130 let Inst{12} = op; 8131 let Inst{11-10} = 0b00; 8132 let Inst{9-5} = Vn; 8133 let Inst{4-0} = Vd; 8134} 8135 8136class SIMDTableLookupAlias<string asm, Instruction inst, 8137 RegisterOperand vectype, RegisterOperand listtype> 8138 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 8139 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 8140 8141multiclass SIMDTableLookup<bit op, string asm> { 8142 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 8143 asm, ".8b">; 8144 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 8145 asm, ".8b">; 8146 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 8147 asm, ".8b">; 8148 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 8149 asm, ".8b">; 8150 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 8151 asm, ".16b">; 8152 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 8153 asm, ".16b">; 8154 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 8155 asm, ".16b">; 8156 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 8157 asm, ".16b">; 8158 8159 def : SIMDTableLookupAlias<asm # ".8b", 8160 !cast<Instruction>(NAME#"v8i8One"), 8161 V64, VecListOne128>; 8162 def : SIMDTableLookupAlias<asm # ".8b", 8163 !cast<Instruction>(NAME#"v8i8Two"), 8164 V64, VecListTwo128>; 8165 def : SIMDTableLookupAlias<asm # ".8b", 8166 !cast<Instruction>(NAME#"v8i8Three"), 8167 V64, VecListThree128>; 8168 def : SIMDTableLookupAlias<asm # ".8b", 8169 !cast<Instruction>(NAME#"v8i8Four"), 8170 V64, VecListFour128>; 8171 def : SIMDTableLookupAlias<asm # ".16b", 8172 !cast<Instruction>(NAME#"v16i8One"), 8173 V128, VecListOne128>; 8174 def : SIMDTableLookupAlias<asm # ".16b", 8175 !cast<Instruction>(NAME#"v16i8Two"), 8176 V128, VecListTwo128>; 8177 def : SIMDTableLookupAlias<asm # ".16b", 8178 !cast<Instruction>(NAME#"v16i8Three"), 8179 V128, VecListThree128>; 8180 def : SIMDTableLookupAlias<asm # ".16b", 8181 !cast<Instruction>(NAME#"v16i8Four"), 8182 V128, VecListFour128>; 8183} 8184 8185multiclass SIMDTableLookupTied<bit op, string asm> { 8186 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 8187 asm, ".8b">; 8188 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 8189 asm, ".8b">; 8190 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 8191 asm, ".8b">; 8192 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 8193 asm, ".8b">; 8194 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 8195 asm, ".16b">; 8196 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 8197 asm, ".16b">; 8198 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 8199 asm, ".16b">; 8200 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 8201 asm, ".16b">; 8202 8203 def : SIMDTableLookupAlias<asm # ".8b", 8204 !cast<Instruction>(NAME#"v8i8One"), 8205 V64, VecListOne128>; 8206 def : SIMDTableLookupAlias<asm # ".8b", 8207 !cast<Instruction>(NAME#"v8i8Two"), 8208 V64, VecListTwo128>; 8209 def : SIMDTableLookupAlias<asm # ".8b", 8210 !cast<Instruction>(NAME#"v8i8Three"), 8211 V64, VecListThree128>; 8212 def : SIMDTableLookupAlias<asm # ".8b", 8213 !cast<Instruction>(NAME#"v8i8Four"), 8214 V64, VecListFour128>; 8215 def : SIMDTableLookupAlias<asm # ".16b", 8216 !cast<Instruction>(NAME#"v16i8One"), 8217 V128, VecListOne128>; 8218 def : SIMDTableLookupAlias<asm # ".16b", 8219 !cast<Instruction>(NAME#"v16i8Two"), 8220 V128, VecListTwo128>; 8221 def : SIMDTableLookupAlias<asm # ".16b", 8222 !cast<Instruction>(NAME#"v16i8Three"), 8223 V128, VecListThree128>; 8224 def : SIMDTableLookupAlias<asm # ".16b", 8225 !cast<Instruction>(NAME#"v16i8Four"), 8226 V128, VecListFour128>; 8227} 8228 8229//---------------------------------------------------------------------------- 8230// AdvSIMD LUT 8231//---------------------------------------------------------------------------- 8232let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8233class BaseSIMDTableLookupIndexed<bit Q, bits<5> opc, RegisterOperand vectype, 8234 RegisterOperand listtype, Operand idx_type, 8235 string asm, string kind> 8236 : I<(outs vectype:$Rd), 8237 (ins listtype:$Rn, vectype:$Rm, idx_type:$idx), 8238 asm, "\t$Rd" # kind # ", $Rn, $Rm$idx", "", []>, 8239 Sched<[]> { 8240 bits<5> Rd; 8241 bits<5> Rn; 8242 bits<5> Rm; 8243 let Inst{31} = 0; 8244 let Inst{30} = Q; 8245 let Inst{29-24} = 0b001110; 8246 let Inst{23-22} = opc{4-3}; 8247 let Inst{21} = 0; 8248 let Inst{20-16} = Rm; 8249 let Inst{15} = 0; 8250 let Inst{14-12} = opc{2-0}; 8251 let Inst{11-10} = 0b00; 8252 let Inst{9-5} = Rn; 8253 let Inst{4-0} = Rd; 8254} 8255 8256multiclass BaseSIMDTableLookupIndexed2<string asm> { 8257 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, V128, VecListOne16b, VectorIndexS, asm, ".16b"> { 8258 bits<2> idx; 8259 let Inst{14-13} = idx; 8260 } 8261 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, V128, VecListOne8h, VectorIndexH, asm, ".8h" > { 8262 bits<3> idx; 8263 let Inst{14-12} = idx; 8264 } 8265} 8266 8267multiclass BaseSIMDTableLookupIndexed4<string asm> { 8268 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, V128, VecListOne16b, VectorIndexD, asm, ".16b"> { 8269 bit idx; 8270 let Inst{14} = idx; 8271 } 8272 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, V128, VecListTwo8h, VectorIndexS, asm, ".8h" > { 8273 bits<2> idx; 8274 let Inst{14-13} = idx; 8275 } 8276} 8277 8278//---------------------------------------------------------------------------- 8279// AdvSIMD scalar DUP 8280//---------------------------------------------------------------------------- 8281let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8282class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 8283 string asm, string kind, Operand idxtype> 8284 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 8285 "{\t$dst, $src" # kind # "$idx" # 8286 "|\t$dst, $src$idx}", "", []>, 8287 Sched<[WriteVd]> { 8288 bits<5> dst; 8289 bits<5> src; 8290 let Inst{31-21} = 0b01011110000; 8291 let Inst{15-10} = 0b000001; 8292 let Inst{9-5} = src; 8293 let Inst{4-0} = dst; 8294} 8295 8296class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 8297 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 8298 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 8299 # "|\t$dst, $src$index}", 8300 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 8301 8302 8303multiclass SIMDScalarDUP<string asm> { 8304 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 8305 bits<4> idx; 8306 let Inst{20-17} = idx; 8307 let Inst{16} = 1; 8308 } 8309 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 8310 bits<3> idx; 8311 let Inst{20-18} = idx; 8312 let Inst{17-16} = 0b10; 8313 } 8314 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 8315 bits<2> idx; 8316 let Inst{20-19} = idx; 8317 let Inst{18-16} = 0b100; 8318 } 8319 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 8320 bits<1> idx; 8321 let Inst{20} = idx; 8322 let Inst{19-16} = 0b1000; 8323 } 8324 8325 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 8326 VectorIndexD:$idx)))), 8327 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 8328 8329 // 'DUP' mnemonic aliases. 8330 def : SIMDScalarDUPAlias<"dup", ".b", 8331 !cast<Instruction>(NAME#"i8"), 8332 FPR8, V128, VectorIndexB>; 8333 def : SIMDScalarDUPAlias<"dup", ".h", 8334 !cast<Instruction>(NAME#"i16"), 8335 FPR16, V128, VectorIndexH>; 8336 def : SIMDScalarDUPAlias<"dup", ".s", 8337 !cast<Instruction>(NAME#"i32"), 8338 FPR32, V128, VectorIndexS>; 8339 def : SIMDScalarDUPAlias<"dup", ".d", 8340 !cast<Instruction>(NAME#"i64"), 8341 FPR64, V128, VectorIndexD>; 8342} 8343 8344//---------------------------------------------------------------------------- 8345// AdvSIMD modified immediate instructions 8346//---------------------------------------------------------------------------- 8347 8348class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 8349 string asm, string op_string, 8350 string cstr, list<dag> pattern> 8351 : I<oops, iops, asm, op_string, cstr, pattern>, 8352 Sched<[!if(Q, WriteVq, WriteVd)]> { 8353 bits<5> Rd; 8354 bits<8> imm8; 8355 let Inst{31} = 0; 8356 let Inst{30} = Q; 8357 let Inst{29} = op; 8358 let Inst{28-19} = 0b0111100000; 8359 let Inst{18-16} = imm8{7-5}; 8360 let Inst{11} = op2; 8361 let Inst{10} = 1; 8362 let Inst{9-5} = imm8{4-0}; 8363 let Inst{4-0} = Rd; 8364} 8365 8366class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 8367 Operand immtype, dag opt_shift_iop, 8368 string opt_shift, string asm, string kind, 8369 list<dag> pattern> 8370 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 8371 !con((ins immtype:$imm8), opt_shift_iop), asm, 8372 "{\t$Rd" # kind # ", $imm8" # opt_shift # 8373 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8374 "", pattern> { 8375 let DecoderMethod = "DecodeModImmInstruction"; 8376} 8377 8378class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 8379 Operand immtype, dag opt_shift_iop, 8380 string opt_shift, string asm, string kind, 8381 list<dag> pattern> 8382 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 8383 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 8384 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 8385 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8386 "$Rd = $dst", pattern> { 8387 let DecoderMethod = "DecodeModImmTiedInstruction"; 8388} 8389 8390class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 8391 RegisterOperand vectype, string asm, 8392 string kind, list<dag> pattern> 8393 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8394 (ins logical_vec_shift:$shift), 8395 "$shift", asm, kind, pattern> { 8396 bits<2> shift; 8397 let Inst{15} = b15_b12{1}; 8398 let Inst{14-13} = shift; 8399 let Inst{12} = b15_b12{0}; 8400} 8401 8402class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 8403 RegisterOperand vectype, string asm, 8404 string kind, list<dag> pattern> 8405 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8406 (ins logical_vec_shift:$shift), 8407 "$shift", asm, kind, pattern> { 8408 bits<2> shift; 8409 let Inst{15} = b15_b12{1}; 8410 let Inst{14-13} = shift; 8411 let Inst{12} = b15_b12{0}; 8412} 8413 8414 8415class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 8416 RegisterOperand vectype, string asm, 8417 string kind, list<dag> pattern> 8418 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8419 (ins logical_vec_hw_shift:$shift), 8420 "$shift", asm, kind, pattern> { 8421 bits<2> shift; 8422 let Inst{15} = b15_b12{1}; 8423 let Inst{14} = 0; 8424 let Inst{13} = shift{0}; 8425 let Inst{12} = b15_b12{0}; 8426} 8427 8428class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 8429 RegisterOperand vectype, string asm, 8430 string kind, list<dag> pattern> 8431 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8432 (ins logical_vec_hw_shift:$shift), 8433 "$shift", asm, kind, pattern> { 8434 bits<2> shift; 8435 let Inst{15} = b15_b12{1}; 8436 let Inst{14} = 0; 8437 let Inst{13} = shift{0}; 8438 let Inst{12} = b15_b12{0}; 8439} 8440 8441multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 8442 string asm> { 8443 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 8444 asm, ".4h", []>; 8445 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 8446 asm, ".8h", []>; 8447 8448 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 8449 asm, ".2s", []>; 8450 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 8451 asm, ".4s", []>; 8452} 8453 8454multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 8455 bits<2> w_cmode, string asm, 8456 SDNode OpNode> { 8457 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 8458 asm, ".4h", 8459 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 8460 imm0_255:$imm8, 8461 (i32 imm:$shift)))]>; 8462 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 8463 asm, ".8h", 8464 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 8465 imm0_255:$imm8, 8466 (i32 imm:$shift)))]>; 8467 8468 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 8469 asm, ".2s", 8470 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 8471 imm0_255:$imm8, 8472 (i32 imm:$shift)))]>; 8473 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 8474 asm, ".4s", 8475 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 8476 imm0_255:$imm8, 8477 (i32 imm:$shift)))]>; 8478} 8479 8480class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 8481 RegisterOperand vectype, string asm, 8482 string kind, list<dag> pattern> 8483 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8484 (ins move_vec_shift:$shift), 8485 "$shift", asm, kind, pattern> { 8486 bits<1> shift; 8487 let Inst{15-13} = cmode{3-1}; 8488 let Inst{12} = shift; 8489} 8490 8491class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 8492 RegisterOperand vectype, 8493 Operand imm_type, string asm, 8494 string kind, list<dag> pattern> 8495 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 8496 asm, kind, pattern> { 8497 let Inst{15-12} = cmode; 8498} 8499 8500class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 8501 list<dag> pattern> 8502 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 8503 "\t$Rd, $imm8", "", pattern> { 8504 let Inst{15-12} = cmode; 8505 let DecoderMethod = "DecodeModImmInstruction"; 8506} 8507 8508//---------------------------------------------------------------------------- 8509// AdvSIMD indexed element 8510//---------------------------------------------------------------------------- 8511 8512let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8513class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8514 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8515 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8516 string apple_kind, string dst_kind, string lhs_kind, 8517 string rhs_kind, list<dag> pattern> 8518 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8519 asm, 8520 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8521 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8522 Sched<[WriteVd]> { 8523 bits<5> Rd; 8524 bits<5> Rn; 8525 bits<5> Rm; 8526 8527 let Inst{31} = 0; 8528 let Inst{30} = Q; 8529 let Inst{29} = U; 8530 let Inst{28} = Scalar; 8531 let Inst{27-24} = 0b1111; 8532 let Inst{23-22} = size; 8533 // Bit 21 must be set by the derived class. 8534 let Inst{20-16} = Rm; 8535 let Inst{15-12} = opc; 8536 // Bit 11 must be set by the derived class. 8537 let Inst{10} = 0; 8538 let Inst{9-5} = Rn; 8539 let Inst{4-0} = Rd; 8540} 8541 8542let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8543class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8544 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8545 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8546 string apple_kind, string dst_kind, string lhs_kind, 8547 string rhs_kind, list<dag> pattern> 8548 : I<(outs dst_reg:$dst), 8549 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8550 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8551 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8552 Sched<[WriteVd]> { 8553 bits<5> Rd; 8554 bits<5> Rn; 8555 bits<5> Rm; 8556 8557 let Inst{31} = 0; 8558 let Inst{30} = Q; 8559 let Inst{29} = U; 8560 let Inst{28} = Scalar; 8561 let Inst{27-24} = 0b1111; 8562 let Inst{23-22} = size; 8563 // Bit 21 must be set by the derived class. 8564 let Inst{20-16} = Rm; 8565 let Inst{15-12} = opc; 8566 // Bit 11 must be set by the derived class. 8567 let Inst{10} = 0; 8568 let Inst{9-5} = Rn; 8569 let Inst{4-0} = Rd; 8570} 8571 8572 8573//---------------------------------------------------------------------------- 8574// Armv8.6 BFloat16 Extension 8575//---------------------------------------------------------------------------- 8576let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8577 8578class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8579 string kind2, RegisterOperand RegType, 8580 ValueType AccumType, ValueType InputType> 8581 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8582 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8583 (InputType RegType:$Rn), 8584 (InputType RegType:$Rm)))]> { 8585 let AsmString = !strconcat(asm, 8586 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8587 ", $Rm" # kind2 # "}"); 8588} 8589 8590multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8591 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8592 v2f32, v4bf16>; 8593 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8594 v4f32, v8bf16>; 8595} 8596 8597class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8598 string dst_kind, string lhs_kind, 8599 string rhs_kind, 8600 RegisterOperand RegType, 8601 ValueType AccumType, 8602 ValueType InputType> 8603 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8604 RegType, RegType, V128, VectorIndexS, 8605 asm, "", dst_kind, lhs_kind, rhs_kind, 8606 [(set (AccumType RegType:$dst), 8607 (AccumType (int_aarch64_neon_bfdot 8608 (AccumType RegType:$Rd), 8609 (InputType RegType:$Rn), 8610 (InputType (bitconvert (AccumType 8611 (AArch64duplane32 (v4f32 V128:$Rm), 8612 VectorIndexS:$idx)))))))]> { 8613 8614 bits<2> idx; 8615 let Inst{21} = idx{0}; // L 8616 let Inst{11} = idx{1}; // H 8617} 8618 8619multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8620 8621 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8622 ".2h", V64, v2f32, v4bf16>; 8623 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8624 ".2h", V128, v4f32, v8bf16>; 8625} 8626 8627let mayRaiseFPException = 1, Uses = [FPCR] in 8628class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8629 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8630 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8631 (v8bf16 V128:$Rn), 8632 (v8bf16 V128:$Rm)))]> { 8633 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8634} 8635 8636let mayRaiseFPException = 1, Uses = [FPCR] in 8637class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8638 : I<(outs V128:$dst), 8639 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8640 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8641 [(set (v4f32 V128:$dst), 8642 (v4f32 (OpNode (v4f32 V128:$Rd), 8643 (v8bf16 V128:$Rn), 8644 (v8bf16 8645 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8646 VectorIndexH:$idx)))))]>, 8647 Sched<[WriteVq]> { 8648 bits<5> Rd; 8649 bits<5> Rn; 8650 bits<4> Rm; 8651 bits<3> idx; 8652 8653 let Inst{31} = 0; 8654 let Inst{30} = Q; 8655 let Inst{29-22} = 0b00111111; 8656 let Inst{21-20} = idx{1-0}; 8657 let Inst{19-16} = Rm; 8658 let Inst{15-12} = 0b1111; 8659 let Inst{11} = idx{2}; // H 8660 let Inst{10} = 0; 8661 let Inst{9-5} = Rn; 8662 let Inst{4-0} = Rd; 8663} 8664 8665class SIMDThreeSameVectorBF16MatrixMul<string asm> 8666 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8667 V128, asm, ".4s", 8668 [(set (v4f32 V128:$dst), 8669 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8670 (v8bf16 V128:$Rn), 8671 (v8bf16 V128:$Rm)))]> { 8672 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8673 ", $Rm", ".8h", "}"); 8674} 8675 8676let mayRaiseFPException = 1, Uses = [FPCR] in 8677class SIMD_BFCVTN 8678 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8679 "bfcvtn", ".4h", ".4s", 8680 [(set (v8bf16 V128:$Rd), 8681 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8682 8683let mayRaiseFPException = 1, Uses = [FPCR] in 8684class SIMD_BFCVTN2 8685 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8686 "bfcvtn2", ".8h", ".4s", 8687 [(set (v8bf16 V128:$dst), 8688 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8689 8690let mayRaiseFPException = 1, Uses = [FPCR] in 8691class BF16ToSinglePrecision<string asm> 8692 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8693 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8694 Sched<[WriteFCvt]> { 8695 bits<5> Rd; 8696 bits<5> Rn; 8697 let Inst{31-10} = 0b0001111001100011010000; 8698 let Inst{9-5} = Rn; 8699 let Inst{4-0} = Rd; 8700} 8701} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8702 8703//---------------------------------------------------------------------------- 8704class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc, 8705 string asm, string dst_kind, 8706 RegisterOperand RegType, 8707 RegisterOperand RegType_lo> 8708 : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc, 8709 RegType, RegType, RegType_lo, VectorIndexB, 8710 asm, "", dst_kind, ".16b", ".b", []> { 8711 8712 // idx = H:L:M 8713 bits<4> idx; 8714 let Inst{11} = idx{3}; 8715 let Inst{21-19} = idx{2-0}; 8716} 8717 8718multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm> { 8719 def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h", 8720 V128, V128_0to7>; 8721} 8722 8723multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm> { 8724 def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s", 8725 V128, V128_0to7>; 8726} 8727 8728//---------------------------------------------------------------------------- 8729// Armv8.6 Matrix Multiply Extension 8730//---------------------------------------------------------------------------- 8731 8732class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8733 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8734 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8735 (v16i8 V128:$Rn), 8736 (v16i8 V128:$Rm)))]> { 8737 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8738} 8739 8740//---------------------------------------------------------------------------- 8741// ARMv8.2-A Dot Product Instructions (Indexed) 8742class BaseSIMDThreeSameVectorIndexS<bit Q, bit U, bits<2> size, bits<4> opc, string asm, 8743 string dst_kind, string lhs_kind, string rhs_kind, 8744 RegisterOperand RegType, 8745 ValueType AccumType, ValueType InputType, 8746 SDPatternOperator OpNode> : 8747 BaseSIMDIndexedTied<Q, U, 0b0, size, opc, RegType, RegType, V128, 8748 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8749 [(set (AccumType RegType:$dst), 8750 (AccumType (OpNode (AccumType RegType:$Rd), 8751 (InputType RegType:$Rn), 8752 (InputType (bitconvert (AccumType 8753 (AArch64duplane32 (v4i32 V128:$Rm), 8754 VectorIndexS:$idx)))))))]> { 8755 bits<2> idx; 8756 let Inst{21} = idx{0}; // L 8757 let Inst{11} = idx{1}; // H 8758} 8759 8760multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8761 SDPatternOperator OpNode> { 8762 def v8i8 : BaseSIMDThreeSameVectorIndexS<0, U, size, {0b111, Mixed}, asm, ".2s", ".8b", ".4b", 8763 V64, v2i32, v8i8, OpNode>; 8764 def v16i8 : BaseSIMDThreeSameVectorIndexS<1, U, size, {0b111, Mixed}, asm, ".4s", ".16b", ".4b", 8765 V128, v4i32, v16i8, OpNode>; 8766} 8767 8768// TODO: The vectors v8i8 and v16i8 should be v8f8 and v16f8 8769multiclass SIMDThreeSameVectorFP8DOT4Index<string asm> { 8770 def v8f8 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b00, 0b0000, asm, ".2s", ".8b", ".4b", 8771 V64, v2f32, v8i8, null_frag>; 8772 def v16f8 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b00, 0b0000, asm, ".4s", ".16b",".4b", 8773 V128, v4f32, v16i8, null_frag>; 8774} 8775 8776// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8777let mayRaiseFPException = 1, Uses = [FPCR] in 8778class BaseSIMDThreeSameVectorIndexH<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 8779 string dst_kind, string lhs_kind, 8780 string rhs_kind, RegisterOperand RegType, 8781 RegisterOperand RegType_lo, ValueType AccumType, 8782 ValueType InputType, SDPatternOperator OpNode> : 8783 BaseSIMDIndexedTied<Q, U, 0, sz, opc, RegType, RegType, RegType_lo, 8784 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8785 [(set (AccumType RegType:$dst), 8786 (AccumType (OpNode (AccumType RegType:$Rd), 8787 (InputType RegType:$Rn), 8788 (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm), 8789 VectorIndexH:$idx)))))]> { 8790 // idx = H:L:M 8791 bits<3> idx; 8792 let Inst{11} = idx{2}; // H 8793 let Inst{21} = idx{1}; // L 8794 let Inst{20} = idx{0}; // M 8795} 8796 8797multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8798 SDPatternOperator OpNode> { 8799 def v4f16 : BaseSIMDThreeSameVectorIndexH<0, U, 0b10, opc, asm, ".2s", ".2h", ".h", 8800 V64, V128_lo, v2f32, v4f16, OpNode>; 8801 def v8f16 : BaseSIMDThreeSameVectorIndexH<1, U, 0b10, opc, asm, ".4s", ".4h", ".h", 8802 V128, V128_lo, v4f32, v8f16, OpNode>; 8803} 8804 8805//---------------------------------------------------------------------------- 8806// FP8 Advanced SIMD vector x indexed element 8807// TODO: Replace value types v8i8 and v16i8 by v8f8 and v16f8 8808multiclass SIMDThreeSameVectorFP8DOT2Index<string asm> { 8809 def v4f16 : BaseSIMDThreeSameVectorIndexH<0b0, 0b0, 0b01, 0b0000, asm, ".4h", ".8b", ".2b", 8810 V64, V128_lo, v4f16, v8i8, null_frag>; 8811 def v8f16 : BaseSIMDThreeSameVectorIndexH<0b1, 0b0, 0b01, 0b0000, asm, ".8h", ".16b", ".2b", 8812 V128, V128_lo, v8f16, v8i16, null_frag>; 8813} 8814 8815multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8816 SDPatternOperator OpNode> { 8817 let mayRaiseFPException = 1, Uses = [FPCR] in { 8818 let Predicates = [HasNEON, HasFullFP16] in { 8819 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8820 V64, V64, 8821 V128_lo, VectorIndexH, 8822 asm, ".4h", ".4h", ".4h", ".h", 8823 [(set (v4f16 V64:$Rd), 8824 (OpNode (v4f16 V64:$Rn), 8825 (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8826 bits<3> idx; 8827 let Inst{11} = idx{2}; 8828 let Inst{21} = idx{1}; 8829 let Inst{20} = idx{0}; 8830 } 8831 8832 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8833 V128, V128, 8834 V128_lo, VectorIndexH, 8835 asm, ".8h", ".8h", ".8h", ".h", 8836 [(set (v8f16 V128:$Rd), 8837 (OpNode (v8f16 V128:$Rn), 8838 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8839 bits<3> idx; 8840 let Inst{11} = idx{2}; 8841 let Inst{21} = idx{1}; 8842 let Inst{20} = idx{0}; 8843 } 8844 } // Predicates = [HasNEON, HasFullFP16] 8845 8846 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8847 V64, V64, 8848 V128, VectorIndexS, 8849 asm, ".2s", ".2s", ".2s", ".s", 8850 [(set (v2f32 V64:$Rd), 8851 (OpNode (v2f32 V64:$Rn), 8852 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> { 8853 bits<2> idx; 8854 let Inst{11} = idx{1}; 8855 let Inst{21} = idx{0}; 8856 } 8857 8858 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8859 V128, V128, 8860 V128, VectorIndexS, 8861 asm, ".4s", ".4s", ".4s", ".s", 8862 [(set (v4f32 V128:$Rd), 8863 (OpNode (v4f32 V128:$Rn), 8864 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8865 bits<2> idx; 8866 let Inst{11} = idx{1}; 8867 let Inst{21} = idx{0}; 8868 } 8869 8870 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8871 V128, V128, 8872 V128, VectorIndexD, 8873 asm, ".2d", ".2d", ".2d", ".d", 8874 [(set (v2f64 V128:$Rd), 8875 (OpNode (v2f64 V128:$Rn), 8876 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8877 bits<1> idx; 8878 let Inst{11} = idx{0}; 8879 let Inst{21} = 0; 8880 } 8881 8882 let Predicates = [HasNEON, HasFullFP16] in { 8883 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8884 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8885 asm, ".h", "", "", ".h", 8886 [(set (f16 FPR16Op:$Rd), 8887 (OpNode (f16 FPR16Op:$Rn), 8888 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8889 VectorIndexH:$idx))))]> { 8890 bits<3> idx; 8891 let Inst{11} = idx{2}; 8892 let Inst{21} = idx{1}; 8893 let Inst{20} = idx{0}; 8894 } 8895 } // Predicates = [HasNEON, HasFullFP16] 8896 8897 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8898 FPR32Op, FPR32Op, V128, VectorIndexS, 8899 asm, ".s", "", "", ".s", 8900 [(set (f32 FPR32Op:$Rd), 8901 (OpNode (f32 FPR32Op:$Rn), 8902 (f32 (vector_extract (v4f32 V128:$Rm), 8903 VectorIndexS:$idx))))]> { 8904 bits<2> idx; 8905 let Inst{11} = idx{1}; 8906 let Inst{21} = idx{0}; 8907 } 8908 8909 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8910 FPR64Op, FPR64Op, V128, VectorIndexD, 8911 asm, ".d", "", "", ".d", 8912 [(set (f64 FPR64Op:$Rd), 8913 (OpNode (f64 FPR64Op:$Rn), 8914 (f64 (vector_extract (v2f64 V128:$Rm), 8915 VectorIndexD:$idx))))]> { 8916 bits<1> idx; 8917 let Inst{11} = idx{0}; 8918 let Inst{21} = 0; 8919 } 8920 } // mayRaiseFPException = 1, Uses = [FPCR] 8921 8922 let Predicates = [HasNEON, HasFullFP16] in { 8923 def : Pat<(f16 (OpNode 8924 (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))), 8925 (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))), 8926 (!cast<Instruction>(NAME # v1i16_indexed) 8927 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128:$Rm, VectorIndexH:$idx)>; 8928 } 8929 8930 let Predicates = [HasNEON] in { 8931 def : Pat<(f32 (OpNode 8932 (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))), 8933 (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))), 8934 (!cast<Instruction>(NAME # v1i32_indexed) 8935 (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>; 8936 8937 def : Pat<(f64 (OpNode 8938 (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))), 8939 (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))), 8940 (!cast<Instruction>(NAME # v1i64_indexed) 8941 (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>; 8942 } 8943} 8944 8945multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8946 let Predicates = [HasNEON, HasFullFP16] in { 8947 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8948 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8949 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8950 VectorIndexH:$idx))), 8951 (!cast<Instruction>(INST # "v8i16_indexed") 8952 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8953 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8954 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8955 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8956 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8957 8958 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8959 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8960 VectorIndexH:$idx))), 8961 (!cast<Instruction>(INST # "v4i16_indexed") 8962 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8963 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8964 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8965 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8966 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8967 8968 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8969 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8970 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8971 V128_lo:$Rm, VectorIndexH:$idx)>; 8972 } // Predicates = [HasNEON, HasFullFP16] 8973 8974 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8975 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8976 (AArch64duplane32 (v4f32 V128:$Rm), 8977 VectorIndexS:$idx))), 8978 (!cast<Instruction>(INST # v2i32_indexed) 8979 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8980 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8981 (AArch64dup (f32 FPR32Op:$Rm)))), 8982 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8983 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8984 8985 8986 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8987 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8988 (AArch64duplane32 (v4f32 V128:$Rm), 8989 VectorIndexS:$idx))), 8990 (!cast<Instruction>(INST # "v4i32_indexed") 8991 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8992 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8993 (AArch64dup (f32 FPR32Op:$Rm)))), 8994 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8995 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8996 8997 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 8998 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 8999 (AArch64duplane64 (v2f64 V128:$Rm), 9000 VectorIndexD:$idx))), 9001 (!cast<Instruction>(INST # "v2i64_indexed") 9002 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 9003 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 9004 (AArch64dup (f64 FPR64Op:$Rm)))), 9005 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 9006 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 9007 9008 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 9009 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 9010 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 9011 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 9012 V128:$Rm, VectorIndexS:$idx)>; 9013 9014 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 9015 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 9016 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 9017 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 9018 V128:$Rm, VectorIndexD:$idx)>; 9019} 9020 9021let mayRaiseFPException = 1, Uses = [FPCR] in 9022multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 9023 let Predicates = [HasNEON, HasFullFP16] in { 9024 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 9025 V128_lo, VectorIndexH, 9026 asm, ".4h", ".4h", ".4h", ".h", []> { 9027 bits<3> idx; 9028 let Inst{11} = idx{2}; 9029 let Inst{21} = idx{1}; 9030 let Inst{20} = idx{0}; 9031 } 9032 9033 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 9034 V128, V128, 9035 V128_lo, VectorIndexH, 9036 asm, ".8h", ".8h", ".8h", ".h", []> { 9037 bits<3> idx; 9038 let Inst{11} = idx{2}; 9039 let Inst{21} = idx{1}; 9040 let Inst{20} = idx{0}; 9041 } 9042 } // Predicates = [HasNEON, HasFullFP16] 9043 9044 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 9045 V128, VectorIndexS, 9046 asm, ".2s", ".2s", ".2s", ".s", []> { 9047 bits<2> idx; 9048 let Inst{11} = idx{1}; 9049 let Inst{21} = idx{0}; 9050 } 9051 9052 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9053 V128, V128, 9054 V128, VectorIndexS, 9055 asm, ".4s", ".4s", ".4s", ".s", []> { 9056 bits<2> idx; 9057 let Inst{11} = idx{1}; 9058 let Inst{21} = idx{0}; 9059 } 9060 9061 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 9062 V128, V128, 9063 V128, VectorIndexD, 9064 asm, ".2d", ".2d", ".2d", ".d", []> { 9065 bits<1> idx; 9066 let Inst{11} = idx{0}; 9067 let Inst{21} = 0; 9068 } 9069 9070 let Predicates = [HasNEON, HasFullFP16] in { 9071 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 9072 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9073 asm, ".h", "", "", ".h", []> { 9074 bits<3> idx; 9075 let Inst{11} = idx{2}; 9076 let Inst{21} = idx{1}; 9077 let Inst{20} = idx{0}; 9078 } 9079 } // Predicates = [HasNEON, HasFullFP16] 9080 9081 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9082 FPR32Op, FPR32Op, V128, VectorIndexS, 9083 asm, ".s", "", "", ".s", []> { 9084 bits<2> idx; 9085 let Inst{11} = idx{1}; 9086 let Inst{21} = idx{0}; 9087 } 9088 9089 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 9090 FPR64Op, FPR64Op, V128, VectorIndexD, 9091 asm, ".d", "", "", ".d", []> { 9092 bits<1> idx; 9093 let Inst{11} = idx{0}; 9094 let Inst{21} = 0; 9095 } 9096} 9097 9098multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 9099 SDPatternOperator OpNodeLaneQ> { 9100 9101 def : Pat<(v4i16 (OpNodeLane 9102 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 9103 VectorIndexS32b:$idx)), 9104 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 9105 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 9106 (UImmS1XForm $idx))>; 9107 9108 def : Pat<(v4i16 (OpNodeLaneQ 9109 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 9110 VectorIndexH32b:$idx)), 9111 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 9112 (UImmS1XForm $idx))>; 9113 9114 def : Pat<(v8i16 (OpNodeLane 9115 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 9116 VectorIndexS32b:$idx)), 9117 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 9118 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9119 (UImmS1XForm $idx))>; 9120 9121 def : Pat<(v8i16 (OpNodeLaneQ 9122 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 9123 VectorIndexH32b:$idx)), 9124 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 9125 (UImmS1XForm $idx))>; 9126 9127 def : Pat<(v2i32 (OpNodeLane 9128 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 9129 VectorIndexD32b:$idx)), 9130 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 9131 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 9132 (UImmS1XForm $idx))>; 9133 9134 def : Pat<(v2i32 (OpNodeLaneQ 9135 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 9136 VectorIndexS32b:$idx)), 9137 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 9138 (UImmS1XForm $idx))>; 9139 9140 def : Pat<(v4i32 (OpNodeLane 9141 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 9142 VectorIndexD32b:$idx)), 9143 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 9144 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9145 (UImmS1XForm $idx))>; 9146 9147 def : Pat<(v4i32 (OpNodeLaneQ 9148 (v4i32 V128:$Rn), 9149 (v4i32 V128:$Rm), 9150 VectorIndexS32b:$idx)), 9151 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 9152 (UImmS1XForm $idx))>; 9153 9154} 9155 9156multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 9157 SDPatternOperator OpNode> { 9158 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 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 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9208 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9209 asm, ".h", "", "", ".h", []> { 9210 bits<3> idx; 9211 let Inst{11} = idx{2}; 9212 let Inst{21} = idx{1}; 9213 let Inst{20} = idx{0}; 9214 } 9215 9216 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9217 FPR32Op, FPR32Op, V128, VectorIndexS, 9218 asm, ".s", "", "", ".s", 9219 [(set (i32 FPR32Op:$Rd), 9220 (OpNode FPR32Op:$Rn, 9221 (i32 (vector_extract (v4i32 V128:$Rm), 9222 VectorIndexS:$idx))))]> { 9223 bits<2> idx; 9224 let Inst{11} = idx{1}; 9225 let Inst{21} = idx{0}; 9226 } 9227} 9228 9229multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 9230 SDPatternOperator OpNode> { 9231 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9232 V64, V64, 9233 V128_lo, VectorIndexH, 9234 asm, ".4h", ".4h", ".4h", ".h", 9235 [(set (v4i16 V64:$Rd), 9236 (OpNode (v4i16 V64:$Rn), 9237 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9238 bits<3> idx; 9239 let Inst{11} = idx{2}; 9240 let Inst{21} = idx{1}; 9241 let Inst{20} = idx{0}; 9242 } 9243 9244 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9245 V128, V128, 9246 V128_lo, VectorIndexH, 9247 asm, ".8h", ".8h", ".8h", ".h", 9248 [(set (v8i16 V128:$Rd), 9249 (OpNode (v8i16 V128:$Rn), 9250 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9251 bits<3> idx; 9252 let Inst{11} = idx{2}; 9253 let Inst{21} = idx{1}; 9254 let Inst{20} = idx{0}; 9255 } 9256 9257 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9258 V64, V64, 9259 V128, VectorIndexS, 9260 asm, ".2s", ".2s", ".2s", ".s", 9261 [(set (v2i32 V64:$Rd), 9262 (OpNode (v2i32 V64:$Rn), 9263 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9264 bits<2> idx; 9265 let Inst{11} = idx{1}; 9266 let Inst{21} = idx{0}; 9267 } 9268 9269 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9270 V128, V128, 9271 V128, VectorIndexS, 9272 asm, ".4s", ".4s", ".4s", ".s", 9273 [(set (v4i32 V128:$Rd), 9274 (OpNode (v4i32 V128:$Rn), 9275 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9276 bits<2> idx; 9277 let Inst{11} = idx{1}; 9278 let Inst{21} = idx{0}; 9279 } 9280} 9281 9282multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 9283 SDPatternOperator OpNode> { 9284 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 9285 V128_lo, VectorIndexH, 9286 asm, ".4h", ".4h", ".4h", ".h", 9287 [(set (v4i16 V64:$dst), 9288 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 9289 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9290 bits<3> idx; 9291 let Inst{11} = idx{2}; 9292 let Inst{21} = idx{1}; 9293 let Inst{20} = idx{0}; 9294 } 9295 9296 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9297 V128, V128, 9298 V128_lo, VectorIndexH, 9299 asm, ".8h", ".8h", ".8h", ".h", 9300 [(set (v8i16 V128:$dst), 9301 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9302 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9303 bits<3> idx; 9304 let Inst{11} = idx{2}; 9305 let Inst{21} = idx{1}; 9306 let Inst{20} = idx{0}; 9307 } 9308 9309 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9310 V64, V64, 9311 V128, VectorIndexS, 9312 asm, ".2s", ".2s", ".2s", ".s", 9313 [(set (v2i32 V64:$dst), 9314 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9315 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9316 bits<2> idx; 9317 let Inst{11} = idx{1}; 9318 let Inst{21} = idx{0}; 9319 } 9320 9321 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9322 V128, V128, 9323 V128, VectorIndexS, 9324 asm, ".4s", ".4s", ".4s", ".s", 9325 [(set (v4i32 V128:$dst), 9326 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9327 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9328 bits<2> idx; 9329 let Inst{11} = idx{1}; 9330 let Inst{21} = idx{0}; 9331 } 9332} 9333 9334multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 9335 SDPatternOperator OpNode> { 9336 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9337 V128, V64, 9338 V128_lo, VectorIndexH, 9339 asm, ".4s", ".4s", ".4h", ".h", 9340 [(set (v4i32 V128:$Rd), 9341 (OpNode (v4i16 V64:$Rn), 9342 (dup_v8i16 (v8i16 V128_lo:$Rm), 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 : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9350 V128, V128, 9351 V128_lo, VectorIndexH, 9352 asm#"2", ".4s", ".4s", ".8h", ".h", 9353 [(set (v4i32 V128:$Rd), 9354 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9355 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9356 9357 bits<3> idx; 9358 let Inst{11} = idx{2}; 9359 let Inst{21} = idx{1}; 9360 let Inst{20} = idx{0}; 9361 } 9362 9363 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9364 V128, V64, 9365 V128, VectorIndexS, 9366 asm, ".2d", ".2d", ".2s", ".s", 9367 [(set (v2i64 V128:$Rd), 9368 (OpNode (v2i32 V64:$Rn), 9369 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9370 bits<2> idx; 9371 let Inst{11} = idx{1}; 9372 let Inst{21} = idx{0}; 9373 } 9374 9375 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9376 V128, V128, 9377 V128, VectorIndexS, 9378 asm#"2", ".2d", ".2d", ".4s", ".s", 9379 [(set (v2i64 V128:$Rd), 9380 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9381 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9382 bits<2> idx; 9383 let Inst{11} = idx{1}; 9384 let Inst{21} = idx{0}; 9385 } 9386 9387 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9388 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9389 asm, ".h", "", "", ".h", []> { 9390 bits<3> idx; 9391 let Inst{11} = idx{2}; 9392 let Inst{21} = idx{1}; 9393 let Inst{20} = idx{0}; 9394 } 9395 9396 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9397 FPR64Op, FPR32Op, V128, VectorIndexS, 9398 asm, ".s", "", "", ".s", []> { 9399 bits<2> idx; 9400 let Inst{11} = idx{1}; 9401 let Inst{21} = idx{0}; 9402 } 9403} 9404 9405multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 9406 SDPatternOperator Accum> { 9407 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9408 V128, V64, 9409 V128_lo, VectorIndexH, 9410 asm, ".4s", ".4s", ".4h", ".h", 9411 [(set (v4i32 V128:$dst), 9412 (Accum (v4i32 V128:$Rd), 9413 (v4i32 (int_aarch64_neon_sqdmull 9414 (v4i16 V64:$Rn), 9415 (dup_v8i16 (v8i16 V128_lo:$Rm), 9416 VectorIndexH:$idx)))))]> { 9417 bits<3> idx; 9418 let Inst{11} = idx{2}; 9419 let Inst{21} = idx{1}; 9420 let Inst{20} = idx{0}; 9421 } 9422 9423 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9424 V128, V128, 9425 V128_lo, VectorIndexH, 9426 asm#"2", ".4s", ".4s", ".8h", ".h", 9427 [(set (v4i32 V128:$dst), 9428 (Accum (v4i32 V128:$Rd), 9429 (v4i32 (int_aarch64_neon_sqdmull 9430 (extract_high_v8i16 (v8i16 V128:$Rn)), 9431 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 9432 bits<3> idx; 9433 let Inst{11} = idx{2}; 9434 let Inst{21} = idx{1}; 9435 let Inst{20} = idx{0}; 9436 } 9437 9438 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9439 V128, V64, 9440 V128, VectorIndexS, 9441 asm, ".2d", ".2d", ".2s", ".s", 9442 [(set (v2i64 V128:$dst), 9443 (Accum (v2i64 V128:$Rd), 9444 (v2i64 (int_aarch64_neon_sqdmull 9445 (v2i32 V64:$Rn), 9446 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9447 bits<2> idx; 9448 let Inst{11} = idx{1}; 9449 let Inst{21} = idx{0}; 9450 } 9451 9452 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9453 V128, V128, 9454 V128, VectorIndexS, 9455 asm#"2", ".2d", ".2d", ".4s", ".s", 9456 [(set (v2i64 V128:$dst), 9457 (Accum (v2i64 V128:$Rd), 9458 (v2i64 (int_aarch64_neon_sqdmull 9459 (extract_high_v4i32 (v4i32 V128:$Rn)), 9460 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9461 bits<2> idx; 9462 let Inst{11} = idx{1}; 9463 let Inst{21} = idx{0}; 9464 } 9465 9466 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9467 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9468 asm, ".h", "", "", ".h", []> { 9469 bits<3> idx; 9470 let Inst{11} = idx{2}; 9471 let Inst{21} = idx{1}; 9472 let Inst{20} = idx{0}; 9473 } 9474 9475 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9476 (i32 (vector_extract 9477 (v4i32 (int_aarch64_neon_sqdmull 9478 (v4i16 V64:$Rn), 9479 (v4i16 V64:$Rm))), 9480 (i64 0))))), 9481 (!cast<Instruction>(NAME # v1i32_indexed) 9482 FPR32Op:$Rd, 9483 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9484 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub), 9485 (i64 0))>; 9486 9487 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9488 (i32 (vector_extract 9489 (v4i32 (int_aarch64_neon_sqdmull 9490 (v4i16 V64:$Rn), 9491 (dup_v8i16 (v8i16 V128_lo:$Rm), 9492 VectorIndexH:$idx))), 9493 (i64 0))))), 9494 (!cast<Instruction>(NAME # v1i32_indexed) 9495 FPR32Op:$Rd, 9496 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9497 V128_lo:$Rm, 9498 VectorIndexH:$idx)>; 9499 9500 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9501 FPR64Op, FPR32Op, V128, VectorIndexS, 9502 asm, ".s", "", "", ".s", 9503 [(set (i64 FPR64Op:$dst), 9504 (Accum (i64 FPR64Op:$Rd), 9505 (i64 (int_aarch64_neon_sqdmulls_scalar 9506 (i32 FPR32Op:$Rn), 9507 (i32 (vector_extract (v4i32 V128:$Rm), 9508 VectorIndexS:$idx))))))]> { 9509 9510 bits<2> idx; 9511 let Inst{11} = idx{1}; 9512 let Inst{21} = idx{0}; 9513 } 9514} 9515 9516multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 9517 SDPatternOperator OpNode> { 9518 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9519 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9520 V128, V64, 9521 V128_lo, VectorIndexH, 9522 asm, ".4s", ".4s", ".4h", ".h", 9523 [(set (v4i32 V128:$Rd), 9524 (OpNode (v4i16 V64:$Rn), 9525 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9526 bits<3> idx; 9527 let Inst{11} = idx{2}; 9528 let Inst{21} = idx{1}; 9529 let Inst{20} = idx{0}; 9530 } 9531 9532 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9533 V128, V128, 9534 V128_lo, VectorIndexH, 9535 asm#"2", ".4s", ".4s", ".8h", ".h", 9536 [(set (v4i32 V128:$Rd), 9537 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9538 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9539 9540 bits<3> idx; 9541 let Inst{11} = idx{2}; 9542 let Inst{21} = idx{1}; 9543 let Inst{20} = idx{0}; 9544 } 9545 9546 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9547 V128, V64, 9548 V128, VectorIndexS, 9549 asm, ".2d", ".2d", ".2s", ".s", 9550 [(set (v2i64 V128:$Rd), 9551 (OpNode (v2i32 V64:$Rn), 9552 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9553 bits<2> idx; 9554 let Inst{11} = idx{1}; 9555 let Inst{21} = idx{0}; 9556 } 9557 9558 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9559 V128, V128, 9560 V128, VectorIndexS, 9561 asm#"2", ".2d", ".2d", ".4s", ".s", 9562 [(set (v2i64 V128:$Rd), 9563 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9564 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9565 bits<2> idx; 9566 let Inst{11} = idx{1}; 9567 let Inst{21} = idx{0}; 9568 } 9569 } 9570} 9571 9572multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 9573 SDPatternOperator OpNode> { 9574 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9575 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9576 V128, V64, 9577 V128_lo, VectorIndexH, 9578 asm, ".4s", ".4s", ".4h", ".h", 9579 [(set (v4i32 V128:$dst), 9580 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 9581 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9582 bits<3> idx; 9583 let Inst{11} = idx{2}; 9584 let Inst{21} = idx{1}; 9585 let Inst{20} = idx{0}; 9586 } 9587 9588 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9589 V128, V128, 9590 V128_lo, VectorIndexH, 9591 asm#"2", ".4s", ".4s", ".8h", ".h", 9592 [(set (v4i32 V128:$dst), 9593 (OpNode (v4i32 V128:$Rd), 9594 (extract_high_v8i16 (v8i16 V128:$Rn)), 9595 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9596 bits<3> idx; 9597 let Inst{11} = idx{2}; 9598 let Inst{21} = idx{1}; 9599 let Inst{20} = idx{0}; 9600 } 9601 9602 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9603 V128, V64, 9604 V128, VectorIndexS, 9605 asm, ".2d", ".2d", ".2s", ".s", 9606 [(set (v2i64 V128:$dst), 9607 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9608 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9609 bits<2> idx; 9610 let Inst{11} = idx{1}; 9611 let Inst{21} = idx{0}; 9612 } 9613 9614 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9615 V128, V128, 9616 V128, VectorIndexS, 9617 asm#"2", ".2d", ".2d", ".4s", ".s", 9618 [(set (v2i64 V128:$dst), 9619 (OpNode (v2i64 V128:$Rd), 9620 (extract_high_v4i32 (v4i32 V128:$Rn)), 9621 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9622 bits<2> idx; 9623 let Inst{11} = idx{1}; 9624 let Inst{21} = idx{0}; 9625 } 9626 } 9627} 9628 9629//---------------------------------------------------------------------------- 9630// AdvSIMD scalar shift by immediate 9631//---------------------------------------------------------------------------- 9632 9633let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9634class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9635 RegisterClass regtype1, RegisterClass regtype2, 9636 Operand immtype, string asm, list<dag> pattern> 9637 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9638 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9639 Sched<[WriteVd]> { 9640 bits<5> Rd; 9641 bits<5> Rn; 9642 bits<7> imm; 9643 let Inst{31-30} = 0b01; 9644 let Inst{29} = U; 9645 let Inst{28-23} = 0b111110; 9646 let Inst{22-16} = fixed_imm; 9647 let Inst{15-11} = opc; 9648 let Inst{10} = 1; 9649 let Inst{9-5} = Rn; 9650 let Inst{4-0} = Rd; 9651} 9652 9653let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9654class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9655 RegisterClass regtype1, RegisterClass regtype2, 9656 Operand immtype, string asm, list<dag> pattern> 9657 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9658 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9659 Sched<[WriteVd]> { 9660 bits<5> Rd; 9661 bits<5> Rn; 9662 bits<7> imm; 9663 let Inst{31-30} = 0b01; 9664 let Inst{29} = U; 9665 let Inst{28-23} = 0b111110; 9666 let Inst{22-16} = fixed_imm; 9667 let Inst{15-11} = opc; 9668 let Inst{10} = 1; 9669 let Inst{9-5} = Rn; 9670 let Inst{4-0} = Rd; 9671} 9672 9673 9674multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9675 let Predicates = [HasNEON, HasFullFP16] in { 9676 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9677 FPR16, FPR16, vecshiftR16, asm, []> { 9678 let Inst{19-16} = imm{3-0}; 9679 } 9680 } // Predicates = [HasNEON, HasFullFP16] 9681 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9682 FPR32, FPR32, vecshiftR32, asm, []> { 9683 let Inst{20-16} = imm{4-0}; 9684 } 9685 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9686 FPR64, FPR64, vecshiftR64, asm, []> { 9687 let Inst{21-16} = imm{5-0}; 9688 } 9689} 9690 9691multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9692 SDPatternOperator OpNode> { 9693 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9694 FPR64, FPR64, vecshiftR64, asm, 9695 [(set (i64 FPR64:$Rd), 9696 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9697 let Inst{21-16} = imm{5-0}; 9698 } 9699 9700 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9701 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9702} 9703 9704multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9705 SDPatternOperator OpNode = null_frag> { 9706 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9707 FPR64, FPR64, vecshiftR64, asm, 9708 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9709 (i32 vecshiftR64:$imm)))]> { 9710 let Inst{21-16} = imm{5-0}; 9711 } 9712 9713 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9714 (i32 vecshiftR64:$imm))), 9715 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9716 vecshiftR64:$imm)>; 9717} 9718 9719multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9720 SDPatternOperator OpNode> { 9721 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9722 FPR64, FPR64, vecshiftL64, asm, 9723 [(set (i64 FPR64:$Rd), 9724 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9725 let Inst{21-16} = imm{5-0}; 9726 } 9727 9728 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9729 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9730} 9731 9732let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9733multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9734 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9735 FPR64, FPR64, vecshiftL64, asm, []> { 9736 let Inst{21-16} = imm{5-0}; 9737 } 9738} 9739 9740let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9741multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9742 SDPatternOperator OpNode = null_frag> { 9743 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9744 FPR8, FPR16, vecshiftR8, asm, []> { 9745 let Inst{18-16} = imm{2-0}; 9746 } 9747 9748 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9749 FPR16, FPR32, vecshiftR16, asm, []> { 9750 let Inst{19-16} = imm{3-0}; 9751 } 9752 9753 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9754 FPR32, FPR64, vecshiftR32, asm, 9755 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9756 let Inst{20-16} = imm{4-0}; 9757 } 9758} 9759 9760multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9761 SDPatternOperator OpNode> { 9762 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9763 FPR8, FPR8, vecshiftL8, asm, []> { 9764 let Inst{18-16} = imm{2-0}; 9765 } 9766 9767 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9768 FPR16, FPR16, vecshiftL16, asm, []> { 9769 let Inst{19-16} = imm{3-0}; 9770 } 9771 9772 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9773 FPR32, FPR32, vecshiftL32, asm, 9774 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9775 let Inst{20-16} = imm{4-0}; 9776 } 9777 9778 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9779 FPR64, FPR64, vecshiftL64, asm, 9780 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9781 let Inst{21-16} = imm{5-0}; 9782 } 9783 9784 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9785 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9786} 9787 9788multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9789 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9790 FPR8, FPR8, vecshiftR8, asm, []> { 9791 let Inst{18-16} = imm{2-0}; 9792 } 9793 9794 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9795 FPR16, FPR16, vecshiftR16, asm, []> { 9796 let Inst{19-16} = imm{3-0}; 9797 } 9798 9799 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9800 FPR32, FPR32, vecshiftR32, asm, []> { 9801 let Inst{20-16} = imm{4-0}; 9802 } 9803 9804 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9805 FPR64, FPR64, vecshiftR64, asm, []> { 9806 let Inst{21-16} = imm{5-0}; 9807 } 9808} 9809 9810//---------------------------------------------------------------------------- 9811// AdvSIMD vector x indexed element 9812//---------------------------------------------------------------------------- 9813 9814let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9815class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9816 RegisterOperand dst_reg, RegisterOperand src_reg, 9817 Operand immtype, 9818 string asm, string dst_kind, string src_kind, 9819 list<dag> pattern> 9820 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9821 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9822 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9823 Sched<[!if(Q, WriteVq, WriteVd)]> { 9824 bits<5> Rd; 9825 bits<5> Rn; 9826 let Inst{31} = 0; 9827 let Inst{30} = Q; 9828 let Inst{29} = U; 9829 let Inst{28-23} = 0b011110; 9830 let Inst{22-16} = fixed_imm; 9831 let Inst{15-11} = opc; 9832 let Inst{10} = 1; 9833 let Inst{9-5} = Rn; 9834 let Inst{4-0} = Rd; 9835} 9836 9837let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9838class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9839 RegisterOperand vectype1, RegisterOperand vectype2, 9840 Operand immtype, 9841 string asm, string dst_kind, string src_kind, 9842 list<dag> pattern> 9843 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9844 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9845 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9846 Sched<[!if(Q, WriteVq, WriteVd)]> { 9847 bits<5> Rd; 9848 bits<5> Rn; 9849 let Inst{31} = 0; 9850 let Inst{30} = Q; 9851 let Inst{29} = U; 9852 let Inst{28-23} = 0b011110; 9853 let Inst{22-16} = fixed_imm; 9854 let Inst{15-11} = opc; 9855 let Inst{10} = 1; 9856 let Inst{9-5} = Rn; 9857 let Inst{4-0} = Rd; 9858} 9859 9860multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9861 Intrinsic OpNode> { 9862 let Predicates = [HasNEON, HasFullFP16] in { 9863 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9864 V64, V64, vecshiftR16, 9865 asm, ".4h", ".4h", 9866 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9867 bits<4> imm; 9868 let Inst{19-16} = imm; 9869 } 9870 9871 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9872 V128, V128, vecshiftR16, 9873 asm, ".8h", ".8h", 9874 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9875 bits<4> imm; 9876 let Inst{19-16} = imm; 9877 } 9878 } // Predicates = [HasNEON, HasFullFP16] 9879 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9880 V64, V64, vecshiftR32, 9881 asm, ".2s", ".2s", 9882 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9883 bits<5> imm; 9884 let Inst{20-16} = imm; 9885 } 9886 9887 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9888 V128, V128, vecshiftR32, 9889 asm, ".4s", ".4s", 9890 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9891 bits<5> imm; 9892 let Inst{20-16} = imm; 9893 } 9894 9895 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9896 V128, V128, vecshiftR64, 9897 asm, ".2d", ".2d", 9898 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9899 bits<6> imm; 9900 let Inst{21-16} = imm; 9901 } 9902} 9903 9904multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9905 Intrinsic OpNode> { 9906 let Predicates = [HasNEON, HasFullFP16] in { 9907 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9908 V64, V64, vecshiftR16, 9909 asm, ".4h", ".4h", 9910 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9911 bits<4> imm; 9912 let Inst{19-16} = imm; 9913 } 9914 9915 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9916 V128, V128, vecshiftR16, 9917 asm, ".8h", ".8h", 9918 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9919 bits<4> imm; 9920 let Inst{19-16} = imm; 9921 } 9922 } // Predicates = [HasNEON, HasFullFP16] 9923 9924 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9925 V64, V64, vecshiftR32, 9926 asm, ".2s", ".2s", 9927 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9928 bits<5> imm; 9929 let Inst{20-16} = imm; 9930 } 9931 9932 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9933 V128, V128, vecshiftR32, 9934 asm, ".4s", ".4s", 9935 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9936 bits<5> imm; 9937 let Inst{20-16} = imm; 9938 } 9939 9940 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9941 V128, V128, vecshiftR64, 9942 asm, ".2d", ".2d", 9943 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9944 bits<6> imm; 9945 let Inst{21-16} = imm; 9946 } 9947} 9948 9949multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9950 SDPatternOperator OpNode> { 9951 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9952 V64, V128, vecshiftR16Narrow, 9953 asm, ".8b", ".8h", 9954 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9955 bits<3> imm; 9956 let Inst{18-16} = imm; 9957 } 9958 9959 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9960 V128, V128, vecshiftR16Narrow, 9961 asm#"2", ".16b", ".8h", []> { 9962 bits<3> imm; 9963 let Inst{18-16} = imm; 9964 let hasSideEffects = 0; 9965 } 9966 9967 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9968 V64, V128, vecshiftR32Narrow, 9969 asm, ".4h", ".4s", 9970 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9971 bits<4> imm; 9972 let Inst{19-16} = imm; 9973 } 9974 9975 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9976 V128, V128, vecshiftR32Narrow, 9977 asm#"2", ".8h", ".4s", []> { 9978 bits<4> imm; 9979 let Inst{19-16} = imm; 9980 let hasSideEffects = 0; 9981 } 9982 9983 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9984 V64, V128, vecshiftR64Narrow, 9985 asm, ".2s", ".2d", 9986 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9987 bits<5> imm; 9988 let Inst{20-16} = imm; 9989 } 9990 9991 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9992 V128, V128, vecshiftR64Narrow, 9993 asm#"2", ".4s", ".2d", []> { 9994 bits<5> imm; 9995 let Inst{20-16} = imm; 9996 let hasSideEffects = 0; 9997 } 9998 9999 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 10000 // themselves, so put them here instead. 10001 10002 // Patterns involving what's effectively an insert high and a normal 10003 // intrinsic, represented by CONCAT_VECTORS. 10004 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 10005 vecshiftR16Narrow:$imm)), 10006 (!cast<Instruction>(NAME # "v16i8_shift") 10007 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10008 V128:$Rn, vecshiftR16Narrow:$imm)>; 10009 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 10010 vecshiftR32Narrow:$imm)), 10011 (!cast<Instruction>(NAME # "v8i16_shift") 10012 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10013 V128:$Rn, vecshiftR32Narrow:$imm)>; 10014 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 10015 vecshiftR64Narrow:$imm)), 10016 (!cast<Instruction>(NAME # "v4i32_shift") 10017 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10018 V128:$Rn, vecshiftR64Narrow:$imm)>; 10019} 10020 10021multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 10022 SDPatternOperator OpNode> { 10023 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10024 V64, V64, vecshiftL8, 10025 asm, ".8b", ".8b", 10026 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10027 (i32 vecshiftL8:$imm)))]> { 10028 bits<3> imm; 10029 let Inst{18-16} = imm; 10030 } 10031 10032 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10033 V128, V128, vecshiftL8, 10034 asm, ".16b", ".16b", 10035 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10036 (i32 vecshiftL8:$imm)))]> { 10037 bits<3> imm; 10038 let Inst{18-16} = imm; 10039 } 10040 10041 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10042 V64, V64, vecshiftL16, 10043 asm, ".4h", ".4h", 10044 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10045 (i32 vecshiftL16:$imm)))]> { 10046 bits<4> imm; 10047 let Inst{19-16} = imm; 10048 } 10049 10050 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10051 V128, V128, vecshiftL16, 10052 asm, ".8h", ".8h", 10053 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10054 (i32 vecshiftL16:$imm)))]> { 10055 bits<4> imm; 10056 let Inst{19-16} = imm; 10057 } 10058 10059 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10060 V64, V64, vecshiftL32, 10061 asm, ".2s", ".2s", 10062 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10063 (i32 vecshiftL32:$imm)))]> { 10064 bits<5> imm; 10065 let Inst{20-16} = imm; 10066 } 10067 10068 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10069 V128, V128, vecshiftL32, 10070 asm, ".4s", ".4s", 10071 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10072 (i32 vecshiftL32:$imm)))]> { 10073 bits<5> imm; 10074 let Inst{20-16} = imm; 10075 } 10076 10077 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10078 V128, V128, vecshiftL64, 10079 asm, ".2d", ".2d", 10080 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10081 (i32 vecshiftL64:$imm)))]> { 10082 bits<6> imm; 10083 let Inst{21-16} = imm; 10084 } 10085} 10086 10087multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 10088 SDPatternOperator OpNode> { 10089 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10090 V64, V64, vecshiftR8, 10091 asm, ".8b", ".8b", 10092 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10093 (i32 vecshiftR8:$imm)))]> { 10094 bits<3> imm; 10095 let Inst{18-16} = imm; 10096 } 10097 10098 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10099 V128, V128, vecshiftR8, 10100 asm, ".16b", ".16b", 10101 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10102 (i32 vecshiftR8:$imm)))]> { 10103 bits<3> imm; 10104 let Inst{18-16} = imm; 10105 } 10106 10107 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10108 V64, V64, vecshiftR16, 10109 asm, ".4h", ".4h", 10110 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10111 (i32 vecshiftR16:$imm)))]> { 10112 bits<4> imm; 10113 let Inst{19-16} = imm; 10114 } 10115 10116 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10117 V128, V128, vecshiftR16, 10118 asm, ".8h", ".8h", 10119 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10120 (i32 vecshiftR16:$imm)))]> { 10121 bits<4> imm; 10122 let Inst{19-16} = imm; 10123 } 10124 10125 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10126 V64, V64, vecshiftR32, 10127 asm, ".2s", ".2s", 10128 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10129 (i32 vecshiftR32:$imm)))]> { 10130 bits<5> imm; 10131 let Inst{20-16} = imm; 10132 } 10133 10134 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10135 V128, V128, vecshiftR32, 10136 asm, ".4s", ".4s", 10137 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10138 (i32 vecshiftR32:$imm)))]> { 10139 bits<5> imm; 10140 let Inst{20-16} = imm; 10141 } 10142 10143 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10144 V128, V128, vecshiftR64, 10145 asm, ".2d", ".2d", 10146 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10147 (i32 vecshiftR64:$imm)))]> { 10148 bits<6> imm; 10149 let Inst{21-16} = imm; 10150 } 10151} 10152 10153let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10154multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 10155 SDPatternOperator OpNode = null_frag> { 10156 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10157 V64, V64, vecshiftR8, asm, ".8b", ".8b", 10158 [(set (v8i8 V64:$dst), 10159 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10160 (i32 vecshiftR8:$imm)))]> { 10161 bits<3> imm; 10162 let Inst{18-16} = imm; 10163 } 10164 10165 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10166 V128, V128, vecshiftR8, asm, ".16b", ".16b", 10167 [(set (v16i8 V128:$dst), 10168 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10169 (i32 vecshiftR8:$imm)))]> { 10170 bits<3> imm; 10171 let Inst{18-16} = imm; 10172 } 10173 10174 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10175 V64, V64, vecshiftR16, asm, ".4h", ".4h", 10176 [(set (v4i16 V64:$dst), 10177 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10178 (i32 vecshiftR16:$imm)))]> { 10179 bits<4> imm; 10180 let Inst{19-16} = imm; 10181 } 10182 10183 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10184 V128, V128, vecshiftR16, asm, ".8h", ".8h", 10185 [(set (v8i16 V128:$dst), 10186 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10187 (i32 vecshiftR16:$imm)))]> { 10188 bits<4> imm; 10189 let Inst{19-16} = imm; 10190 } 10191 10192 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10193 V64, V64, vecshiftR32, asm, ".2s", ".2s", 10194 [(set (v2i32 V64:$dst), 10195 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10196 (i32 vecshiftR32:$imm)))]> { 10197 bits<5> imm; 10198 let Inst{20-16} = imm; 10199 } 10200 10201 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10202 V128, V128, vecshiftR32, asm, ".4s", ".4s", 10203 [(set (v4i32 V128:$dst), 10204 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10205 (i32 vecshiftR32:$imm)))]> { 10206 bits<5> imm; 10207 let Inst{20-16} = imm; 10208 } 10209 10210 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10211 V128, V128, vecshiftR64, 10212 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 10213 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10214 (i32 vecshiftR64:$imm)))]> { 10215 bits<6> imm; 10216 let Inst{21-16} = imm; 10217 } 10218} 10219 10220multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 10221 SDPatternOperator OpNode = null_frag> { 10222 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10223 V64, V64, vecshiftL8, 10224 asm, ".8b", ".8b", 10225 [(set (v8i8 V64:$dst), 10226 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10227 (i32 vecshiftL8:$imm)))]> { 10228 bits<3> imm; 10229 let Inst{18-16} = imm; 10230 } 10231 10232 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10233 V128, V128, vecshiftL8, 10234 asm, ".16b", ".16b", 10235 [(set (v16i8 V128:$dst), 10236 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10237 (i32 vecshiftL8:$imm)))]> { 10238 bits<3> imm; 10239 let Inst{18-16} = imm; 10240 } 10241 10242 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10243 V64, V64, vecshiftL16, 10244 asm, ".4h", ".4h", 10245 [(set (v4i16 V64:$dst), 10246 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10247 (i32 vecshiftL16:$imm)))]> { 10248 bits<4> imm; 10249 let Inst{19-16} = imm; 10250 } 10251 10252 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10253 V128, V128, vecshiftL16, 10254 asm, ".8h", ".8h", 10255 [(set (v8i16 V128:$dst), 10256 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10257 (i32 vecshiftL16:$imm)))]> { 10258 bits<4> imm; 10259 let Inst{19-16} = imm; 10260 } 10261 10262 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10263 V64, V64, vecshiftL32, 10264 asm, ".2s", ".2s", 10265 [(set (v2i32 V64:$dst), 10266 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10267 (i32 vecshiftL32:$imm)))]> { 10268 bits<5> imm; 10269 let Inst{20-16} = imm; 10270 } 10271 10272 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10273 V128, V128, vecshiftL32, 10274 asm, ".4s", ".4s", 10275 [(set (v4i32 V128:$dst), 10276 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10277 (i32 vecshiftL32:$imm)))]> { 10278 bits<5> imm; 10279 let Inst{20-16} = imm; 10280 } 10281 10282 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10283 V128, V128, vecshiftL64, 10284 asm, ".2d", ".2d", 10285 [(set (v2i64 V128:$dst), 10286 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10287 (i32 vecshiftL64:$imm)))]> { 10288 bits<6> imm; 10289 let Inst{21-16} = imm; 10290 } 10291} 10292 10293multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 10294 SDPatternOperator OpNode> { 10295 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10296 V128, V64, vecshiftL8, asm, ".8h", ".8b", 10297 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 10298 bits<3> imm; 10299 let Inst{18-16} = imm; 10300 } 10301 10302 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10303 V128, V128, vecshiftL8, 10304 asm#"2", ".8h", ".16b", 10305 [(set (v8i16 V128:$Rd), 10306 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 10307 bits<3> imm; 10308 let Inst{18-16} = imm; 10309 } 10310 10311 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10312 V128, V64, vecshiftL16, asm, ".4s", ".4h", 10313 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 10314 bits<4> imm; 10315 let Inst{19-16} = imm; 10316 } 10317 10318 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10319 V128, V128, vecshiftL16, 10320 asm#"2", ".4s", ".8h", 10321 [(set (v4i32 V128:$Rd), 10322 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 10323 10324 bits<4> imm; 10325 let Inst{19-16} = imm; 10326 } 10327 10328 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10329 V128, V64, vecshiftL32, asm, ".2d", ".2s", 10330 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 10331 bits<5> imm; 10332 let Inst{20-16} = imm; 10333 } 10334 10335 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10336 V128, V128, vecshiftL32, 10337 asm#"2", ".2d", ".4s", 10338 [(set (v2i64 V128:$Rd), 10339 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 10340 bits<5> imm; 10341 let Inst{20-16} = imm; 10342 } 10343} 10344 10345 10346//--- 10347// Vector load/store 10348//--- 10349// SIMD ldX/stX no-index memory references don't allow the optional 10350// ", #0" constant and handle post-indexing explicitly, so we use 10351// a more specialized parse method for them. Otherwise, it's the same as 10352// the general GPR64sp handling. 10353 10354class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 10355 string asm, dag oops, dag iops, list<dag> pattern> 10356 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 10357 bits<5> Vt; 10358 bits<5> Rn; 10359 let Inst{31} = 0; 10360 let Inst{30} = Q; 10361 let Inst{29-23} = 0b0011000; 10362 let Inst{22} = L; 10363 let Inst{21-16} = 0b000000; 10364 let Inst{15-12} = opcode; 10365 let Inst{11-10} = size; 10366 let Inst{9-5} = Rn; 10367 let Inst{4-0} = Vt; 10368} 10369 10370class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 10371 string asm, dag oops, dag iops> 10372 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 10373 bits<5> Vt; 10374 bits<5> Rn; 10375 bits<5> Xm; 10376 let Inst{31} = 0; 10377 let Inst{30} = Q; 10378 let Inst{29-23} = 0b0011001; 10379 let Inst{22} = L; 10380 let Inst{21} = 0; 10381 let Inst{20-16} = Xm; 10382 let Inst{15-12} = opcode; 10383 let Inst{11-10} = size; 10384 let Inst{9-5} = Rn; 10385 let Inst{4-0} = Vt; 10386} 10387 10388// The immediate form of AdvSIMD post-indexed addressing is encoded with 10389// register post-index addressing from the zero register. 10390multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 10391 int Offset, int Size> { 10392 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 10393 // "ld1\t$Vt, [$Rn], #16" 10394 // may get mapped to 10395 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 10396 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10397 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10398 GPR64sp:$Rn, 10399 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10400 XZR), 1>; 10401 10402 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 10403 // "ld1.8b\t$Vt, [$Rn], #16" 10404 // may get mapped to 10405 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 10406 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10407 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10408 GPR64sp:$Rn, 10409 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10410 XZR), 0>; 10411 10412 // E.g. "ld1.8b { v0, v1 }, [x1]" 10413 // "ld1\t$Vt, [$Rn]" 10414 // may get mapped to 10415 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 10416 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10417 (!cast<Instruction>(BaseName # Count # "v" # layout) 10418 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10419 GPR64sp:$Rn), 0>; 10420 10421 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 10422 // "ld1\t$Vt, [$Rn], $Xm" 10423 // may get mapped to 10424 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 10425 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10426 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10427 GPR64sp:$Rn, 10428 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10429 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10430} 10431 10432multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 10433 int Offset128, int Offset64, bits<4> opcode> { 10434 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10435 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 10436 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 10437 (ins GPR64sp:$Rn), []>; 10438 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 10439 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 10440 (ins GPR64sp:$Rn), []>; 10441 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 10442 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 10443 (ins GPR64sp:$Rn), []>; 10444 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 10445 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 10446 (ins GPR64sp:$Rn), []>; 10447 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 10448 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 10449 (ins GPR64sp:$Rn), []>; 10450 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 10451 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 10452 (ins GPR64sp:$Rn), []>; 10453 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 10454 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 10455 (ins GPR64sp:$Rn), []>; 10456 10457 10458 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 10459 (outs GPR64sp:$wback, 10460 !cast<RegisterOperand>(veclist # "16b"):$Vt), 10461 (ins GPR64sp:$Rn, 10462 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10463 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 10464 (outs GPR64sp:$wback, 10465 !cast<RegisterOperand>(veclist # "8h"):$Vt), 10466 (ins GPR64sp:$Rn, 10467 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10468 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 10469 (outs GPR64sp:$wback, 10470 !cast<RegisterOperand>(veclist # "4s"):$Vt), 10471 (ins GPR64sp:$Rn, 10472 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10473 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 10474 (outs GPR64sp:$wback, 10475 !cast<RegisterOperand>(veclist # "2d"):$Vt), 10476 (ins GPR64sp:$Rn, 10477 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10478 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 10479 (outs GPR64sp:$wback, 10480 !cast<RegisterOperand>(veclist # "8b"):$Vt), 10481 (ins GPR64sp:$Rn, 10482 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10483 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 10484 (outs GPR64sp:$wback, 10485 !cast<RegisterOperand>(veclist # "4h"):$Vt), 10486 (ins GPR64sp:$Rn, 10487 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10488 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 10489 (outs GPR64sp:$wback, 10490 !cast<RegisterOperand>(veclist # "2s"):$Vt), 10491 (ins GPR64sp:$Rn, 10492 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10493 } 10494 10495 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10496 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10497 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10498 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10499 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10500 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10501 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10502} 10503 10504// Only ld1/st1 has a v1d version. 10505multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 10506 int Offset128, int Offset64, bits<4> opcode> { 10507 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 10508 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 10509 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10510 GPR64sp:$Rn), []>; 10511 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 10512 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10513 GPR64sp:$Rn), []>; 10514 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 10515 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10516 GPR64sp:$Rn), []>; 10517 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 10518 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10519 GPR64sp:$Rn), []>; 10520 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 10521 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10522 GPR64sp:$Rn), []>; 10523 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 10524 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10525 GPR64sp:$Rn), []>; 10526 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 10527 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10528 GPR64sp:$Rn), []>; 10529 10530 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 10531 (outs GPR64sp:$wback), 10532 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10533 GPR64sp:$Rn, 10534 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10535 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 10536 (outs GPR64sp:$wback), 10537 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10538 GPR64sp:$Rn, 10539 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10540 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 10541 (outs GPR64sp:$wback), 10542 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10543 GPR64sp:$Rn, 10544 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10545 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 10546 (outs GPR64sp:$wback), 10547 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10548 GPR64sp:$Rn, 10549 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10550 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 10551 (outs GPR64sp:$wback), 10552 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10553 GPR64sp:$Rn, 10554 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10555 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 10556 (outs GPR64sp:$wback), 10557 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10558 GPR64sp:$Rn, 10559 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10560 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 10561 (outs GPR64sp:$wback), 10562 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10563 GPR64sp:$Rn, 10564 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10565 } 10566 10567 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10568 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10569 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10570 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10571 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10572 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10573 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10574} 10575 10576multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 10577 int Offset128, int Offset64, bits<4> opcode> 10578 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10579 10580 // LD1 instructions have extra "1d" variants. 10581 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10582 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 10583 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10584 (ins GPR64sp:$Rn), []>; 10585 10586 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10587 (outs GPR64sp:$wback, 10588 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10589 (ins GPR64sp:$Rn, 10590 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10591 } 10592 10593 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10594} 10595 10596multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10597 int Offset128, int Offset64, bits<4> opcode> 10598 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10599 10600 // ST1 instructions have extra "1d" variants. 10601 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10602 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10603 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10604 GPR64sp:$Rn), []>; 10605 10606 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10607 (outs GPR64sp:$wback), 10608 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10609 GPR64sp:$Rn, 10610 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10611 } 10612 10613 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10614} 10615 10616multiclass SIMDLd1Multiple<string asm> { 10617 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10618 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10619 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10620 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10621} 10622 10623multiclass SIMDSt1Multiple<string asm> { 10624 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10625 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10626 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10627 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10628} 10629 10630multiclass SIMDLd2Multiple<string asm> { 10631 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10632} 10633 10634multiclass SIMDSt2Multiple<string asm> { 10635 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10636} 10637 10638multiclass SIMDLd3Multiple<string asm> { 10639 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10640} 10641 10642multiclass SIMDSt3Multiple<string asm> { 10643 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10644} 10645 10646multiclass SIMDLd4Multiple<string asm> { 10647 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10648} 10649 10650multiclass SIMDSt4Multiple<string asm> { 10651 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10652} 10653 10654//--- 10655// AdvSIMD Load/store single-element 10656//--- 10657 10658class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10659 string asm, string operands, string cst, 10660 dag oops, dag iops, list<dag> pattern> 10661 : I<oops, iops, asm, operands, cst, pattern> { 10662 bits<5> Vt; 10663 bits<5> Rn; 10664 let Inst{31} = 0; 10665 let Inst{29-24} = 0b001101; 10666 let Inst{22} = L; 10667 let Inst{21} = R; 10668 let Inst{15-13} = opcode; 10669 let Inst{9-5} = Rn; 10670 let Inst{4-0} = Vt; 10671} 10672 10673class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10674 string asm, string operands, string cst, 10675 dag oops, dag iops, list<dag> pattern> 10676 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10677 bits<5> Vt; 10678 bits<5> Rn; 10679 let Inst{31} = 0; 10680 let Inst{29-24} = 0b001101; 10681 let Inst{22} = L; 10682 let Inst{21} = R; 10683 let Inst{15-13} = opcode; 10684 let Inst{9-5} = Rn; 10685 let Inst{4-0} = Vt; 10686} 10687 10688 10689let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10690class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10691 DAGOperand listtype> 10692 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10693 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10694 []> { 10695 let Inst{30} = Q; 10696 let Inst{23} = 0; 10697 let Inst{20-16} = 0b00000; 10698 let Inst{12} = S; 10699 let Inst{11-10} = size; 10700} 10701let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10702class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10703 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10704 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10705 "$Rn = $wback", 10706 (outs GPR64sp:$wback, listtype:$Vt), 10707 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10708 bits<5> Xm; 10709 let Inst{30} = Q; 10710 let Inst{23} = 1; 10711 let Inst{20-16} = Xm; 10712 let Inst{12} = S; 10713 let Inst{11-10} = size; 10714} 10715 10716multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10717 int Offset, int Size> { 10718 // E.g. "ld1r { v0.8b }, [x1], #1" 10719 // "ld1r.8b\t$Vt, [$Rn], #1" 10720 // may get mapped to 10721 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10722 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10723 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10724 GPR64sp:$Rn, 10725 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10726 XZR), 1>; 10727 10728 // E.g. "ld1r.8b { v0 }, [x1], #1" 10729 // "ld1r.8b\t$Vt, [$Rn], #1" 10730 // may get mapped to 10731 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10732 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10733 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10734 GPR64sp:$Rn, 10735 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10736 XZR), 0>; 10737 10738 // E.g. "ld1r.8b { v0 }, [x1]" 10739 // "ld1r.8b\t$Vt, [$Rn]" 10740 // may get mapped to 10741 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10742 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10743 (!cast<Instruction>(BaseName # "v" # layout) 10744 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10745 GPR64sp:$Rn), 0>; 10746 10747 // E.g. "ld1r.8b { v0 }, [x1], x2" 10748 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10749 // may get mapped to 10750 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10751 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10752 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10753 GPR64sp:$Rn, 10754 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10755 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10756} 10757 10758multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10759 int Offset1, int Offset2, int Offset4, int Offset8> { 10760 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10761 !cast<DAGOperand>("VecList" # Count # "8b")>; 10762 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10763 !cast<DAGOperand>("VecList" # Count #"16b")>; 10764 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10765 !cast<DAGOperand>("VecList" # Count #"4h")>; 10766 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10767 !cast<DAGOperand>("VecList" # Count #"8h")>; 10768 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10769 !cast<DAGOperand>("VecList" # Count #"2s")>; 10770 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10771 !cast<DAGOperand>("VecList" # Count #"4s")>; 10772 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10773 !cast<DAGOperand>("VecList" # Count #"1d")>; 10774 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10775 !cast<DAGOperand>("VecList" # Count #"2d")>; 10776 10777 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10778 !cast<DAGOperand>("VecList" # Count # "8b"), 10779 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10780 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10781 !cast<DAGOperand>("VecList" # Count # "16b"), 10782 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10783 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10784 !cast<DAGOperand>("VecList" # Count # "4h"), 10785 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10786 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10787 !cast<DAGOperand>("VecList" # Count # "8h"), 10788 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10789 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10790 !cast<DAGOperand>("VecList" # Count # "2s"), 10791 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10792 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10793 !cast<DAGOperand>("VecList" # Count # "4s"), 10794 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10795 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10796 !cast<DAGOperand>("VecList" # Count # "1d"), 10797 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10798 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10799 !cast<DAGOperand>("VecList" # Count # "2d"), 10800 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10801 10802 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10803 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10804 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10805 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10806 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10807 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10808 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10809 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10810} 10811 10812class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10813 dag oops, dag iops, list<dag> pattern> 10814 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10815 pattern> { 10816 // idx encoded in Q:S:size fields. 10817 bits<4> idx; 10818 let Inst{30} = idx{3}; 10819 let Inst{23} = 0; 10820 let Inst{20-16} = 0b00000; 10821 let Inst{12} = idx{2}; 10822 let Inst{11-10} = idx{1-0}; 10823} 10824class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10825 dag oops, dag iops, list<dag> pattern> 10826 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10827 oops, iops, pattern> { 10828 // idx encoded in Q:S:size fields. 10829 bits<4> idx; 10830 let Inst{30} = idx{3}; 10831 let Inst{23} = 0; 10832 let Inst{20-16} = 0b00000; 10833 let Inst{12} = idx{2}; 10834 let Inst{11-10} = idx{1-0}; 10835} 10836class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10837 dag oops, dag iops> 10838 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10839 "$Rn = $wback", oops, iops, []> { 10840 // idx encoded in Q:S:size fields. 10841 bits<4> idx; 10842 bits<5> Xm; 10843 let Inst{30} = idx{3}; 10844 let Inst{23} = 1; 10845 let Inst{20-16} = Xm; 10846 let Inst{12} = idx{2}; 10847 let Inst{11-10} = idx{1-0}; 10848} 10849class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10850 dag oops, dag iops> 10851 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10852 "$Rn = $wback", oops, iops, []> { 10853 // idx encoded in Q:S:size fields. 10854 bits<4> idx; 10855 bits<5> Xm; 10856 let Inst{30} = idx{3}; 10857 let Inst{23} = 1; 10858 let Inst{20-16} = Xm; 10859 let Inst{12} = idx{2}; 10860 let Inst{11-10} = idx{1-0}; 10861} 10862 10863class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10864 dag oops, dag iops, list<dag> pattern> 10865 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10866 pattern> { 10867 // idx encoded in Q:S:size<1> fields. 10868 bits<3> idx; 10869 let Inst{30} = idx{2}; 10870 let Inst{23} = 0; 10871 let Inst{20-16} = 0b00000; 10872 let Inst{12} = idx{1}; 10873 let Inst{11} = idx{0}; 10874 let Inst{10} = size; 10875} 10876class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10877 dag oops, dag iops, list<dag> pattern> 10878 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10879 oops, iops, pattern> { 10880 // idx encoded in Q:S:size<1> fields. 10881 bits<3> idx; 10882 let Inst{30} = idx{2}; 10883 let Inst{23} = 0; 10884 let Inst{20-16} = 0b00000; 10885 let Inst{12} = idx{1}; 10886 let Inst{11} = idx{0}; 10887 let Inst{10} = size; 10888} 10889 10890class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10891 dag oops, dag iops> 10892 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10893 "$Rn = $wback", oops, iops, []> { 10894 // idx encoded in Q:S:size<1> fields. 10895 bits<3> idx; 10896 bits<5> Xm; 10897 let Inst{30} = idx{2}; 10898 let Inst{23} = 1; 10899 let Inst{20-16} = Xm; 10900 let Inst{12} = idx{1}; 10901 let Inst{11} = idx{0}; 10902 let Inst{10} = size; 10903} 10904class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10905 dag oops, dag iops> 10906 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10907 "$Rn = $wback", oops, iops, []> { 10908 // idx encoded in Q:S:size<1> fields. 10909 bits<3> idx; 10910 bits<5> Xm; 10911 let Inst{30} = idx{2}; 10912 let Inst{23} = 1; 10913 let Inst{20-16} = Xm; 10914 let Inst{12} = idx{1}; 10915 let Inst{11} = idx{0}; 10916 let Inst{10} = size; 10917} 10918class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10919 dag oops, dag iops, list<dag> pattern> 10920 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10921 pattern> { 10922 // idx encoded in Q:S fields. 10923 bits<2> idx; 10924 let Inst{30} = idx{1}; 10925 let Inst{23} = 0; 10926 let Inst{20-16} = 0b00000; 10927 let Inst{12} = idx{0}; 10928 let Inst{11-10} = size; 10929} 10930class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10931 dag oops, dag iops, list<dag> pattern> 10932 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10933 oops, iops, pattern> { 10934 // idx encoded in Q:S fields. 10935 bits<2> idx; 10936 let Inst{30} = idx{1}; 10937 let Inst{23} = 0; 10938 let Inst{20-16} = 0b00000; 10939 let Inst{12} = idx{0}; 10940 let Inst{11-10} = size; 10941} 10942class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10943 string asm, dag oops, dag iops> 10944 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10945 "$Rn = $wback", oops, iops, []> { 10946 // idx encoded in Q:S fields. 10947 bits<2> idx; 10948 bits<5> Xm; 10949 let Inst{30} = idx{1}; 10950 let Inst{23} = 1; 10951 let Inst{20-16} = Xm; 10952 let Inst{12} = idx{0}; 10953 let Inst{11-10} = size; 10954} 10955class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10956 string asm, dag oops, dag iops> 10957 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10958 "$Rn = $wback", oops, iops, []> { 10959 // idx encoded in Q:S fields. 10960 bits<2> idx; 10961 bits<5> Xm; 10962 let Inst{30} = idx{1}; 10963 let Inst{23} = 1; 10964 let Inst{20-16} = Xm; 10965 let Inst{12} = idx{0}; 10966 let Inst{11-10} = size; 10967} 10968class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10969 dag oops, dag iops, list<dag> pattern> 10970 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10971 pattern> { 10972 // idx encoded in Q field. 10973 bits<1> idx; 10974 let Inst{30} = idx; 10975 let Inst{23} = 0; 10976 let Inst{20-16} = 0b00000; 10977 let Inst{12} = 0; 10978 let Inst{11-10} = size; 10979} 10980class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10981 dag oops, dag iops, list<dag> pattern> 10982 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10983 oops, iops, pattern> { 10984 // idx encoded in Q field. 10985 bits<1> idx; 10986 let Inst{30} = idx; 10987 let Inst{23} = 0; 10988 let Inst{20-16} = 0b00000; 10989 let Inst{12} = 0; 10990 let Inst{11-10} = size; 10991} 10992class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10993 string asm, dag oops, dag iops> 10994 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10995 "$Rn = $wback", oops, iops, []> { 10996 // idx encoded in Q field. 10997 bits<1> idx; 10998 bits<5> Xm; 10999 let Inst{30} = idx; 11000 let Inst{23} = 1; 11001 let Inst{20-16} = Xm; 11002 let Inst{12} = 0; 11003 let Inst{11-10} = size; 11004} 11005class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 11006 string asm, dag oops, dag iops> 11007 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11008 "$Rn = $wback", oops, iops, []> { 11009 // idx encoded in Q field. 11010 bits<1> idx; 11011 bits<5> Xm; 11012 let Inst{30} = idx; 11013 let Inst{23} = 1; 11014 let Inst{20-16} = Xm; 11015 let Inst{12} = 0; 11016 let Inst{11-10} = size; 11017} 11018 11019let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11020multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 11021 RegisterOperand listtype, 11022 RegisterOperand GPR64pi> { 11023 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 11024 (outs listtype:$dst), 11025 (ins listtype:$Vt, VectorIndexB:$idx, 11026 GPR64sp:$Rn), []>; 11027 11028 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 11029 (outs GPR64sp:$wback, listtype:$dst), 11030 (ins listtype:$Vt, VectorIndexB:$idx, 11031 GPR64sp:$Rn, GPR64pi:$Xm)>; 11032} 11033let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11034multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 11035 RegisterOperand listtype, 11036 RegisterOperand GPR64pi> { 11037 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 11038 (outs listtype:$dst), 11039 (ins listtype:$Vt, VectorIndexH:$idx, 11040 GPR64sp:$Rn), []>; 11041 11042 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 11043 (outs GPR64sp:$wback, listtype:$dst), 11044 (ins listtype:$Vt, VectorIndexH:$idx, 11045 GPR64sp:$Rn, GPR64pi:$Xm)>; 11046} 11047let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11048multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 11049 RegisterOperand listtype, 11050 RegisterOperand GPR64pi> { 11051 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 11052 (outs listtype:$dst), 11053 (ins listtype:$Vt, VectorIndexS:$idx, 11054 GPR64sp:$Rn), []>; 11055 11056 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 11057 (outs GPR64sp:$wback, listtype:$dst), 11058 (ins listtype:$Vt, VectorIndexS:$idx, 11059 GPR64sp:$Rn, GPR64pi:$Xm)>; 11060} 11061let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11062multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 11063 RegisterOperand listtype, RegisterOperand GPR64pi> { 11064 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 11065 (outs listtype:$dst), 11066 (ins listtype:$Vt, VectorIndexD:$idx, 11067 GPR64sp:$Rn), []>; 11068 11069 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 11070 (outs GPR64sp:$wback, listtype:$dst), 11071 (ins listtype:$Vt, VectorIndexD:$idx, 11072 GPR64sp:$Rn, GPR64pi:$Xm)>; 11073} 11074let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11075multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 11076 RegisterOperand listtype, RegisterOperand GPR64pi> { 11077 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 11078 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 11079 GPR64sp:$Rn), []>; 11080 11081 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 11082 (outs GPR64sp:$wback), 11083 (ins listtype:$Vt, VectorIndexB:$idx, 11084 GPR64sp:$Rn, GPR64pi:$Xm)>; 11085} 11086let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11087multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 11088 RegisterOperand listtype, RegisterOperand GPR64pi> { 11089 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 11090 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 11091 GPR64sp:$Rn), []>; 11092 11093 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 11094 (outs GPR64sp:$wback), 11095 (ins listtype:$Vt, VectorIndexH:$idx, 11096 GPR64sp:$Rn, GPR64pi:$Xm)>; 11097} 11098let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11099multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 11100 RegisterOperand listtype, RegisterOperand GPR64pi> { 11101 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 11102 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 11103 GPR64sp:$Rn), []>; 11104 11105 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 11106 (outs GPR64sp:$wback), 11107 (ins listtype:$Vt, VectorIndexS:$idx, 11108 GPR64sp:$Rn, GPR64pi:$Xm)>; 11109} 11110let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11111multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 11112 RegisterOperand listtype, RegisterOperand GPR64pi> { 11113 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 11114 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 11115 GPR64sp:$Rn), []>; 11116 11117 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 11118 (outs GPR64sp:$wback), 11119 (ins listtype:$Vt, VectorIndexD:$idx, 11120 GPR64sp:$Rn, GPR64pi:$Xm)>; 11121} 11122 11123multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 11124 string Count, int Offset, Operand idxtype> { 11125 // E.g. "ld1 { v0.8b }[0], [x1], #1" 11126 // "ld1\t$Vt, [$Rn], #1" 11127 // may get mapped to 11128 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 11129 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 11130 (!cast<Instruction>(NAME # Type # "_POST") 11131 GPR64sp:$Rn, 11132 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 11133 idxtype:$idx, XZR), 1>; 11134 11135 // E.g. "ld1.8b { v0 }[0], [x1], #1" 11136 // "ld1.8b\t$Vt, [$Rn], #1" 11137 // may get mapped to 11138 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 11139 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 11140 (!cast<Instruction>(NAME # Type # "_POST") 11141 GPR64sp:$Rn, 11142 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11143 idxtype:$idx, XZR), 0>; 11144 11145 // E.g. "ld1.8b { v0 }[0], [x1]" 11146 // "ld1.8b\t$Vt, [$Rn]" 11147 // may get mapped to 11148 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 11149 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 11150 (!cast<Instruction>(NAME # Type) 11151 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11152 idxtype:$idx, GPR64sp:$Rn), 0>; 11153 11154 // E.g. "ld1.8b { v0 }[0], [x1], x2" 11155 // "ld1.8b\t$Vt, [$Rn], $Xm" 11156 // may get mapped to 11157 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 11158 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 11159 (!cast<Instruction>(NAME # Type # "_POST") 11160 GPR64sp:$Rn, 11161 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11162 idxtype:$idx, 11163 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 11164} 11165 11166multiclass SIMDLdSt1SingleAliases<string asm> { 11167 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 11168 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 11169 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 11170 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 11171} 11172 11173multiclass SIMDLdSt2SingleAliases<string asm> { 11174 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 11175 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 11176 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 11177 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 11178} 11179 11180multiclass SIMDLdSt3SingleAliases<string asm> { 11181 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 11182 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 11183 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 11184 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 11185} 11186 11187multiclass SIMDLdSt4SingleAliases<string asm> { 11188 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 11189 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 11190 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 11191 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 11192} 11193} // end of 'let Predicates = [HasNEON]' 11194 11195//---------------------------------------------------------------------------- 11196// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 11197//---------------------------------------------------------------------------- 11198 11199let Predicates = [HasNEON, HasRDM] in { 11200 11201class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 11202 RegisterOperand regtype, string asm, 11203 string kind, list<dag> pattern> 11204 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 11205 pattern> { 11206} 11207multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 11208 SDPatternOperator op> { 11209 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 11210 [(set (v4i16 V64:$dst), 11211 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 11212 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 11213 [(set (v8i16 V128:$dst), 11214 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 11215 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 11216 [(set (v2i32 V64:$dst), 11217 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 11218 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 11219 [(set (v4i32 V128:$dst), 11220 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 11221} 11222 11223multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 11224 SDPatternOperator op> { 11225 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 11226 V64, V64, V128_lo, VectorIndexH, 11227 asm, ".4h", ".4h", ".4h", ".h", 11228 [(set (v4i16 V64:$dst), 11229 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 11230 (dup_v8i16 (v8i16 V128_lo:$Rm), 11231 VectorIndexH:$idx))))]> { 11232 bits<3> idx; 11233 let Inst{11} = idx{2}; 11234 let Inst{21} = idx{1}; 11235 let Inst{20} = idx{0}; 11236 } 11237 11238 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 11239 V128, V128, V128_lo, VectorIndexH, 11240 asm, ".8h", ".8h", ".8h", ".h", 11241 [(set (v8i16 V128:$dst), 11242 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 11243 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 11244 VectorIndexH:$idx)))))]> { 11245 bits<3> idx; 11246 let Inst{11} = idx{2}; 11247 let Inst{21} = idx{1}; 11248 let Inst{20} = idx{0}; 11249 } 11250 11251 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 11252 V64, V64, V128, VectorIndexS, 11253 asm, ".2s", ".2s", ".2s", ".s", 11254 [(set (v2i32 V64:$dst), 11255 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 11256 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 11257 bits<2> idx; 11258 let Inst{11} = idx{1}; 11259 let Inst{21} = idx{0}; 11260 } 11261 11262 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 11263 V128, V128, V128, VectorIndexS, 11264 asm, ".4s", ".4s", ".4s", ".s", 11265 [(set (v4i32 V128:$dst), 11266 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11267 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 11268 VectorIndexS:$idx)))))]> { 11269 bits<2> idx; 11270 let Inst{11} = idx{1}; 11271 let Inst{21} = idx{0}; 11272 } 11273 11274 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 11275 FPR16Op, FPR16Op, V128_lo, 11276 VectorIndexH, asm, ".h", "", "", ".h", 11277 []> { 11278 bits<3> idx; 11279 let Inst{11} = idx{2}; 11280 let Inst{21} = idx{1}; 11281 let Inst{20} = idx{0}; 11282 } 11283 11284 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 11285 FPR32Op, FPR32Op, V128, VectorIndexS, 11286 asm, ".s", "", "", ".s", 11287 [(set (i32 FPR32Op:$dst), 11288 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 11289 (i32 (vector_extract (v4i32 V128:$Rm), 11290 VectorIndexS:$idx)))))]> { 11291 bits<2> idx; 11292 let Inst{11} = idx{1}; 11293 let Inst{21} = idx{0}; 11294 } 11295} 11296} // let Predicates = [HasNeon, HasRDM] 11297 11298//---------------------------------------------------------------------------- 11299// ARMv8.3 Complex ADD/MLA instructions 11300//---------------------------------------------------------------------------- 11301 11302class ComplexRotationOperand<int Angle, int Remainder, string Type> 11303 : AsmOperandClass { 11304 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 11305 let DiagnosticType = "InvalidComplexRotation" # Type; 11306 let Name = "ComplexRotation" # Type; 11307} 11308def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11309 SDNodeXForm<imm, [{ 11310 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 11311}]>> { 11312 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 11313 let PrintMethod = "printComplexRotationOp<90, 0>"; 11314} 11315def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11316 SDNodeXForm<imm, [{ 11317 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 11318}]>> { 11319 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 11320 let PrintMethod = "printComplexRotationOp<180, 90>"; 11321} 11322let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11323class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 11324 RegisterOperand regtype, Operand rottype, 11325 string asm, string kind, list<dag> pattern> 11326 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11327 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11328 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 11329 Sched<[!if(Q, WriteVq, WriteVd)]> { 11330 bits<5> Rd; 11331 bits<5> Rn; 11332 bits<5> Rm; 11333 bits<1> 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 // Non-tied version (FCADD) only has one rotation bit 11343 let Inst{12} = rot; 11344 let Inst{11} = 0; 11345 let Inst{10} = 1; 11346 let Inst{9-5} = Rn; 11347 let Inst{4-0} = Rd; 11348} 11349 11350//8.3 CompNum - Floating-point complex number support 11351multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 11352 string asm, SDPatternOperator OpNode>{ 11353 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11354 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 11355 asm, ".4h", 11356 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11357 (v4f16 V64:$Rn), 11358 (v4f16 V64:$Rm), 11359 (i32 rottype:$rot)))]>; 11360 11361 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 11362 asm, ".8h", 11363 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11364 (v8f16 V128:$Rn), 11365 (v8f16 V128:$Rm), 11366 (i32 rottype:$rot)))]>; 11367 } 11368 11369 let Predicates = [HasComplxNum, HasNEON] in { 11370 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 11371 asm, ".2s", 11372 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11373 (v2f32 V64:$Rn), 11374 (v2f32 V64:$Rm), 11375 (i32 rottype:$rot)))]>; 11376 11377 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 11378 asm, ".4s", 11379 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11380 (v4f32 V128:$Rn), 11381 (v4f32 V128:$Rm), 11382 (i32 rottype:$rot)))]>; 11383 11384 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 11385 asm, ".2d", 11386 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11387 (v2f64 V128:$Rn), 11388 (v2f64 V128:$Rm), 11389 (i32 rottype:$rot)))]>; 11390 } 11391} 11392 11393let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11394class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 11395 bits<3> opcode, 11396 RegisterOperand regtype, 11397 Operand rottype, string asm, 11398 string kind, list<dag> pattern> 11399 : I<(outs regtype:$dst), 11400 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11401 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11402 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 11403 Sched<[!if(Q, WriteVq, WriteVd)]> { 11404 bits<5> Rd; 11405 bits<5> Rn; 11406 bits<5> Rm; 11407 bits<2> rot; 11408 let Inst{31} = 0; 11409 let Inst{30} = Q; 11410 let Inst{29} = U; 11411 let Inst{28-24} = 0b01110; 11412 let Inst{23-22} = size; 11413 let Inst{21} = 0; 11414 let Inst{20-16} = Rm; 11415 let Inst{15-13} = opcode; 11416 let Inst{12-11} = rot; 11417 let Inst{10} = 1; 11418 let Inst{9-5} = Rn; 11419 let Inst{4-0} = Rd; 11420} 11421 11422multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 11423 Operand rottype, string asm, 11424 SDPatternOperator OpNode> { 11425 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11426 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 11427 rottype, asm, ".4h", 11428 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11429 (v4f16 V64:$Rn), 11430 (v4f16 V64:$Rm), 11431 (i32 rottype:$rot)))]>; 11432 11433 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 11434 rottype, asm, ".8h", 11435 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11436 (v8f16 V128:$Rn), 11437 (v8f16 V128:$Rm), 11438 (i32 rottype:$rot)))]>; 11439 } 11440 11441 let Predicates = [HasComplxNum, HasNEON] in { 11442 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 11443 rottype, asm, ".2s", 11444 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11445 (v2f32 V64:$Rn), 11446 (v2f32 V64:$Rm), 11447 (i32 rottype:$rot)))]>; 11448 11449 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 11450 rottype, asm, ".4s", 11451 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11452 (v4f32 V128:$Rn), 11453 (v4f32 V128:$Rm), 11454 (i32 rottype:$rot)))]>; 11455 11456 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 11457 rottype, asm, ".2d", 11458 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11459 (v2f64 V128:$Rn), 11460 (v2f64 V128:$Rm), 11461 (i32 rottype:$rot)))]>; 11462 } 11463} 11464 11465let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11466class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 11467 bit opc1, bit opc2, RegisterOperand dst_reg, 11468 RegisterOperand lhs_reg, 11469 RegisterOperand rhs_reg, Operand vec_idx, 11470 Operand rottype, string asm, string apple_kind, 11471 string dst_kind, string lhs_kind, 11472 string rhs_kind, list<dag> pattern> 11473 : I<(outs dst_reg:$dst), 11474 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 11475 asm, 11476 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 11477 "$idx, $rot" # "|" # apple_kind # 11478 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 11479 Sched<[!if(Q, WriteVq, WriteVd)]> { 11480 bits<5> Rd; 11481 bits<5> Rn; 11482 bits<5> Rm; 11483 bits<2> rot; 11484 11485 let Inst{31} = 0; 11486 let Inst{30} = Q; 11487 let Inst{29} = U; 11488 let Inst{28} = Scalar; 11489 let Inst{27-24} = 0b1111; 11490 let Inst{23-22} = size; 11491 // Bit 21 must be set by the derived class. 11492 let Inst{20-16} = Rm; 11493 let Inst{15} = opc1; 11494 let Inst{14-13} = rot; 11495 let Inst{12} = opc2; 11496 // Bit 11 must be set by the derived class. 11497 let Inst{10} = 0; 11498 let Inst{9-5} = Rn; 11499 let Inst{4-0} = Rd; 11500} 11501 11502// The complex instructions index by pairs of elements, so the VectorIndexes 11503// don't match the lane types, and the index bits are different to the other 11504// classes. 11505multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 11506 string asm> { 11507 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11508 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 11509 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 11510 ".4h", ".h", []> { 11511 bits<1> idx; 11512 let Inst{11} = 0; 11513 let Inst{21} = idx{0}; 11514 } 11515 11516 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 11517 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 11518 ".8h", ".8h", ".h", []> { 11519 bits<2> idx; 11520 let Inst{11} = idx{1}; 11521 let Inst{21} = idx{0}; 11522 } 11523 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 11524 11525 let Predicates = [HasComplxNum, HasNEON] in { 11526 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 11527 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 11528 ".4s", ".4s", ".s", []> { 11529 bits<1> idx; 11530 let Inst{11} = idx{0}; 11531 let Inst{21} = 0; 11532 } 11533 } // Predicates = [HasComplxNum, HasNEON] 11534} 11535 11536//---------------------------------------------------------------------------- 11537// Crypto extensions 11538//---------------------------------------------------------------------------- 11539 11540let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11541class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 11542 list<dag> pat> 11543 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 11544 Sched<[WriteVq]>{ 11545 bits<5> Rd; 11546 bits<5> Rn; 11547 let Inst{31-16} = 0b0100111000101000; 11548 let Inst{15-12} = opc; 11549 let Inst{11-10} = 0b10; 11550 let Inst{9-5} = Rn; 11551 let Inst{4-0} = Rd; 11552} 11553 11554class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 11555 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 11556 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 11557 11558class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 11559 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 11560 "$Rd = $dst", 11561 [(set (v16i8 V128:$dst), 11562 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 11563 11564let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11565class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 11566 dag oops, dag iops, list<dag> pat> 11567 : I<oops, iops, asm, 11568 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 11569 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 11570 Sched<[WriteVq]>{ 11571 bits<5> Rd; 11572 bits<5> Rn; 11573 bits<5> Rm; 11574 let Inst{31-21} = 0b01011110000; 11575 let Inst{20-16} = Rm; 11576 let Inst{15} = 0; 11577 let Inst{14-12} = opc; 11578 let Inst{11-10} = 0b00; 11579 let Inst{9-5} = Rn; 11580 let Inst{4-0} = Rd; 11581} 11582 11583class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11584 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11585 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11586 [(set (v4i32 FPR128:$dst), 11587 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11588 (v4i32 V128:$Rm)))]>; 11589 11590class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11591 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11592 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11593 [(set (v4i32 V128:$dst), 11594 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11595 (v4i32 V128:$Rm)))]>; 11596 11597class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11598 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11599 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11600 [(set (v4i32 FPR128:$dst), 11601 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11602 (v4i32 V128:$Rm)))]>; 11603 11604let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11605class SHA2OpInst<bits<4> opc, string asm, string kind, 11606 string cstr, dag oops, dag iops, 11607 list<dag> pat> 11608 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11609 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11610 Sched<[WriteVq]>{ 11611 bits<5> Rd; 11612 bits<5> Rn; 11613 let Inst{31-16} = 0b0101111000101000; 11614 let Inst{15-12} = opc; 11615 let Inst{11-10} = 0b10; 11616 let Inst{9-5} = Rn; 11617 let Inst{4-0} = Rd; 11618} 11619 11620class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11621 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11622 (ins V128:$Rd, V128:$Rn), 11623 [(set (v4i32 V128:$dst), 11624 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11625 11626class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11627 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11628 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11629 11630// Armv8.2-A Crypto extensions 11631class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11632 list<dag> pattern> 11633 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11634 bits<5> Vd; 11635 bits<5> Vn; 11636 let Inst{31-25} = 0b1100111; 11637 let Inst{9-5} = Vn; 11638 let Inst{4-0} = Vd; 11639} 11640 11641class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11642 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11643 "$Vd = $Vdst", []> { 11644 let Inst{31-25} = 0b1100111; 11645 let Inst{24-21} = 0b0110; 11646 let Inst{20-15} = 0b000001; 11647 let Inst{14} = op0; 11648 let Inst{13-12} = 0b00; 11649 let Inst{11-10} = op1; 11650} 11651class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11652 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11653class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11654 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11655 11656class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11657 string asmops, string cst> 11658 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11659 bits<5> Vm; 11660 let Inst{24-21} = 0b0011; 11661 let Inst{20-16} = Vm; 11662 let Inst{15} = 0b1; 11663 let Inst{14} = op0; 11664 let Inst{13-12} = 0b00; 11665 let Inst{11-10} = op1; 11666} 11667class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11668 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11669 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11670class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11671 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11672 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11673class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11674 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11675 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11676class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11677 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11678 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11679class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11680 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11681 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11682 11683class CryptoRRRR<bits<2>op0, string asm, string asmops> 11684 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11685 asmops, "", []> { 11686 bits<5> Vm; 11687 bits<5> Va; 11688 let Inst{24-23} = 0b00; 11689 let Inst{22-21} = op0; 11690 let Inst{20-16} = Vm; 11691 let Inst{15} = 0b0; 11692 let Inst{14-10} = Va; 11693} 11694class CryptoRRRR_16B<bits<2>op0, string asm> 11695 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11696 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11697} 11698class CryptoRRRR_4S<bits<2>op0, string asm> 11699 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11700 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11701} 11702 11703class CryptoRRRi6<string asm> 11704 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11705 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11706 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11707 bits<6> imm; 11708 bits<5> Vm; 11709 let Inst{24-21} = 0b0100; 11710 let Inst{20-16} = Vm; 11711 let Inst{15-10} = imm; 11712 let Inst{9-5} = Vn; 11713 let Inst{4-0} = Vd; 11714} 11715 11716class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11717 : BaseCryptoV82<(outs V128:$Vdst), 11718 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11719 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11720 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11721 bits<2> imm; 11722 bits<5> Vm; 11723 let Inst{24-21} = 0b0010; 11724 let Inst{20-16} = Vm; 11725 let Inst{15} = 0b1; 11726 let Inst{14} = op0; 11727 let Inst{13-12} = imm; 11728 let Inst{11-10} = op1; 11729} 11730 11731//---------------------------------------------------------------------------- 11732// v8.1 atomic instructions extension: 11733// * CAS 11734// * CASP 11735// * SWP 11736// * LDOPregister<OP>, and aliases STOPregister<OP> 11737 11738// Instruction encodings: 11739// 11740// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11741// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11742// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11743// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11744// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11745// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11746 11747// Instruction syntax: 11748// 11749// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11750// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11751// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11752// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11753// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11754// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11755// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11756// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11757// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11758// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11759 11760let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11761class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11762 string cstr, list<dag> pattern> 11763 : I<oops, iops, asm, operands, cstr, pattern> { 11764 bits<2> Sz; 11765 bit NP; 11766 bit Acq; 11767 bit Rel; 11768 bits<5> Rs; 11769 bits<5> Rn; 11770 bits<5> Rt; 11771 let Inst{31-30} = Sz; 11772 let Inst{29-24} = 0b001000; 11773 let Inst{23} = NP; 11774 let Inst{22} = Acq; 11775 let Inst{21} = 0b1; 11776 let Inst{20-16} = Rs; 11777 let Inst{15} = Rel; 11778 let Inst{14-10} = 0b11111; 11779 let Inst{9-5} = Rn; 11780 let Inst{4-0} = Rt; 11781 let Predicates = [HasLSE]; 11782} 11783 11784class BaseCAS<string order, string size, RegisterClass RC> 11785 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11786 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11787 "$out = $Rs",[]>, 11788 Sched<[WriteAtomic]> { 11789 let NP = 1; 11790} 11791 11792multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11793 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11794 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11795 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11796 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11797} 11798 11799class BaseCASP<string order, string size, RegisterOperand RC> 11800 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11801 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11802 "$out = $Rs",[]>, 11803 Sched<[WriteAtomic]> { 11804 let NP = 0; 11805} 11806 11807multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11808 let Sz = 0b00, Acq = Acq, Rel = Rel in 11809 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11810 let Sz = 0b01, Acq = Acq, Rel = Rel in 11811 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11812} 11813 11814let Predicates = [HasLSE] in 11815class BaseSWP<string order, string size, RegisterClass RC> 11816 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11817 "\t$Rs, $Rt, [$Rn]","",[]>, 11818 Sched<[WriteAtomic]> { 11819 bits<2> Sz; 11820 bit Acq; 11821 bit Rel; 11822 bits<5> Rs; 11823 bits<3> opc = 0b000; 11824 bits<5> Rn; 11825 bits<5> Rt; 11826 let Inst{31-30} = Sz; 11827 let Inst{29-24} = 0b111000; 11828 let Inst{23} = Acq; 11829 let Inst{22} = Rel; 11830 let Inst{21} = 0b1; 11831 let Inst{20-16} = Rs; 11832 let Inst{15} = 0b1; 11833 let Inst{14-12} = opc; 11834 let Inst{11-10} = 0b00; 11835 let Inst{9-5} = Rn; 11836 let Inst{4-0} = Rt; 11837 let Predicates = [HasLSE]; 11838} 11839 11840multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11841 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11842 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11843 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11844 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11845} 11846 11847let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11848class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11849 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11850 "\t$Rs, $Rt, [$Rn]","",[]>, 11851 Sched<[WriteAtomic]> { 11852 bits<2> Sz; 11853 bit Acq; 11854 bit Rel; 11855 bits<5> Rs; 11856 bits<3> opc; 11857 bits<5> Rn; 11858 bits<5> Rt; 11859 let Inst{31-30} = Sz; 11860 let Inst{29-24} = 0b111000; 11861 let Inst{23} = Acq; 11862 let Inst{22} = Rel; 11863 let Inst{21} = 0b1; 11864 let Inst{20-16} = Rs; 11865 let Inst{15} = 0b0; 11866 let Inst{14-12} = opc; 11867 let Inst{11-10} = 0b00; 11868 let Inst{9-5} = Rn; 11869 let Inst{4-0} = Rt; 11870 let Predicates = [HasLSE]; 11871} 11872 11873multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11874 string order> { 11875 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11876 def B : BaseLDOPregister<op, order, "b", GPR32>; 11877 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11878 def H : BaseLDOPregister<op, order, "h", GPR32>; 11879 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11880 def W : BaseLDOPregister<op, order, "", GPR32>; 11881 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11882 def X : BaseLDOPregister<op, order, "", GPR64>; 11883} 11884 11885// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11886// complex DAG for DstRHS. 11887let Predicates = [HasLSE] in 11888multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11889 string size, dag SrcRHS, dag DstRHS> { 11890 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 11891 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11892 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 11893 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11894 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 11895 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11896 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11897 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11898 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11899 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11900} 11901 11902multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11903 string size, dag RHS> { 11904 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 11905} 11906 11907multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11908 string size, dag LHS, dag RHS> { 11909 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 11910} 11911 11912multiclass LDOPregister_patterns<string inst, string op> { 11913 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 11914 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 11915 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 11916 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 11917} 11918 11919multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11920 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 11921 (i64 GPR64:$Rm), 11922 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11923 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 11924 (i32 GPR32:$Rm), 11925 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11926 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 11927 (i32 GPR32:$Rm), 11928 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11929 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 11930 (i32 GPR32:$Rm), 11931 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11932} 11933 11934let Predicates = [HasLSE] in 11935multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11936 string size, dag OLD, dag NEW> { 11937 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11938 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11939 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 11940 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11941 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 11942 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11943 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11944 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11945 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11946 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11947} 11948 11949multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11950 string size, dag OLD, dag NEW> { 11951 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 11952} 11953 11954multiclass CASregister_patterns<string inst, string op> { 11955 defm : CASregister_patterns_ord<inst, "X", op, "64", 11956 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11957 defm : CASregister_patterns_ord<inst, "W", op, "32", 11958 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11959 defm : CASregister_patterns_ord<inst, "H", op, "16", 11960 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11961 defm : CASregister_patterns_ord<inst, "B", op, "8", 11962 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11963} 11964 11965let Predicates = [HasLSE] in 11966class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11967 Instruction inst> : 11968 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11969 11970multiclass STOPregister<string asm, string instr> { 11971 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11972 !cast<Instruction>(instr # "LB")>; 11973 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11974 !cast<Instruction>(instr # "LH")>; 11975 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11976 !cast<Instruction>(instr # "LW")>; 11977 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11978 !cast<Instruction>(instr # "LX")>; 11979 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11980 !cast<Instruction>(instr # "B")>; 11981 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11982 !cast<Instruction>(instr # "H")>; 11983 def : BaseSTOPregister<asm, GPR32, WZR, 11984 !cast<Instruction>(instr # "W")>; 11985 def : BaseSTOPregister<asm, GPR64, XZR, 11986 !cast<Instruction>(instr # "X")>; 11987} 11988 11989class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11990 dag iops, dag oops, list<dag> pat> 11991 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11992 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11993 bits<5> Rt; 11994 bits<5> Rn; 11995 let Inst{31-21} = 0b11111000001; 11996 let Inst{15} = 1; 11997 let Inst{14-12} = opc; 11998 let Inst{11-10} = 0b00; 11999 let Inst{9-5} = Rn; 12000 let Inst{4-0} = Rt; 12001 12002 let Predicates = [HasV8_7a]; 12003} 12004 12005class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 12006 list<dag> pat = []> 12007 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 12008 let Inst{20-16} = 0b11111; 12009} 12010 12011class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 12012 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 12013 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 12014 bits<5> Rs; 12015 let Inst{20-16} = Rs; 12016} 12017 12018class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 12019 bits<2> op2, string asm> 12020 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 12021 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 12022 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 12023 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 12024 Sched<[]> { 12025 bits<5> Rd; 12026 bits<5> Rs; 12027 bits<5> Rn; 12028 let Inst{31-27} = 0b00011; 12029 let Inst{26} = isMove; 12030 let Inst{25-24} = 0b01; 12031 let Inst{23-22} = opcode; 12032 let Inst{21} = 0b0; 12033 let Inst{20-16} = Rs; 12034 let Inst{15-14} = op2; 12035 let Inst{13-12} = op1; 12036 let Inst{11-10} = 0b01; 12037 let Inst{9-5} = Rn; 12038 let Inst{4-0} = Rd; 12039 12040 let DecoderMethod = "DecodeCPYMemOpInstruction"; 12041 let mayLoad = 1; 12042 let mayStore = 1; 12043} 12044 12045class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 12046 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 12047 12048class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 12049 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 12050 12051class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 12052 string asm> 12053 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 12054 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 12055 asm, "\t[$Rd]!, $Rn!, $Rm", 12056 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 12057 Sched<[]> { 12058 bits<5> Rd; 12059 bits<5> Rn; 12060 bits<5> Rm; 12061 let Inst{31-27} = 0b00011; 12062 let Inst{26} = isTagging; 12063 let Inst{25-21} = 0b01110; 12064 let Inst{20-16} = Rm; 12065 let Inst{15-14} = opcode; 12066 let Inst{13} = op2; 12067 let Inst{12} = op1; 12068 let Inst{11-10} = 0b01; 12069 let Inst{9-5} = Rn; 12070 let Inst{4-0} = Rd; 12071 12072 let DecoderMethod = "DecodeSETMemOpInstruction"; 12073 let mayLoad = 0; 12074 let mayStore = 1; 12075} 12076 12077class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 12078 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 12079 12080class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 12081 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 12082 12083multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 12084 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 12085 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 12086 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 12087 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 12088 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 12089 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 12090 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 12091 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 12092 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 12093 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 12094 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 12095 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 12096 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 12097 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 12098 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 12099 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 12100} 12101 12102multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 12103 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 12104 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 12105 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 12106 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 12107 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 12108 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 12109 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 12110 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 12111 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 12112 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 12113 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 12114 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 12115 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 12116 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 12117 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 12118 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 12119} 12120 12121multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 12122 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 12123 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 12124 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 12125 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 12126} 12127 12128multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 12129 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 12130 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 12131 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 12132 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 12133} 12134 12135//---------------------------------------------------------------------------- 12136// 2022 Armv8.9/Armv9.4 Extensions 12137//---------------------------------------------------------------------------- 12138 12139//--- 12140// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC) 12141//--- 12142 12143class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc, 12144 RegisterClass regtype, ImmLeaf immtype, string asm, 12145 SDPatternOperator OpNode> 12146 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm), 12147 asm, "\t$Rd, $Rn, $imm", "", 12148 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> { 12149 bits<5> Rd; 12150 bits<5> Rn; 12151 bits<8> imm; 12152 12153 let Inst{31} = sf; 12154 let Inst{30} = Op; 12155 let Inst{29} = S; 12156 let Inst{28-22} = 0b1000111; 12157 let Inst{21-18} = opc; 12158 let Inst{17-10} = imm; 12159 let Inst{9-5} = Rn; 12160 let Inst{4-0} = Rd; 12161} 12162 12163class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin, 12164 RegisterClass regtype, string asm, 12165 SDPatternOperator OpNode> 12166 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>, 12167 Sched<[WriteI]> { 12168 let Inst{11} = isMin; 12169 let Inst{10} = isUnsigned; 12170 let mayLoad = 0; 12171 let mayStore = 0; 12172 let hasSideEffects = 0; 12173} 12174 12175class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin, 12176 RegisterClass regtype, ImmLeaf immtype, string asm, 12177 SDPatternOperator OpNode> 12178 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm, 12179 OpNode>, 12180 Sched<[]> { 12181 let Inst{19} = isMin; 12182 let Inst{18} = isUnsigned; 12183 let mayLoad = 0; 12184 let mayStore = 0; 12185 let hasSideEffects = 0; 12186} 12187 12188multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm, 12189 SDPatternOperator OpNode = null_frag> { 12190 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>; 12191 12192 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32, 12193 !cond(isUnsigned : uimm8_32b, 12194 !not(isUnsigned) : simm8_32b), asm, OpNode>; 12195 12196 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>; 12197 12198 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64, 12199 !cond(isUnsigned : uimm8_64b, 12200 !not(isUnsigned) : simm8_64b), asm, OpNode>; 12201} 12202 12203//--- 12204// RCPC instructions (FEAT_LRCPC3) 12205//--- 12206 12207class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops, 12208 string asm, string operands, string cstr = ""> 12209 : I<oops, iops, asm, operands, cstr, []>, 12210 Sched<[WriteAtomic]> { 12211 bits<5> Rt; 12212 bits<5> Rn; 12213 let Inst{31-30} = size; 12214 let Inst{29-24} = {0,1,1,V,0,1}; 12215 let Inst{23-22} = opc; 12216 let Inst{21} = 0b0; 12217 // Inst{20-12} 12218 let Inst{11-10} = 0b10; 12219 let Inst{9-5} = Rn; 12220 let Inst{4-0} = Rt; 12221 12222 let mayLoad = Inst{22}; 12223 let mayStore = !not(Inst{22}); 12224 let hasSideEffects = 0; 12225} 12226 12227class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2, 12228 dag oops, dag iops, string asm, 12229 string operands, string cstr> 12230 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12231 bits<5> Rt2; 12232 let Inst{20-16} = Rt2; 12233 let Inst{15-12} = opc2; 12234} 12235 12236class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops, 12237 string asm, string operands, string cstr> 12238 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12239 let Inst{20-12} = 0b000000000; // imm9 12240} 12241 12242multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype, 12243 dag oops, dag iops, string asm> { 12244 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> { 12245 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 12246 let Inst{20-12} = simm; 12247 } 12248 12249 def a : InstAlias<asm # "\t$Rt, [$Rn]", 12250 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 12251} 12252 12253class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst> 12254 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm, 12255 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>, 12256 Sched<[]> { 12257 bit Q; 12258 let Inst{31} = 0; 12259 let Inst{30} = Q; 12260 let Inst{23} = 0; 12261 let Inst{20-16} = 0b00001; 12262 let Inst{12} = 0; // S 12263 let Inst{11-10} = 0b01; // size 12264 12265 let mayLoad = L; 12266 let mayStore = !not(L); 12267 let hasSideEffects = 1; 12268} 12269 12270//--- 12271// Instrumentation Extension (FEAT_ITE) 12272//--- 12273 12274let Predicates = [HasITE] in 12275def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> { 12276 let Inst{20-19} = 0b01; 12277 let Inst{18-16} = 0b011; 12278 let Inst{15-12} = 0b0111; 12279 let Inst{11-8} = 0b0010; 12280 let Inst{7-5} = 0b111; 12281} 12282 12283// * RCWCAS family 12284// * RCW<OP> family 12285 12286//-------------------------------------------------------------------- 12287// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?) 12288 12289// Instruction encoding: 12290// 12291// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0 12292// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12293// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12294// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12295// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12296 12297// Instruction syntax: 12298// 12299// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 12300// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>] 12301 12302class BaseRCWCASEncoding<dag oops, dag iops, string asm> 12303 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>, 12304 Sched<[]> { 12305 bit Acq; 12306 bit Rel; 12307 bit SC; 12308 bit Pair; 12309 bits<5> Rs; 12310 bits<5> Rn; 12311 bits<5> Rt; 12312 let Inst{31} = 0b0; 12313 let Inst{30} = SC; 12314 let Inst{29-24} = 0b011001; 12315 let Inst{23} = Acq; 12316 let Inst{22} = Rel; 12317 let Inst{21} = 0b1; 12318 let Inst{20-16} = Rs; 12319 let Inst{15-13} = 0b000; 12320 let Inst{12-11} = 0b01; 12321 let Inst{10} = Pair; 12322 let Inst{9-5} = Rn; 12323 let Inst{4-0} = Rt; 12324 let mayLoad = 1; 12325 let mayStore = 1; 12326 let hasSideEffects = 1; 12327 let Defs = [NZCV]; 12328} 12329 12330multiclass BaseRCWCAS<dag oops, dag iops, string prefix> { 12331 let Acq = 0b0, Rel = 0b0 in 12332 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">; 12333 let Acq = 0b1, Rel = 0b0 in 12334 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">; 12335 let Acq = 0b0, Rel = 0b1 in 12336 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">; 12337 let Acq = 0b1, Rel = 0b1 in 12338 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">; 12339} 12340 12341multiclass ReadCheckWriteCompareAndSwap { 12342 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in 12343 defm CAS : BaseRCWCAS<(outs GPR64:$out), 12344 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >; 12345 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in 12346 defm SCAS : BaseRCWCAS<(outs GPR64:$out), 12347 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">; 12348 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12349 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12350 (ins XSeqPairClassOperand:$Rs, 12351 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12352 "rcwcasp">; 12353 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12354 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12355 (ins XSeqPairClassOperand:$Rs, 12356 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12357 "rcwscasp">; 12358} 12359 12360//------------------------------------------------------------------ 12361// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?) 12362 12363// Instruction encoding: 12364// 12365// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12366// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12367// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12368// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12369// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12370// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12371// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12372 12373// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12374// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12375// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12376// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12377// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12378// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12379// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12380 12381// Instruction syntax: 12382// 12383// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 12384// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>] 12385 12386class BaseRCWOPEncoding<string asm> 12387 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm, 12388 "\t$Rs, $Rt, [$Rn]", "", []>, 12389 Sched<[]> { 12390 bit Acq; 12391 bit Rel; 12392 bit SC; 12393 bits<3> opc; 12394 bits<5> Rs; 12395 bits<5> Rn; 12396 bits<5> Rt; 12397 let Inst{31} = 0b0; 12398 let Inst{30} = SC; 12399 let Inst{29-24} = 0b111000; 12400 let Inst{23} = Acq; 12401 let Inst{22} = Rel; 12402 let Inst{21} = 0b1; 12403 let Inst{20-16} = Rs; 12404 let Inst{15} = 0b1; 12405 let Inst{14-12} = opc; 12406 let Inst{11-10} = 0b00; 12407 let Inst{9-5} = Rn; 12408 let Inst{4-0} = Rt; 12409 let mayLoad = 1; 12410 let mayStore = 1; 12411 let hasSideEffects = 1; 12412 let Defs = [NZCV]; 12413 let Predicates = [HasTHE]; 12414} 12415 12416class BaseRCWOPPEncoding<string asm> 12417 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12418 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm, 12419 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12420 Sched<[]> { 12421 bit Acq; 12422 bit Rel; 12423 bit SC; 12424 bits<3> opc; 12425 bits<5> Rt2; 12426 bits<5> Rn; 12427 bits<5> Rt; 12428 let Inst{31} = 0b0; 12429 let Inst{30} = SC; 12430 let Inst{29-24} = 0b011001; 12431 let Inst{23} = Acq; 12432 let Inst{22} = Rel; 12433 let Inst{21} = 0b1; 12434 let Inst{20-16} = Rt2; 12435 let Inst{15} = 0b1; 12436 let Inst{14-12} = opc; 12437 let Inst{11-10} = 0b00; 12438 let Inst{9-5} = Rn; 12439 let Inst{4-0} = Rt; 12440 let mayLoad = 1; 12441 let mayStore = 1; 12442 let hasSideEffects = 1; 12443 let Defs = [NZCV]; 12444 let Predicates = [HasTHE, HasD128]; 12445} 12446 12447multiclass BaseRCWOP<string prefix> { 12448 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">; 12449 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">; 12450 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">; 12451 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">; 12452 12453 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">; 12454 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">; 12455 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">; 12456 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">; 12457} 12458 12459multiclass ReadCheckWriteOperation<bits<3> opc, string op> { 12460 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>; 12461 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >; 12462} 12463 12464//--- 12465// 128-bit atomic instructions (FEAT_LSE128) 12466//--- 12467 12468let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in 12469class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm> 12470: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12471 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), 12472 asm, "\t$Rt, $Rt2, [$Rn]", 12473 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12474 Sched<[]> { 12475 bits<5> Rt; 12476 bits<5> Rt2; 12477 bits<5> Rn; 12478 let Inst{31-24} = 0b00011001; 12479 let Inst{23-22} = AR; 12480 let Inst{21} = 0b1; 12481 let Inst{20-16} = Rt2; 12482 let Inst{15} = o3; 12483 let Inst{14-12} = op0; 12484 let Inst{11-10} = 0b00; 12485 let Inst{9-5} = Rn; 12486 let Inst{4-0} = Rt; 12487} 12488 12489//--- 12490// 128-bit System Instructions (FEAT_SYSINSTR128) 12491//--- 12492 12493// Instruction encoding: 12494// 12495// 31 19|18 16|15 12|11 8|7 5|4 0 12496// SYSP 1101010101001| op1| Cn| Cm|op2| Rt 12497 12498// Instruction syntax: 12499// 12500// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>} 12501 12502class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> : 12503 RtSystemI<L, oops, iops, asm, operands, pattern> { 12504 let Inst{22} = 0b1; // override BaseSystemI 12505} 12506 12507class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs> 12508 : RtSystemI128<L, outputs, inputs, asm, operands> { 12509 bits<3> op1; 12510 bits<4> Cn; 12511 bits<4> Cm; 12512 bits<3> op2; 12513 let Inst{20-19} = 0b01; 12514 let Inst{18-16} = op1; 12515 let Inst{15-12} = Cn; 12516 let Inst{11-8} = Cm; 12517 let Inst{7-5} = op2; 12518} 12519class SystemPXtI<bit L, string asm> : 12520 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs), 12521 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>; 12522 12523//---------------------------------------------------------------------------- 12524// 2023 Armv9.5 Extensions 12525//---------------------------------------------------------------------------- 12526 12527//--- 12528// Checked Pointer Arithmetic (FEAT_CPA) 12529//--- 12530 12531def LSLImm3ShiftOperand : AsmOperandClass { 12532 let SuperClasses = [ExtendOperandLSL64]; 12533 let Name = "LSLImm3Shift"; 12534 let RenderMethod = "addLSLImm3ShifterOperands"; 12535 let DiagnosticType = "AddSubLSLImm3ShiftLarge"; 12536} 12537 12538def lsl_imm3_shift_operand : Operand<i32> { 12539 let PrintMethod = "printShifter"; 12540 let ParserMatchClass = LSLImm3ShiftOperand; 12541} 12542 12543// Base CPA scalar add/subtract with lsl #imm3 shift 12544class BaseAddSubCPA<bit isSub, string asm> : I<(outs GPR64sp:$Rd), 12545 (ins GPR64sp:$Rn, GPR64:$Rm, lsl_imm3_shift_operand:$shift_imm), 12546 asm, "\t$Rd, $Rn, $Rm$shift_imm", "", []>, Sched<[]> { 12547 bits<5> Rd; 12548 bits<5> Rn; 12549 bits<5> Rm; 12550 bits<3> shift_imm; 12551 let Inst{31} = 0b1; 12552 let Inst{30} = isSub; 12553 let Inst{29-21} = 0b011010000; 12554 let Inst{20-16} = Rm; 12555 let Inst{15-13} = 0b001; 12556 let Inst{12-10} = shift_imm; 12557 let Inst{9-5} = Rn; 12558 let Inst{4-0} = Rd; 12559} 12560 12561// Alias for CPA scalar add/subtract with no shift 12562class AddSubCPAAlias<string asm, Instruction inst> 12563 : InstAlias<asm#"\t$Rd, $Rn, $Rm", 12564 (inst GPR64sp:$Rd, GPR64sp:$Rn, GPR64:$Rm, 0)>; 12565 12566multiclass AddSubCPA<bit isSub, string asm> { 12567 def _shift : BaseAddSubCPA<isSub, asm>; 12568 def _noshift : AddSubCPAAlias<asm, !cast<Instruction>(NAME#"_shift")>; 12569} 12570 12571class MulAccumCPA<bit isSub, string asm> 12572 : BaseMulAccum<isSub, 0b011, GPR64, GPR64, asm, []>, Sched<[]> { 12573 let Inst{31} = 0b1; 12574} 12575 12576//---------------------------------------------------------------------------- 12577// Allow the size specifier tokens to be upper case, not just lower. 12578def : TokenAlias<".4B", ".4b">; // Add dot product 12579def : TokenAlias<".8B", ".8b">; 12580def : TokenAlias<".4H", ".4h">; 12581def : TokenAlias<".2S", ".2s">; 12582def : TokenAlias<".1D", ".1d">; 12583def : TokenAlias<".16B", ".16b">; 12584def : TokenAlias<".8H", ".8h">; 12585def : TokenAlias<".4S", ".4s">; 12586def : TokenAlias<".2D", ".2d">; 12587def : TokenAlias<".1Q", ".1q">; 12588def : TokenAlias<".2H", ".2h">; 12589def : TokenAlias<".2B", ".2b">; 12590def : TokenAlias<".B", ".b">; 12591def : TokenAlias<".H", ".h">; 12592def : TokenAlias<".S", ".s">; 12593def : TokenAlias<".D", ".d">; 12594def : TokenAlias<".Q", ".q">; 12595