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 let hasPostISelHook = 1; 2813} 2814 2815class BaseAddSubRegPseudo<RegisterClass regtype, 2816 SDPatternOperator OpNode> 2817 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2818 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2819 Sched<[WriteI, ReadI, ReadI]>; 2820 2821class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2822 arith_shifted_reg shifted_regtype, string asm, 2823 SDPatternOperator OpNode> 2824 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 2825 asm, "\t$Rd, $Rn, $Rm_and_shift", "", 2826 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>, 2827 Sched<[WriteISReg, ReadI, ReadISReg]> { 2828 bits<5> Rd; 2829 bits<5> Rn; 2830 bits<5> Rm; 2831 bits<8> shift; 2832 let Inst{30} = isSub; 2833 let Inst{29} = setFlags; 2834 let Inst{28-24} = 0b01011; 2835 let Inst{23-22} = shift{7-6}; 2836 let Inst{21} = 0; 2837 let Inst{20-16} = Rm; 2838 let Inst{15-10} = shift{5-0}; 2839 let Inst{9-5} = Rn; 2840 let Inst{4-0} = Rd; 2841 2842 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2843} 2844 2845class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2846 RegisterClass src1Regtype, Operand src2Regtype, 2847 string asm, SDPatternOperator OpNode> 2848 : I<(outs dstRegtype:$Rd), 2849 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend), 2850 asm, "\t$Rd, $Rn, $Rm_and_extend", "", 2851 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>, 2852 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2853 bits<5> Rd; 2854 bits<5> Rn; 2855 bits<5> Rm; 2856 bits<6> extend; 2857 let Inst{30} = isSub; 2858 let Inst{29} = setFlags; 2859 let Inst{28-24} = 0b01011; 2860 let Inst{23-21} = 0b001; 2861 let Inst{20-16} = Rm; 2862 let Inst{15-13} = extend{5-3}; 2863 let Inst{12-10} = extend{2-0}; 2864 let Inst{9-5} = Rn; 2865 let Inst{4-0} = Rd; 2866 2867 let DecoderMethod = "DecodeAddSubERegInstruction"; 2868} 2869 2870let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2871class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2872 RegisterClass src1Regtype, RegisterClass src2Regtype, 2873 Operand ext_op, string asm> 2874 : I<(outs dstRegtype:$Rd), 2875 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2876 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2877 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2878 bits<5> Rd; 2879 bits<5> Rn; 2880 bits<5> Rm; 2881 bits<6> ext; 2882 let Inst{30} = isSub; 2883 let Inst{29} = setFlags; 2884 let Inst{28-24} = 0b01011; 2885 let Inst{23-21} = 0b001; 2886 let Inst{20-16} = Rm; 2887 let Inst{15} = ext{5}; 2888 let Inst{12-10} = ext{2-0}; 2889 let Inst{9-5} = Rn; 2890 let Inst{4-0} = Rd; 2891 2892 let DecoderMethod = "DecodeAddSubERegInstruction"; 2893} 2894 2895// Aliases for register+register add/subtract. 2896class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2897 RegisterClass src1Regtype, RegisterClass src2Regtype, 2898 int shiftExt> 2899 : InstAlias<asm#"\t$dst, $src1, $src2", 2900 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2901 shiftExt)>; 2902 2903multiclass AddSub<bit isSub, string mnemonic, string alias, 2904 SDPatternOperator OpNode = null_frag> { 2905 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2906 // Add/Subtract immediate 2907 // Increase the weight of the immediate variant to try to match it before 2908 // the extended register variant. 2909 // We used to match the register variant before the immediate when the 2910 // register argument could be implicitly zero-extended. 2911 let AddedComplexity = 6 in 2912 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2913 mnemonic, OpNode> { 2914 let Inst{31} = 0; 2915 } 2916 let AddedComplexity = 6 in 2917 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2918 mnemonic, OpNode> { 2919 let Inst{31} = 1; 2920 } 2921 2922 // Add/Subtract register - Only used for CodeGen 2923 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2924 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2925 2926 // Add/Subtract shifted register 2927 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2928 OpNode> { 2929 let Inst{31} = 0; 2930 } 2931 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2932 OpNode> { 2933 let Inst{31} = 1; 2934 } 2935 } 2936 2937 // Add/Subtract extended register 2938 let AddedComplexity = 1, hasSideEffects = 0 in { 2939 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2940 arith_extended_reg32_i32, mnemonic, OpNode> { 2941 let Inst{31} = 0; 2942 } 2943 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2944 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2945 let Inst{31} = 1; 2946 } 2947 } 2948 2949 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2950 arith_extendlsl64, mnemonic> { 2951 // UXTX and SXTX only. 2952 let Inst{14-13} = 0b11; 2953 let Inst{31} = 1; 2954 } 2955 2956 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2957 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2958 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2959 addsub_shifted_imm32_neg:$imm), 0>; 2960 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2961 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2962 addsub_shifted_imm64_neg:$imm), 0>; 2963 2964 // Register/register aliases with no shift when SP is not used. 2965 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2966 GPR32, GPR32, GPR32, 0>; 2967 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2968 GPR64, GPR64, GPR64, 0>; 2969 2970 // Register/register aliases with no shift when either the destination or 2971 // first source register is SP. 2972 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2973 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2974 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2975 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2976 def : AddSubRegAlias<mnemonic, 2977 !cast<Instruction>(NAME#"Xrx64"), 2978 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2979 def : AddSubRegAlias<mnemonic, 2980 !cast<Instruction>(NAME#"Xrx64"), 2981 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2982} 2983 2984multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2985 string alias, string cmpAlias> { 2986 let isCompare = 1, Defs = [NZCV] in { 2987 // Add/Subtract immediate 2988 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2989 mnemonic, OpNode> { 2990 let Inst{31} = 0; 2991 } 2992 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2993 mnemonic, OpNode> { 2994 let Inst{31} = 1; 2995 } 2996 2997 // Add/Subtract register 2998 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2999 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 3000 3001 // Add/Subtract shifted register 3002 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 3003 OpNode> { 3004 let Inst{31} = 0; 3005 } 3006 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 3007 OpNode> { 3008 let Inst{31} = 1; 3009 } 3010 3011 // Add/Subtract extended register 3012 let AddedComplexity = 1 in { 3013 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 3014 arith_extended_reg32_i32, mnemonic, OpNode> { 3015 let Inst{31} = 0; 3016 } 3017 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 3018 arith_extended_reg32_i64, mnemonic, OpNode> { 3019 let Inst{31} = 1; 3020 } 3021 } 3022 3023 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 3024 arith_extendlsl64, mnemonic> { 3025 // UXTX and SXTX only. 3026 let Inst{14-13} = 0b11; 3027 let Inst{31} = 1; 3028 } 3029 } // Defs = [NZCV] 3030 3031 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 3032 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3033 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 3034 addsub_shifted_imm32_neg:$imm), 0>; 3035 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 3036 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 3037 addsub_shifted_imm64_neg:$imm), 0>; 3038 3039 // Compare aliases 3040 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 3041 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 3042 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 3043 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 3044 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 3045 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 3046 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 3047 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 3048 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 3049 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 3050 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 3051 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 3052 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 3053 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 3054 3055 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 3056 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 3057 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 3058 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 3059 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 3060 3061 // Compare shorthands 3062 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 3063 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 3064 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 3065 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 3066 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 3067 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 3068 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 3069 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 3070 3071 // Register/register aliases with no shift when SP is not used. 3072 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 3073 GPR32, GPR32, GPR32, 0>; 3074 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 3075 GPR64, GPR64, GPR64, 0>; 3076 3077 // Register/register aliases with no shift when the first source register 3078 // is SP. 3079 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 3080 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 3081 def : AddSubRegAlias<mnemonic, 3082 !cast<Instruction>(NAME#"Xrx64"), 3083 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 3084} 3085 3086class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 3087 : BaseAddSubImm< 3088 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 3089 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 3090 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 3091 bits<6> imm6; 3092 bits<4> imm4; 3093 let Inst{31} = 1; 3094 let Inst{23-22} = 0b10; 3095 let Inst{21-16} = imm6; 3096 let Inst{15-14} = 0b00; 3097 let Inst{13-10} = imm4; 3098 let Unpredictable{15-14} = 0b11; 3099} 3100 3101class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 3102 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode, 3103 GPR64sp, GPR64sp>; 3104 3105//--- 3106// Extract 3107//--- 3108def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 3109 SDTCisPtrTy<3>]>; 3110def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 3111 3112class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 3113 list<dag> patterns> 3114 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 3115 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 3116 Sched<[WriteExtr, ReadExtrHi]> { 3117 bits<5> Rd; 3118 bits<5> Rn; 3119 bits<5> Rm; 3120 bits<6> imm; 3121 3122 let Inst{30-23} = 0b00100111; 3123 let Inst{21} = 0; 3124 let Inst{20-16} = Rm; 3125 let Inst{15-10} = imm; 3126 let Inst{9-5} = Rn; 3127 let Inst{4-0} = Rd; 3128} 3129 3130multiclass ExtractImm<string asm> { 3131 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 3132 [(set GPR32:$Rd, 3133 (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 3134 let Inst{31} = 0; 3135 let Inst{22} = 0; 3136 // imm<5> must be zero. 3137 let imm{5} = 0; 3138 } 3139 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 3140 [(set GPR64:$Rd, 3141 (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 3142 3143 let Inst{31} = 1; 3144 let Inst{22} = 1; 3145 } 3146} 3147 3148//--- 3149// Bitfield 3150//--- 3151 3152let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3153class BaseBitfieldImm<bits<2> opc, 3154 RegisterClass regtype, Operand imm_type, string asm> 3155 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 3156 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 3157 Sched<[WriteIS, ReadI]> { 3158 bits<5> Rd; 3159 bits<5> Rn; 3160 bits<6> immr; 3161 bits<6> imms; 3162 3163 let Inst{30-29} = opc; 3164 let Inst{28-23} = 0b100110; 3165 let Inst{21-16} = immr; 3166 let Inst{15-10} = imms; 3167 let Inst{9-5} = Rn; 3168 let Inst{4-0} = Rd; 3169} 3170 3171multiclass BitfieldImm<bits<2> opc, string asm> { 3172 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 3173 let Inst{31} = 0; 3174 let Inst{22} = 0; 3175 // imms<5> and immr<5> must be zero, else ReservedValue(). 3176 let Inst{21} = 0; 3177 let Inst{15} = 0; 3178 } 3179 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 3180 let Inst{31} = 1; 3181 let Inst{22} = 1; 3182 } 3183} 3184 3185let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3186class BaseBitfieldImmWith2RegArgs<bits<2> opc, 3187 RegisterClass regtype, Operand imm_type, string asm> 3188 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 3189 imm_type:$imms), 3190 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 3191 Sched<[WriteIS, ReadI]> { 3192 bits<5> Rd; 3193 bits<5> Rn; 3194 bits<6> immr; 3195 bits<6> imms; 3196 3197 let Inst{30-29} = opc; 3198 let Inst{28-23} = 0b100110; 3199 let Inst{21-16} = immr; 3200 let Inst{15-10} = imms; 3201 let Inst{9-5} = Rn; 3202 let Inst{4-0} = Rd; 3203} 3204 3205multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 3206 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 3207 let Inst{31} = 0; 3208 let Inst{22} = 0; 3209 // imms<5> and immr<5> must be zero, else ReservedValue(). 3210 let Inst{21} = 0; 3211 let Inst{15} = 0; 3212 } 3213 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 3214 let Inst{31} = 1; 3215 let Inst{22} = 1; 3216 } 3217} 3218 3219//--- 3220// Logical 3221//--- 3222 3223// Logical (immediate) 3224class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 3225 RegisterClass sregtype, Operand imm_type, string asm, 3226 list<dag> pattern> 3227 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 3228 asm, "\t$Rd, $Rn, $imm", "", pattern>, 3229 Sched<[WriteI, ReadI]> { 3230 bits<5> Rd; 3231 bits<5> Rn; 3232 bits<13> imm; 3233 let Inst{30-29} = opc; 3234 let Inst{28-23} = 0b100100; 3235 let Inst{22} = imm{12}; 3236 let Inst{21-16} = imm{11-6}; 3237 let Inst{15-10} = imm{5-0}; 3238 let Inst{9-5} = Rn; 3239 let Inst{4-0} = Rd; 3240 3241 let DecoderMethod = "DecodeLogicalImmInstruction"; 3242} 3243 3244// Logical (shifted register) 3245class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 3246 logical_shifted_reg shifted_regtype, string asm, 3247 list<dag> pattern> 3248 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift), 3249 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>, 3250 Sched<[WriteISReg, ReadI, ReadISReg]> { 3251 bits<5> Rd; 3252 bits<5> Rn; 3253 bits<5> Rm; 3254 bits<8> shift; 3255 let Inst{30-29} = opc; 3256 let Inst{28-24} = 0b01010; 3257 let Inst{23-22} = shift{7-6}; 3258 let Inst{21} = N; 3259 let Inst{20-16} = Rm; 3260 let Inst{15-10} = shift{5-0}; 3261 let Inst{9-5} = Rn; 3262 let Inst{4-0} = Rd; 3263 3264 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 3265} 3266 3267// Aliases for register+register logical instructions. 3268class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 3269 : InstAlias<asm#"\t$dst, $src1, $src2", 3270 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 3271 3272multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 3273 string Alias> { 3274 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3275 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 3276 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 3277 logical_imm32:$imm))]> { 3278 let Inst{31} = 0; 3279 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3280 } 3281 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 3282 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 3283 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 3284 logical_imm64:$imm))]> { 3285 let Inst{31} = 1; 3286 } 3287 3288 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3289 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 3290 logical_imm32_not:$imm), 0>; 3291 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3292 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 3293 logical_imm64_not:$imm), 0>; 3294} 3295 3296multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 3297 string Alias> { 3298 let isCompare = 1, Defs = [NZCV] in { 3299 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 3300 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 3301 let Inst{31} = 0; 3302 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 3303 } 3304 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 3305 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 3306 let Inst{31} = 1; 3307 } 3308 } // end Defs = [NZCV] 3309 3310 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3311 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 3312 logical_imm32_not:$imm), 0>; 3313 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 3314 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 3315 logical_imm64_not:$imm), 0>; 3316} 3317 3318class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 3319 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3320 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 3321 Sched<[WriteI, ReadI, ReadI]>; 3322 3323// Split from LogicalImm as not all instructions have both. 3324multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 3325 SDPatternOperator OpNode, int AddedComplexityVal = 0> { 3326 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in { 3327 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3328 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3329 } 3330 3331 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3332 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 3333 logical_shifted_reg32:$Rm_and_shift))]> { 3334 let Inst{31} = 0; 3335 } 3336 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3337 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 3338 logical_shifted_reg64:$Rm_and_shift))]> { 3339 let Inst{31} = 1; 3340 } 3341 3342 def : LogicalRegAlias<mnemonic, 3343 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3344 def : LogicalRegAlias<mnemonic, 3345 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3346} 3347 3348// Split from LogicalReg to allow setting NZCV Defs 3349multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 3350 SDPatternOperator OpNode = null_frag> { 3351 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 3352 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 3353 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 3354 3355 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 3356 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> { 3357 let Inst{31} = 0; 3358 } 3359 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 3360 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> { 3361 let Inst{31} = 1; 3362 } 3363 } // Defs = [NZCV] 3364 3365 def : LogicalRegAlias<mnemonic, 3366 !cast<Instruction>(NAME#"Wrs"), GPR32>; 3367 def : LogicalRegAlias<mnemonic, 3368 !cast<Instruction>(NAME#"Xrs"), GPR64>; 3369} 3370 3371//--- 3372// Conditionally set flags 3373//--- 3374 3375let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3376class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 3377 string mnemonic, SDNode OpNode> 3378 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 3379 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 3380 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 3381 (i32 imm:$cond), NZCV))]>, 3382 Sched<[WriteI, ReadI]> { 3383 let Uses = [NZCV]; 3384 let Defs = [NZCV]; 3385 3386 bits<5> Rn; 3387 bits<5> imm; 3388 bits<4> nzcv; 3389 bits<4> cond; 3390 3391 let Inst{30} = op; 3392 let Inst{29-21} = 0b111010010; 3393 let Inst{20-16} = imm; 3394 let Inst{15-12} = cond; 3395 let Inst{11-10} = 0b10; 3396 let Inst{9-5} = Rn; 3397 let Inst{4} = 0b0; 3398 let Inst{3-0} = nzcv; 3399} 3400 3401let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3402class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 3403 SDNode OpNode> 3404 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 3405 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 3406 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 3407 (i32 imm:$cond), NZCV))]>, 3408 Sched<[WriteI, ReadI, ReadI]> { 3409 let Uses = [NZCV]; 3410 let Defs = [NZCV]; 3411 3412 bits<5> Rn; 3413 bits<5> Rm; 3414 bits<4> nzcv; 3415 bits<4> cond; 3416 3417 let Inst{30} = op; 3418 let Inst{29-21} = 0b111010010; 3419 let Inst{20-16} = Rm; 3420 let Inst{15-12} = cond; 3421 let Inst{11-10} = 0b00; 3422 let Inst{9-5} = Rn; 3423 let Inst{4} = 0b0; 3424 let Inst{3-0} = nzcv; 3425} 3426 3427multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 3428 // immediate operand variants 3429 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 3430 let Inst{31} = 0; 3431 } 3432 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 3433 let Inst{31} = 1; 3434 } 3435 // register operand variants 3436 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 3437 let Inst{31} = 0; 3438 } 3439 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 3440 let Inst{31} = 1; 3441 } 3442} 3443 3444//--- 3445// Conditional select 3446//--- 3447 3448class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 3449 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3450 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3451 [(set regtype:$Rd, 3452 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 3453 Sched<[WriteI, ReadI, ReadI]> { 3454 let Uses = [NZCV]; 3455 3456 bits<5> Rd; 3457 bits<5> Rn; 3458 bits<5> Rm; 3459 bits<4> cond; 3460 3461 let Inst{30} = op; 3462 let Inst{29-21} = 0b011010100; 3463 let Inst{20-16} = Rm; 3464 let Inst{15-12} = cond; 3465 let Inst{11-10} = op2; 3466 let Inst{9-5} = Rn; 3467 let Inst{4-0} = Rd; 3468} 3469 3470multiclass CondSelect<bit op, bits<2> op2, string asm> { 3471 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 3472 let Inst{31} = 0; 3473 } 3474 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 3475 let Inst{31} = 1; 3476 } 3477} 3478 3479class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 3480 PatFrag frag> 3481 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3482 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3483 [(set regtype:$Rd, 3484 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 3485 (i32 imm:$cond), NZCV))]>, 3486 Sched<[WriteI, ReadI, ReadI]> { 3487 let Uses = [NZCV]; 3488 3489 bits<5> Rd; 3490 bits<5> Rn; 3491 bits<5> Rm; 3492 bits<4> cond; 3493 3494 let Inst{30} = op; 3495 let Inst{29-21} = 0b011010100; 3496 let Inst{20-16} = Rm; 3497 let Inst{15-12} = cond; 3498 let Inst{11-10} = op2; 3499 let Inst{9-5} = Rn; 3500 let Inst{4-0} = Rd; 3501} 3502 3503def inv_cond_XFORM : SDNodeXForm<imm, [{ 3504 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 3505 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 3506 MVT::i32); 3507}]>; 3508 3509multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 3510 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 3511 let Inst{31} = 0; 3512 } 3513 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 3514 let Inst{31} = 1; 3515 } 3516 3517 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 3518 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 3519 (inv_cond_XFORM imm:$cond))>; 3520 3521 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 3522 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 3523 (inv_cond_XFORM imm:$cond))>; 3524} 3525 3526//--- 3527// Special Mask Value 3528//--- 3529def maski8_or_more : Operand<i32>, 3530 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 3531} 3532def maski16_or_more : Operand<i32>, 3533 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 3534} 3535 3536 3537//--- 3538// Load/store 3539//--- 3540 3541// (unsigned immediate) 3542// Indexed for 8-bit registers. offset is in range [0,4095]. 3543def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>; 3544def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>; 3545def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>; 3546def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>; 3547def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>; 3548 3549// (unsigned immediate) 3550// Indexed for 8-bit registers. offset is in range [0,63]. 3551def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>; 3552def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>; 3553def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>; 3554def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>; 3555 3556def gi_am_indexed8 : 3557 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 3558 GIComplexPatternEquiv<am_indexed8>; 3559def gi_am_indexed16 : 3560 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 3561 GIComplexPatternEquiv<am_indexed16>; 3562def gi_am_indexed32 : 3563 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 3564 GIComplexPatternEquiv<am_indexed32>; 3565def gi_am_indexed64 : 3566 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 3567 GIComplexPatternEquiv<am_indexed64>; 3568def gi_am_indexed128 : 3569 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 3570 GIComplexPatternEquiv<am_indexed128>; 3571 3572class UImm12OffsetOperand<int Scale> : AsmOperandClass { 3573 let Name = "UImm12Offset" # Scale; 3574 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 3575 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 3576 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 3577} 3578 3579def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 3580def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 3581def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 3582def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 3583def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 3584 3585class uimm12_scaled<int Scale> : Operand<i64> { 3586 let ParserMatchClass 3587 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 3588 let EncoderMethod 3589 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 3590 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 3591} 3592 3593def uimm12s1 : uimm12_scaled<1>; 3594def uimm12s2 : uimm12_scaled<2>; 3595def uimm12s4 : uimm12_scaled<4>; 3596def uimm12s8 : uimm12_scaled<8>; 3597def uimm12s16 : uimm12_scaled<16>; 3598 3599class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3600 string asm, list<dag> pattern> 3601 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3602 bits<5> Rt; 3603 3604 bits<5> Rn; 3605 bits<12> offset; 3606 3607 let Inst{31-30} = sz; 3608 let Inst{29-27} = 0b111; 3609 let Inst{26} = V; 3610 let Inst{25-24} = 0b01; 3611 let Inst{23-22} = opc; 3612 let Inst{21-10} = offset; 3613 let Inst{9-5} = Rn; 3614 let Inst{4-0} = Rt; 3615 3616 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 3617} 3618 3619multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3620 Operand indextype, string asm, list<dag> pattern> { 3621 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3622 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 3623 (ins GPR64sp:$Rn, indextype:$offset), 3624 asm, pattern>, 3625 Sched<[WriteLD]>; 3626 3627 def : InstAlias<asm # "\t$Rt, [$Rn]", 3628 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3629} 3630 3631multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3632 Operand indextype, string asm, list<dag> pattern> { 3633 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3634 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3635 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3636 asm, pattern>, 3637 Sched<[WriteST]>; 3638 3639 def : InstAlias<asm # "\t$Rt, [$Rn]", 3640 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3641} 3642 3643// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 3644// substitute zero-registers automatically. 3645// 3646// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 3647// into StoreUI. 3648multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3649 Operand indextype, string asm, list<dag> pattern> { 3650 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3651 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 3652 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 3653 asm, pattern>, 3654 Sched<[WriteST]>; 3655 3656 def : InstAlias<asm # "\t$Rt, [$Rn]", 3657 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 3658} 3659 3660def PrefetchOperand : AsmOperandClass { 3661 let Name = "Prefetch"; 3662 let ParserMethod = "tryParsePrefetch"; 3663} 3664def prfop : Operand<i32> { 3665 let PrintMethod = "printPrefetchOp"; 3666 let ParserMatchClass = PrefetchOperand; 3667} 3668 3669let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3670class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 3671 : BaseLoadStoreUI<sz, V, opc, 3672 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 3673 asm, pat>, 3674 Sched<[WriteLD]>; 3675 3676//--- 3677// Load literal 3678//--- 3679 3680// Load literal address: 19-bit immediate. The low two bits of the target 3681// offset are implied zero and so are not part of the immediate. 3682def am_ldrlit : Operand<iPTR> { 3683 let EncoderMethod = "getLoadLiteralOpValue"; 3684 let DecoderMethod = "DecodePCRelLabel19"; 3685 let PrintMethod = "printAlignedLabel"; 3686 let ParserMatchClass = PCRelLabel19Operand; 3687 let OperandType = "OPERAND_PCREL"; 3688} 3689 3690let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 3691class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 3692 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 3693 asm, "\t$Rt, $label", "", pat>, 3694 Sched<[WriteLD]> { 3695 bits<5> Rt; 3696 bits<19> label; 3697 let Inst{31-30} = opc; 3698 let Inst{29-27} = 0b011; 3699 let Inst{26} = V; 3700 let Inst{25-24} = 0b00; 3701 let Inst{23-5} = label; 3702 let Inst{4-0} = Rt; 3703} 3704 3705let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3706class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3707 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3708 asm, "\t$Rt, $label", "", pat>, 3709 Sched<[WriteLD]> { 3710 bits<5> Rt; 3711 bits<19> label; 3712 let Inst{31-30} = opc; 3713 let Inst{29-27} = 0b011; 3714 let Inst{26} = V; 3715 let Inst{25-24} = 0b00; 3716 let Inst{23-5} = label; 3717 let Inst{4-0} = Rt; 3718} 3719 3720//--- 3721// Load/store register offset 3722//--- 3723 3724def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>; 3725def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>; 3726def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>; 3727def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>; 3728def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>; 3729 3730def gi_ro_Xindexed8 : 3731 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3732 GIComplexPatternEquiv<ro_Xindexed8>; 3733def gi_ro_Xindexed16 : 3734 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3735 GIComplexPatternEquiv<ro_Xindexed16>; 3736def gi_ro_Xindexed32 : 3737 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3738 GIComplexPatternEquiv<ro_Xindexed32>; 3739def gi_ro_Xindexed64 : 3740 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3741 GIComplexPatternEquiv<ro_Xindexed64>; 3742def gi_ro_Xindexed128 : 3743 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3744 GIComplexPatternEquiv<ro_Xindexed128>; 3745 3746def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>; 3747def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>; 3748def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>; 3749def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>; 3750def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>; 3751 3752def gi_ro_Windexed8 : 3753 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">, 3754 GIComplexPatternEquiv<ro_Windexed8>; 3755def gi_ro_Windexed16 : 3756 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">, 3757 GIComplexPatternEquiv<ro_Windexed16>; 3758def gi_ro_Windexed32 : 3759 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">, 3760 GIComplexPatternEquiv<ro_Windexed32>; 3761def gi_ro_Windexed64 : 3762 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">, 3763 GIComplexPatternEquiv<ro_Windexed64>; 3764def gi_ro_Windexed128 : 3765 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">, 3766 GIComplexPatternEquiv<ro_Windexed128>; 3767 3768class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3769 let Name = "Mem" # Reg # "Extend" # Width; 3770 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3771 let RenderMethod = "addMemExtendOperands"; 3772 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3773} 3774 3775def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3776 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3777 // the trivial shift. 3778 let RenderMethod = "addMemExtend8Operands"; 3779} 3780def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3781def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3782def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3783def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3784 3785def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3786 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3787 // the trivial shift. 3788 let RenderMethod = "addMemExtend8Operands"; 3789} 3790def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3791def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3792def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3793def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3794 3795class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3796 : Operand<i32> { 3797 let ParserMatchClass = ParserClass; 3798 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3799 let DecoderMethod = "DecodeMemExtend"; 3800 let EncoderMethod = "getMemExtendOpValue"; 3801 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3802} 3803 3804def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3805def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3806def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3807def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3808def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3809 3810def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3811def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3812def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3813def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3814def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3815 3816class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3817 Operand wextend, Operand xextend> { 3818 // CodeGen-level pattern covering the entire addressing mode. 3819 ComplexPattern Wpat = windex; 3820 ComplexPattern Xpat = xindex; 3821 3822 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3823 Operand Wext = wextend; 3824 Operand Xext = xextend; 3825} 3826 3827def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3828def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3829def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3830def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3831def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3832 ro_Xextend128>; 3833 3834class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3835 dag outs, list<dag> pat> 3836 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3837 bits<5> Rt; 3838 bits<5> Rn; 3839 bits<5> Rm; 3840 bits<2> extend; 3841 let Inst{31-30} = sz; 3842 let Inst{29-27} = 0b111; 3843 let Inst{26} = V; 3844 let Inst{25-24} = 0b00; 3845 let Inst{23-22} = opc; 3846 let Inst{21} = 1; 3847 let Inst{20-16} = Rm; 3848 let Inst{15} = extend{1}; // sign extend Rm? 3849 let Inst{14} = 1; 3850 let Inst{12} = extend{0}; // do shift? 3851 let Inst{11-10} = 0b10; 3852 let Inst{9-5} = Rn; 3853 let Inst{4-0} = Rt; 3854} 3855 3856class ROInstAlias<string asm, DAGOperand regtype, Instruction INST> 3857 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3858 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3859 3860multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3861 string asm, ValueType Ty, SDPatternOperator loadop> { 3862 let AddedComplexity = 10 in 3863 def roW : LoadStore8RO<sz, V, opc, asm, 3864 (outs regtype:$Rt), 3865 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3866 [(set (Ty regtype:$Rt), 3867 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3868 ro_Wextend8:$extend)))]>, 3869 Sched<[WriteLDIdx, ReadAdrBase]> { 3870 let Inst{13} = 0b0; 3871 } 3872 3873 let AddedComplexity = 10 in 3874 def roX : LoadStore8RO<sz, V, opc, asm, 3875 (outs regtype:$Rt), 3876 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3877 [(set (Ty regtype:$Rt), 3878 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3879 ro_Xextend8:$extend)))]>, 3880 Sched<[WriteLDIdx, ReadAdrBase]> { 3881 let Inst{13} = 0b1; 3882 } 3883 3884 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3885} 3886 3887multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3888 string asm, ValueType Ty, SDPatternOperator storeop> { 3889 let AddedComplexity = 10 in 3890 def roW : LoadStore8RO<sz, V, opc, asm, (outs), 3891 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3892 [(storeop (Ty regtype:$Rt), 3893 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3894 ro_Wextend8:$extend))]>, 3895 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3896 let Inst{13} = 0b0; 3897 } 3898 3899 let AddedComplexity = 10 in 3900 def roX : LoadStore8RO<sz, V, opc, asm, (outs), 3901 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3902 [(storeop (Ty regtype:$Rt), 3903 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3904 ro_Xextend8:$extend))]>, 3905 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3906 let Inst{13} = 0b1; 3907 } 3908 3909 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3910} 3911 3912class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3913 dag outs, list<dag> pat> 3914 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3915 bits<5> Rt; 3916 bits<5> Rn; 3917 bits<5> Rm; 3918 bits<2> extend; 3919 let Inst{31-30} = sz; 3920 let Inst{29-27} = 0b111; 3921 let Inst{26} = V; 3922 let Inst{25-24} = 0b00; 3923 let Inst{23-22} = opc; 3924 let Inst{21} = 1; 3925 let Inst{20-16} = Rm; 3926 let Inst{15} = extend{1}; // sign extend Rm? 3927 let Inst{14} = 1; 3928 let Inst{12} = extend{0}; // do shift? 3929 let Inst{11-10} = 0b10; 3930 let Inst{9-5} = Rn; 3931 let Inst{4-0} = Rt; 3932} 3933 3934multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3935 string asm, ValueType Ty, SDPatternOperator loadop> { 3936 let AddedComplexity = 10 in 3937 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3938 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3939 [(set (Ty regtype:$Rt), 3940 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3941 ro_Wextend16:$extend)))]>, 3942 Sched<[WriteLDIdx, ReadAdrBase]> { 3943 let Inst{13} = 0b0; 3944 } 3945 3946 let AddedComplexity = 10 in 3947 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt), 3948 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3949 [(set (Ty regtype:$Rt), 3950 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3951 ro_Xextend16:$extend)))]>, 3952 Sched<[WriteLDIdx, ReadAdrBase]> { 3953 let Inst{13} = 0b1; 3954 } 3955 3956 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3957} 3958 3959multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 3960 string asm, ValueType Ty, SDPatternOperator storeop> { 3961 let AddedComplexity = 10 in 3962 def roW : LoadStore16RO<sz, V, opc, asm, (outs), 3963 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3964 [(storeop (Ty regtype:$Rt), 3965 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3966 ro_Wextend16:$extend))]>, 3967 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3968 let Inst{13} = 0b0; 3969 } 3970 3971 let AddedComplexity = 10 in 3972 def roX : LoadStore16RO<sz, V, opc, asm, (outs), 3973 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3974 [(storeop (Ty regtype:$Rt), 3975 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3976 ro_Xextend16:$extend))]>, 3977 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 3978 let Inst{13} = 0b1; 3979 } 3980 3981 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3982} 3983 3984class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 3985 dag outs, list<dag> pat> 3986 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3987 bits<5> Rt; 3988 bits<5> Rn; 3989 bits<5> Rm; 3990 bits<2> extend; 3991 let Inst{31-30} = sz; 3992 let Inst{29-27} = 0b111; 3993 let Inst{26} = V; 3994 let Inst{25-24} = 0b00; 3995 let Inst{23-22} = opc; 3996 let Inst{21} = 1; 3997 let Inst{20-16} = Rm; 3998 let Inst{15} = extend{1}; // sign extend Rm? 3999 let Inst{14} = 1; 4000 let Inst{12} = extend{0}; // do shift? 4001 let Inst{11-10} = 0b10; 4002 let Inst{9-5} = Rn; 4003 let Inst{4-0} = Rt; 4004} 4005 4006multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4007 string asm, ValueType Ty, SDPatternOperator loadop> { 4008 let AddedComplexity = 10 in 4009 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 4010 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 4011 [(set (Ty regtype:$Rt), 4012 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 4013 ro_Wextend32:$extend)))]>, 4014 Sched<[WriteLDIdx, ReadAdrBase]> { 4015 let Inst{13} = 0b0; 4016 } 4017 4018 let AddedComplexity = 10 in 4019 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt), 4020 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 4021 [(set (Ty regtype:$Rt), 4022 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 4023 ro_Xextend32:$extend)))]>, 4024 Sched<[WriteLDIdx, ReadAdrBase]> { 4025 let Inst{13} = 0b1; 4026 } 4027 4028 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4029} 4030 4031multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4032 string asm, ValueType Ty, SDPatternOperator storeop> { 4033 let AddedComplexity = 10 in 4034 def roW : LoadStore32RO<sz, V, opc, asm, (outs), 4035 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 4036 [(storeop (Ty regtype:$Rt), 4037 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 4038 ro_Wextend32:$extend))]>, 4039 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4040 let Inst{13} = 0b0; 4041 } 4042 4043 let AddedComplexity = 10 in 4044 def roX : LoadStore32RO<sz, V, opc, asm, (outs), 4045 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 4046 [(storeop (Ty regtype:$Rt), 4047 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 4048 ro_Xextend32:$extend))]>, 4049 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4050 let Inst{13} = 0b1; 4051 } 4052 4053 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4054} 4055 4056class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4057 dag outs, list<dag> pat> 4058 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4059 bits<5> Rt; 4060 bits<5> Rn; 4061 bits<5> Rm; 4062 bits<2> extend; 4063 let Inst{31-30} = sz; 4064 let Inst{29-27} = 0b111; 4065 let Inst{26} = V; 4066 let Inst{25-24} = 0b00; 4067 let Inst{23-22} = opc; 4068 let Inst{21} = 1; 4069 let Inst{20-16} = Rm; 4070 let Inst{15} = extend{1}; // sign extend Rm? 4071 let Inst{14} = 1; 4072 let Inst{12} = extend{0}; // do shift? 4073 let Inst{11-10} = 0b10; 4074 let Inst{9-5} = Rn; 4075 let Inst{4-0} = Rt; 4076} 4077 4078multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4079 string asm, ValueType Ty, SDPatternOperator loadop> { 4080 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4081 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4082 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4083 [(set (Ty regtype:$Rt), 4084 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4085 ro_Wextend64:$extend)))]>, 4086 Sched<[WriteLDIdx, ReadAdrBase]> { 4087 let Inst{13} = 0b0; 4088 } 4089 4090 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4091 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt), 4092 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4093 [(set (Ty regtype:$Rt), 4094 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4095 ro_Xextend64:$extend)))]>, 4096 Sched<[WriteLDIdx, ReadAdrBase]> { 4097 let Inst{13} = 0b1; 4098 } 4099 4100 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4101} 4102 4103multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4104 string asm, ValueType Ty, SDPatternOperator storeop> { 4105 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4106 def roW : LoadStore64RO<sz, V, opc, asm, (outs), 4107 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4108 [(storeop (Ty regtype:$Rt), 4109 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4110 ro_Wextend64:$extend))]>, 4111 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4112 let Inst{13} = 0b0; 4113 } 4114 4115 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4116 def roX : LoadStore64RO<sz, V, opc, asm, (outs), 4117 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4118 [(storeop (Ty regtype:$Rt), 4119 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4120 ro_Xextend64:$extend))]>, 4121 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4122 let Inst{13} = 0b1; 4123 } 4124 4125 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4126} 4127 4128class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins, 4129 dag outs, list<dag> pat> 4130 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 4131 bits<5> Rt; 4132 bits<5> Rn; 4133 bits<5> Rm; 4134 bits<2> extend; 4135 let Inst{31-30} = sz; 4136 let Inst{29-27} = 0b111; 4137 let Inst{26} = V; 4138 let Inst{25-24} = 0b00; 4139 let Inst{23-22} = opc; 4140 let Inst{21} = 1; 4141 let Inst{20-16} = Rm; 4142 let Inst{15} = extend{1}; // sign extend Rm? 4143 let Inst{14} = 1; 4144 let Inst{12} = extend{0}; // do shift? 4145 let Inst{11-10} = 0b10; 4146 let Inst{9-5} = Rn; 4147 let Inst{4-0} = Rt; 4148} 4149 4150multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4151 string asm, ValueType Ty, SDPatternOperator loadop> { 4152 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4153 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4154 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4155 [(set (Ty regtype:$Rt), 4156 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 4157 ro_Wextend128:$extend)))]>, 4158 Sched<[WriteLDIdx, ReadAdrBase]> { 4159 let Inst{13} = 0b0; 4160 } 4161 4162 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 4163 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt), 4164 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4165 [(set (Ty regtype:$Rt), 4166 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 4167 ro_Xextend128:$extend)))]>, 4168 Sched<[WriteLDIdx, ReadAdrBase]> { 4169 let Inst{13} = 0b1; 4170 } 4171 4172 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4173} 4174 4175multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4176 string asm> { 4177 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4178 def roW : LoadStore128RO<sz, V, opc, asm, (outs), 4179 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 4180 []>, 4181 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4182 let Inst{13} = 0b0; 4183 } 4184 4185 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 4186 def roX : LoadStore128RO<sz, V, opc, asm, (outs), 4187 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 4188 []>, 4189 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> { 4190 let Inst{13} = 0b1; 4191 } 4192 4193 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 4194} 4195 4196let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4197class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 4198 string asm, list<dag> pat> 4199 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 4200 Sched<[WriteLD]> { 4201 bits<5> Rt; 4202 bits<5> Rn; 4203 bits<5> Rm; 4204 bits<2> extend; 4205 let Inst{31-30} = sz; 4206 let Inst{29-27} = 0b111; 4207 let Inst{26} = V; 4208 let Inst{25-24} = 0b00; 4209 let Inst{23-22} = opc; 4210 let Inst{21} = 1; 4211 let Inst{20-16} = Rm; 4212 let Inst{15} = extend{1}; // sign extend Rm? 4213 let Inst{14} = 1; 4214 let Inst{12} = extend{0}; // do shift? 4215 let Inst{11-10} = 0b10; 4216 let Inst{9-5} = Rn; 4217 let Inst{4-0} = Rt; 4218 let DecoderMethod = "DecodePRFMRegInstruction"; 4219 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When 4220 // the decoder method returns Fail, the decoder should attempt to decode the 4221 // instruction as RPRFM. 4222 let hasCompleteDecoder = 0; 4223} 4224 4225multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 4226 def roW : BasePrefetchRO<sz, V, opc, (outs), 4227 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 4228 asm, [(AArch64Prefetch timm:$Rt, 4229 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 4230 ro_Wextend64:$extend))]> { 4231 let Inst{13} = 0b0; 4232 } 4233 4234 def roX : BasePrefetchRO<sz, V, opc, (outs), 4235 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 4236 asm, [(AArch64Prefetch timm:$Rt, 4237 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 4238 ro_Xextend64:$extend))]> { 4239 let Inst{13} = 0b1; 4240 } 4241 4242 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 4243 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 4244 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 4245} 4246 4247//--- 4248// Load/store unscaled immediate 4249//--- 4250 4251def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>; 4252def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>; 4253def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>; 4254def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>; 4255def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>; 4256 4257def gi_am_unscaled8 : 4258 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 4259 GIComplexPatternEquiv<am_unscaled8>; 4260def gi_am_unscaled16 : 4261 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 4262 GIComplexPatternEquiv<am_unscaled16>; 4263def gi_am_unscaled32 : 4264 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 4265 GIComplexPatternEquiv<am_unscaled32>; 4266def gi_am_unscaled64 : 4267 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 4268 GIComplexPatternEquiv<am_unscaled64>; 4269def gi_am_unscaled128 : 4270 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 4271 GIComplexPatternEquiv<am_unscaled128>; 4272 4273 4274class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4275 string asm, list<dag> pattern> 4276 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 4277 bits<5> Rt; 4278 bits<5> Rn; 4279 bits<9> offset; 4280 let Inst{31-30} = sz; 4281 let Inst{29-27} = 0b111; 4282 let Inst{26} = V; 4283 let Inst{25-24} = 0b00; 4284 let Inst{23-22} = opc; 4285 let Inst{21} = 0; 4286 let Inst{20-12} = offset; 4287 let Inst{11-10} = 0b00; 4288 let Inst{9-5} = Rn; 4289 let Inst{4-0} = Rt; 4290 4291 let DecoderMethod = "DecodeSignedLdStInstruction"; 4292} 4293 4294// Armv8.4 LDAPR & STLR with Immediate Offset instruction 4295multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4296 DAGOperand regtype > { 4297 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 4298 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 4299 Sched<[WriteST]> { 4300 let Inst{29} = 0; 4301 let Inst{24} = 1; 4302 } 4303 def : InstAlias<asm # "\t$Rt, [$Rn]", 4304 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4305} 4306 4307multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 4308 DAGOperand regtype > { 4309 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 4310 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4311 asm, []>, 4312 Sched<[WriteST]> { 4313 let Inst{29} = 0; 4314 let Inst{24} = 1; 4315 } 4316 def : InstAlias<asm # "\t$Rt, [$Rn]", 4317 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4318} 4319 4320multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4321 string asm, list<dag> pattern> { 4322 let AddedComplexity = 1 in // try this before LoadUI 4323 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 4324 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 4325 Sched<[WriteLD]>; 4326 4327 def : InstAlias<asm # "\t$Rt, [$Rn]", 4328 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4329} 4330 4331multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype, 4332 string asm, list<dag> pattern> { 4333 let AddedComplexity = 1 in // try this before StoreUI 4334 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4335 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4336 asm, pattern>, 4337 Sched<[WriteST]>; 4338 4339 def : InstAlias<asm # "\t$Rt, [$Rn]", 4340 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4341} 4342 4343multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 4344 list<dag> pat> { 4345 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4346 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 4347 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 4348 asm, pat>, 4349 Sched<[WriteLD]>; 4350 4351 def : InstAlias<asm # "\t$Rt, [$Rn]", 4352 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 4353} 4354 4355//--- 4356// Load/store unscaled immediate, unprivileged 4357//--- 4358 4359class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4360 dag oops, dag iops, string asm> 4361 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 4362 bits<5> Rt; 4363 bits<5> Rn; 4364 bits<9> offset; 4365 let Inst{31-30} = sz; 4366 let Inst{29-27} = 0b111; 4367 let Inst{26} = V; 4368 let Inst{25-24} = 0b00; 4369 let Inst{23-22} = opc; 4370 let Inst{21} = 0; 4371 let Inst{20-12} = offset; 4372 let Inst{11-10} = 0b10; 4373 let Inst{9-5} = Rn; 4374 let Inst{4-0} = Rt; 4375 4376 let DecoderMethod = "DecodeSignedLdStInstruction"; 4377} 4378 4379multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 4380 RegisterClass regtype, string asm> { 4381 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 4382 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 4383 (ins GPR64sp:$Rn, simm9:$offset), asm>, 4384 Sched<[WriteLD]>; 4385 4386 def : InstAlias<asm # "\t$Rt, [$Rn]", 4387 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4388} 4389 4390multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 4391 RegisterClass regtype, string asm> { 4392 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 4393 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 4394 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4395 asm>, 4396 Sched<[WriteST]>; 4397 4398 def : InstAlias<asm # "\t$Rt, [$Rn]", 4399 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 4400} 4401 4402//--- 4403// Load/store pre-indexed 4404//--- 4405 4406class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4407 string asm, string cstr, list<dag> pat> 4408 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 4409 bits<5> Rt; 4410 bits<5> Rn; 4411 bits<9> offset; 4412 let Inst{31-30} = sz; 4413 let Inst{29-27} = 0b111; 4414 let Inst{26} = V; 4415 let Inst{25-24} = 0; 4416 let Inst{23-22} = opc; 4417 let Inst{21} = 0; 4418 let Inst{20-12} = offset; 4419 let Inst{11-10} = 0b11; 4420 let Inst{9-5} = Rn; 4421 let Inst{4-0} = Rt; 4422 4423 let DecoderMethod = "DecodeSignedLdStInstruction"; 4424} 4425 4426let hasSideEffects = 0 in { 4427let mayStore = 0, mayLoad = 1 in 4428class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4429 string asm> 4430 : BaseLoadStorePreIdx<sz, V, opc, 4431 (outs GPR64sp:$wback, regtype:$Rt), 4432 (ins GPR64sp:$Rn, simm9:$offset), asm, 4433 "$Rn = $wback,@earlyclobber $wback", []>, 4434 Sched<[WriteAdr, WriteLD]>; 4435 4436let mayStore = 1, mayLoad = 0 in 4437class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4438 string asm, SDPatternOperator storeop, ValueType Ty> 4439 : BaseLoadStorePreIdx<sz, V, opc, 4440 (outs GPR64sp:$wback), 4441 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4442 asm, "$Rn = $wback,@earlyclobber $wback", 4443 [(set GPR64sp:$wback, 4444 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4445 Sched<[WriteAdr, WriteST]>; 4446} // hasSideEffects = 0 4447 4448//--- 4449// Load/store post-indexed 4450//--- 4451 4452class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 4453 string asm, string cstr, list<dag> pat> 4454 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 4455 bits<5> Rt; 4456 bits<5> Rn; 4457 bits<9> offset; 4458 let Inst{31-30} = sz; 4459 let Inst{29-27} = 0b111; 4460 let Inst{26} = V; 4461 let Inst{25-24} = 0b00; 4462 let Inst{23-22} = opc; 4463 let Inst{21} = 0b0; 4464 let Inst{20-12} = offset; 4465 let Inst{11-10} = 0b01; 4466 let Inst{9-5} = Rn; 4467 let Inst{4-0} = Rt; 4468 4469 let DecoderMethod = "DecodeSignedLdStInstruction"; 4470} 4471 4472let hasSideEffects = 0 in { 4473let mayStore = 0, mayLoad = 1 in 4474class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4475 string asm> 4476 : BaseLoadStorePostIdx<sz, V, opc, 4477 (outs GPR64sp:$wback, regtype:$Rt), 4478 (ins GPR64sp:$Rn, simm9:$offset), 4479 asm, "$Rn = $wback,@earlyclobber $wback", []>, 4480 Sched<[WriteAdr, WriteLD]>; 4481 4482let mayStore = 1, mayLoad = 0 in 4483class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 4484 string asm, SDPatternOperator storeop, ValueType Ty> 4485 : BaseLoadStorePostIdx<sz, V, opc, 4486 (outs GPR64sp:$wback), 4487 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 4488 asm, "$Rn = $wback,@earlyclobber $wback", 4489 [(set GPR64sp:$wback, 4490 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 4491 Sched<[WriteAdr, WriteST]>; 4492} // hasSideEffects = 0 4493 4494 4495//--- 4496// Load/store pair 4497//--- 4498 4499// (indexed, offset) 4500 4501class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 4502 string asm> 4503 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4504 bits<5> Rt; 4505 bits<5> Rt2; 4506 bits<5> Rn; 4507 bits<7> offset; 4508 let Inst{31-30} = opc; 4509 let Inst{29-27} = 0b101; 4510 let Inst{26} = V; 4511 let Inst{25-23} = 0b010; 4512 let Inst{22} = L; 4513 let Inst{21-15} = offset; 4514 let Inst{14-10} = Rt2; 4515 let Inst{9-5} = Rn; 4516 let Inst{4-0} = Rt; 4517 4518 let DecoderMethod = "DecodePairLdStInstruction"; 4519} 4520 4521multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4522 Operand indextype, string asm> { 4523 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4524 def i : BaseLoadStorePairOffset<opc, V, 1, 4525 (outs regtype:$Rt, regtype:$Rt2), 4526 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4527 Sched<[WriteLD, WriteLDHi]>; 4528 4529 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4530 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4531 GPR64sp:$Rn, 0)>; 4532} 4533 4534 4535multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 4536 Operand indextype, string asm> { 4537 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 4538 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 4539 (ins regtype:$Rt, regtype:$Rt2, 4540 GPR64sp:$Rn, indextype:$offset), 4541 asm>, 4542 Sched<[WriteSTP]>; 4543 4544 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4545 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4546 GPR64sp:$Rn, 0)>; 4547} 4548 4549// (pre-indexed) 4550class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4551 string asm> 4552 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 4553 bits<5> Rt; 4554 bits<5> Rt2; 4555 bits<5> Rn; 4556 bits<7> offset; 4557 let Inst{31-30} = opc; 4558 let Inst{29-27} = 0b101; 4559 let Inst{26} = V; 4560 let Inst{25-23} = 0b011; 4561 let Inst{22} = L; 4562 let Inst{21-15} = offset; 4563 let Inst{14-10} = Rt2; 4564 let Inst{9-5} = Rn; 4565 let Inst{4-0} = Rt; 4566 4567 let DecoderMethod = "DecodePairLdStInstruction"; 4568} 4569 4570let hasSideEffects = 0 in { 4571let mayStore = 0, mayLoad = 1 in 4572class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4573 Operand indextype, string asm> 4574 : BaseLoadStorePairPreIdx<opc, V, 1, 4575 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4576 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4577 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4578 4579let mayStore = 1, mayLoad = 0 in 4580class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 4581 Operand indextype, string asm> 4582 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 4583 (ins regtype:$Rt, regtype:$Rt2, 4584 GPR64sp:$Rn, indextype:$offset), 4585 asm>, 4586 Sched<[WriteAdr, WriteSTP]>; 4587} // hasSideEffects = 0 4588 4589// (post-indexed) 4590 4591class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 4592 string asm> 4593 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 4594 bits<5> Rt; 4595 bits<5> Rt2; 4596 bits<5> Rn; 4597 bits<7> offset; 4598 let Inst{31-30} = opc; 4599 let Inst{29-27} = 0b101; 4600 let Inst{26} = V; 4601 let Inst{25-23} = 0b001; 4602 let Inst{22} = L; 4603 let Inst{21-15} = offset; 4604 let Inst{14-10} = Rt2; 4605 let Inst{9-5} = Rn; 4606 let Inst{4-0} = Rt; 4607 4608 let DecoderMethod = "DecodePairLdStInstruction"; 4609} 4610 4611let hasSideEffects = 0 in { 4612let mayStore = 0, mayLoad = 1 in 4613class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4614 Operand idxtype, string asm> 4615 : BaseLoadStorePairPostIdx<opc, V, 1, 4616 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 4617 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 4618 Sched<[WriteAdr, WriteLD, WriteLDHi]>; 4619 4620let mayStore = 1, mayLoad = 0 in 4621class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 4622 Operand idxtype, string asm> 4623 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 4624 (ins regtype:$Rt, regtype:$Rt2, 4625 GPR64sp:$Rn, idxtype:$offset), 4626 asm>, 4627 Sched<[WriteAdr, WriteSTP]>; 4628} // hasSideEffects = 0 4629 4630// (no-allocate) 4631 4632class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 4633 string asm> 4634 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 4635 bits<5> Rt; 4636 bits<5> Rt2; 4637 bits<5> Rn; 4638 bits<7> offset; 4639 let Inst{31-30} = opc; 4640 let Inst{29-27} = 0b101; 4641 let Inst{26} = V; 4642 let Inst{25-23} = 0b000; 4643 let Inst{22} = L; 4644 let Inst{21-15} = offset; 4645 let Inst{14-10} = Rt2; 4646 let Inst{9-5} = Rn; 4647 let Inst{4-0} = Rt; 4648 4649 let DecoderMethod = "DecodePairLdStInstruction"; 4650} 4651 4652multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4653 Operand indextype, string asm> { 4654 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 4655 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 4656 (outs regtype:$Rt, regtype:$Rt2), 4657 (ins GPR64sp:$Rn, indextype:$offset), asm>, 4658 Sched<[WriteLD, WriteLDHi]>; 4659 4660 4661 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4662 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4663 GPR64sp:$Rn, 0)>; 4664} 4665 4666multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype, 4667 Operand indextype, string asm> { 4668 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 4669 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 4670 (ins regtype:$Rt, regtype:$Rt2, 4671 GPR64sp:$Rn, indextype:$offset), 4672 asm>, 4673 Sched<[WriteSTP]>; 4674 4675 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 4676 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 4677 GPR64sp:$Rn, 0)>; 4678} 4679 4680//--- 4681// Load/store exclusive 4682//--- 4683 4684// True exclusive operations write to and/or read from the system's exclusive 4685// monitors, which as far as a compiler is concerned can be modelled as a 4686// random shared memory address. Hence LoadExclusive mayStore. 4687// 4688// Since these instructions have the undefined register bits set to 1 in 4689// their canonical form, we need a post encoder method to set those bits 4690// to 1 when encoding these instructions. We do this using the 4691// fixLoadStoreExclusive function. This function has template parameters: 4692// 4693// fixLoadStoreExclusive<int hasRs, int hasRt2> 4694// 4695// hasRs indicates that the instruction uses the Rs field, so we won't set 4696// it to 1 (and the same for Rt2). We don't need template parameters for 4697// the other register fields since Rt and Rn are always used. 4698// 4699let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 4700class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4701 dag oops, dag iops, string asm, string operands> 4702 : I<oops, iops, asm, operands, "", []> { 4703 let Inst{31-30} = sz; 4704 let Inst{29-24} = 0b001000; 4705 let Inst{23} = o2; 4706 let Inst{22} = L; 4707 let Inst{21} = o1; 4708 let Inst{15} = o0; 4709 4710 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 4711} 4712 4713// Neither Rs nor Rt2 operands. 4714class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4715 dag oops, dag iops, string asm, string operands> 4716 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 4717 bits<5> Rt; 4718 bits<5> Rn; 4719 let Inst{20-16} = 0b11111; 4720 let Unpredictable{20-16} = 0b11111; 4721 let Inst{14-10} = 0b11111; 4722 let Unpredictable{14-10} = 0b11111; 4723 let Inst{9-5} = Rn; 4724 let Inst{4-0} = Rt; 4725 4726 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4727} 4728 4729// Simple load acquires don't set the exclusive monitor 4730let mayLoad = 1, mayStore = 0 in 4731class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4732 RegisterClass regtype, string asm> 4733 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4734 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4735 Sched<[WriteLD]>; 4736 4737class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4738 RegisterClass regtype, string asm> 4739 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4740 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4741 Sched<[WriteLD]>; 4742 4743class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4744 RegisterClass regtype, string asm> 4745 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4746 (outs regtype:$Rt, regtype:$Rt2), 4747 (ins GPR64sp0:$Rn), asm, 4748 "\t$Rt, $Rt2, [$Rn]">, 4749 Sched<[WriteLD, WriteLDHi]> { 4750 bits<5> Rt; 4751 bits<5> Rt2; 4752 bits<5> Rn; 4753 let Inst{14-10} = Rt2; 4754 let Inst{9-5} = Rn; 4755 let Inst{4-0} = Rt; 4756 4757 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4758} 4759 4760// Simple store release operations do not check the exclusive monitor. 4761let mayLoad = 0, mayStore = 1 in 4762class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4763 RegisterClass regtype, string asm> 4764 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4765 (ins regtype:$Rt, GPR64sp:$Rn), 4766 asm, "\t$Rt, [$Rn]">, 4767 Sched<[WriteST]>; 4768 4769let mayLoad = 1, mayStore = 1 in 4770class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4771 RegisterClass regtype, string asm> 4772 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4773 (ins regtype:$Rt, GPR64sp0:$Rn), 4774 asm, "\t$Ws, $Rt, [$Rn]">, 4775 Sched<[WriteSTX]> { 4776 bits<5> Ws; 4777 bits<5> Rt; 4778 bits<5> Rn; 4779 let Inst{20-16} = Ws; 4780 let Inst{9-5} = Rn; 4781 let Inst{4-0} = Rt; 4782 4783 let Constraints = "@earlyclobber $Ws"; 4784 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4785} 4786 4787class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4788 RegisterClass regtype, string asm> 4789 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4790 (outs GPR32:$Ws), 4791 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4792 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4793 Sched<[WriteSTX]> { 4794 bits<5> Ws; 4795 bits<5> Rt; 4796 bits<5> Rt2; 4797 bits<5> Rn; 4798 let Inst{20-16} = Ws; 4799 let Inst{14-10} = Rt2; 4800 let Inst{9-5} = Rn; 4801 let Inst{4-0} = Rt; 4802 4803 let Constraints = "@earlyclobber $Ws"; 4804} 4805 4806// Armv8.5-A Memory Tagging Extension 4807class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4808 string asm_opnds, string cstr, dag oops, dag iops> 4809 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4810 Sched<[]> { 4811 bits<5> Rn; 4812 4813 let Inst{31-24} = 0b11011001; 4814 let Inst{23-22} = opc1; 4815 let Inst{21} = 1; 4816 // Inst{20-12} defined by subclass 4817 let Inst{11-10} = opc2; 4818 let Inst{9-5} = Rn; 4819 // Inst{4-0} defined by subclass 4820} 4821 4822class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4823 dag oops, dag iops> 4824 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4825 "", oops, iops> { 4826 bits<5> Rt; 4827 4828 let Inst{20-12} = 0b000000000; 4829 let Inst{4-0} = Rt; 4830 4831 let mayLoad = Load; 4832} 4833 4834class MemTagLoad<string asm_insn, string asm_opnds> 4835 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4836 (outs GPR64:$wback), 4837 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4838 bits<5> Rt; 4839 bits<9> offset; 4840 4841 let Inst{20-12} = offset; 4842 let Inst{4-0} = Rt; 4843 4844 let mayLoad = 1; 4845} 4846 4847class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4848 string asm_opnds, string cstr, dag oops, dag iops> 4849 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4850 bits<5> Rt; 4851 bits<9> offset; 4852 4853 let Inst{20-12} = offset; 4854 let Inst{4-0} = Rt; 4855 4856 let mayStore = 1; 4857} 4858 4859multiclass MemTagStore<bits<2> opc1, string insn> { 4860 def i : 4861 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4862 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4863 def PreIndex : 4864 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4865 "$Rn = $wback", 4866 (outs GPR64sp:$wback), 4867 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4868 def PostIndex : 4869 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4870 "$Rn = $wback", 4871 (outs GPR64sp:$wback), 4872 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4873 4874 def : InstAlias<insn # "\t$Rt, [$Rn]", 4875 (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4876} 4877 4878//--- 4879// Exception generation 4880//--- 4881 4882let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4883class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, 4884 list<dag> pattern = []> 4885 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, 4886 Sched<[WriteSys]> { 4887 bits<16> imm; 4888 let Inst{31-24} = 0b11010100; 4889 let Inst{23-21} = op1; 4890 let Inst{20-5} = imm; 4891 let Inst{4-2} = 0b000; 4892 let Inst{1-0} = ll; 4893} 4894 4895//--- 4896// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4897//-- 4898let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4899class UDFType<bits<16> opc, string asm> 4900 : I<(outs), (ins uimm16:$imm), 4901 asm, "\t$imm", "", []>, 4902 Sched<[]> { 4903 bits<16> imm; 4904 let Inst{31-16} = opc; 4905 let Inst{15-0} = imm; 4906} 4907} 4908let Predicates = [HasFPARMv8] in { 4909 4910//--- 4911// Floating point to integer conversion 4912//--- 4913 4914let mayRaiseFPException = 1, Uses = [FPCR] in 4915class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4916 RegisterClass srcType, RegisterClass dstType, 4917 string asm, list<dag> pattern> 4918 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4919 asm, "\t$Rd, $Rn", "", pattern>, 4920 Sched<[WriteFCvt]> { 4921 bits<5> Rd; 4922 bits<5> Rn; 4923 let Inst{30-29} = 0b00; 4924 let Inst{28-24} = 0b11110; 4925 let Inst{23-22} = type; 4926 let Inst{21} = 1; 4927 let Inst{20-19} = rmode; 4928 let Inst{18-16} = opcode; 4929 let Inst{15-10} = 0; 4930 let Inst{9-5} = Rn; 4931 let Inst{4-0} = Rd; 4932} 4933 4934let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 4935class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4936 RegisterClass srcType, RegisterClass dstType, 4937 Operand immType, string asm, list<dag> pattern> 4938 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4939 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4940 Sched<[WriteFCvt]> { 4941 bits<5> Rd; 4942 bits<5> Rn; 4943 bits<6> scale; 4944 let Inst{30-29} = 0b00; 4945 let Inst{28-24} = 0b11110; 4946 let Inst{23-22} = type; 4947 let Inst{21} = 0; 4948 let Inst{20-19} = rmode; 4949 let Inst{18-16} = opcode; 4950 let Inst{15-10} = scale; 4951 let Inst{9-5} = Rn; 4952 let Inst{4-0} = Rd; 4953} 4954 4955multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4956 SDPatternOperator OpN> { 4957 // Unscaled half-precision to 32-bit 4958 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4959 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4960 let Inst{31} = 0; // 32-bit GPR flag 4961 let Predicates = [HasFullFP16]; 4962 } 4963 4964 // Unscaled half-precision to 64-bit 4965 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4966 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> { 4967 let Inst{31} = 1; // 64-bit GPR flag 4968 let Predicates = [HasFullFP16]; 4969 } 4970 4971 // Unscaled single-precision to 32-bit 4972 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4973 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4974 let Inst{31} = 0; // 32-bit GPR flag 4975 } 4976 4977 // Unscaled single-precision to 64-bit 4978 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4979 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4980 let Inst{31} = 1; // 64-bit GPR flag 4981 } 4982 4983 // Unscaled double-precision to 32-bit 4984 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4985 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4986 let Inst{31} = 0; // 32-bit GPR flag 4987 } 4988 4989 // Unscaled double-precision to 64-bit 4990 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4991 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4992 let Inst{31} = 1; // 64-bit GPR flag 4993 } 4994} 4995 4996multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4997 SDPatternOperator OpN> { 4998 // Scaled half-precision to 32-bit 4999 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 5000 fixedpoint_f16_i32, asm, 5001 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn), 5002 fixedpoint_f16_i32:$scale)))]> { 5003 let Inst{31} = 0; // 32-bit GPR flag 5004 let scale{5} = 1; 5005 let Predicates = [HasFullFP16]; 5006 } 5007 5008 // Scaled half-precision to 64-bit 5009 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 5010 fixedpoint_f16_i64, asm, 5011 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn), 5012 fixedpoint_f16_i64:$scale)))]> { 5013 let Inst{31} = 1; // 64-bit GPR flag 5014 let Predicates = [HasFullFP16]; 5015 } 5016 5017 // Scaled single-precision to 32-bit 5018 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 5019 fixedpoint_f32_i32, asm, 5020 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 5021 fixedpoint_f32_i32:$scale)))]> { 5022 let Inst{31} = 0; // 32-bit GPR flag 5023 let scale{5} = 1; 5024 } 5025 5026 // Scaled single-precision to 64-bit 5027 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 5028 fixedpoint_f32_i64, asm, 5029 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 5030 fixedpoint_f32_i64:$scale)))]> { 5031 let Inst{31} = 1; // 64-bit GPR flag 5032 } 5033 5034 // Scaled double-precision to 32-bit 5035 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 5036 fixedpoint_f64_i32, asm, 5037 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 5038 fixedpoint_f64_i32:$scale)))]> { 5039 let Inst{31} = 0; // 32-bit GPR flag 5040 let scale{5} = 1; 5041 } 5042 5043 // Scaled double-precision to 64-bit 5044 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 5045 fixedpoint_f64_i64, asm, 5046 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 5047 fixedpoint_f64_i64:$scale)))]> { 5048 let Inst{31} = 1; // 64-bit GPR flag 5049 } 5050} 5051 5052//--- 5053// Integer to floating point conversion 5054//--- 5055 5056let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5057class BaseIntegerToFP<bit isUnsigned, 5058 RegisterClass srcType, RegisterClass dstType, 5059 Operand immType, string asm, list<dag> pattern> 5060 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 5061 asm, "\t$Rd, $Rn, $scale", "", pattern>, 5062 Sched<[WriteFCvt]> { 5063 bits<5> Rd; 5064 bits<5> Rn; 5065 bits<6> scale; 5066 let Inst{30-24} = 0b0011110; 5067 let Inst{21-17} = 0b00001; 5068 let Inst{16} = isUnsigned; 5069 let Inst{15-10} = scale; 5070 let Inst{9-5} = Rn; 5071 let Inst{4-0} = Rd; 5072} 5073 5074let mayRaiseFPException = 1, Uses = [FPCR] in 5075class BaseIntegerToFPUnscaled<bit isUnsigned, 5076 RegisterClass srcType, RegisterClass dstType, 5077 ValueType dvt, string asm, SDPatternOperator node> 5078 : I<(outs dstType:$Rd), (ins srcType:$Rn), 5079 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 5080 Sched<[WriteFCvt]> { 5081 bits<5> Rd; 5082 bits<5> Rn; 5083 bits<6> scale; 5084 let Inst{30-24} = 0b0011110; 5085 let Inst{21-17} = 0b10001; 5086 let Inst{16} = isUnsigned; 5087 let Inst{15-10} = 0b000000; 5088 let Inst{9-5} = Rn; 5089 let Inst{4-0} = Rd; 5090} 5091 5092multiclass IntegerToFP<bit isUnsigned, string asm, SDPatternOperator node> { 5093 // Unscaled 5094 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 5095 let Inst{31} = 0; // 32-bit GPR flag 5096 let Inst{23-22} = 0b11; // 16-bit FPR flag 5097 let Predicates = [HasFullFP16]; 5098 } 5099 5100 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 5101 let Inst{31} = 0; // 32-bit GPR flag 5102 let Inst{23-22} = 0b00; // 32-bit FPR flag 5103 } 5104 5105 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 5106 let Inst{31} = 0; // 32-bit GPR flag 5107 let Inst{23-22} = 0b01; // 64-bit FPR flag 5108 } 5109 5110 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 5111 let Inst{31} = 1; // 64-bit GPR flag 5112 let Inst{23-22} = 0b11; // 16-bit FPR flag 5113 let Predicates = [HasFullFP16]; 5114 } 5115 5116 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 5117 let Inst{31} = 1; // 64-bit GPR flag 5118 let Inst{23-22} = 0b00; // 32-bit FPR flag 5119 } 5120 5121 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 5122 let Inst{31} = 1; // 64-bit GPR flag 5123 let Inst{23-22} = 0b01; // 64-bit FPR flag 5124 } 5125 5126 // Scaled 5127 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_recip_f16_i32, asm, 5128 [(set (f16 FPR16:$Rd), 5129 (fmul (node GPR32:$Rn), 5130 fixedpoint_recip_f16_i32:$scale))]> { 5131 let Inst{31} = 0; // 32-bit GPR flag 5132 let Inst{23-22} = 0b11; // 16-bit FPR flag 5133 let scale{5} = 1; 5134 let Predicates = [HasFullFP16]; 5135 } 5136 5137 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_recip_f32_i32, asm, 5138 [(set FPR32:$Rd, 5139 (fmul (node GPR32:$Rn), 5140 fixedpoint_recip_f32_i32:$scale))]> { 5141 let Inst{31} = 0; // 32-bit GPR flag 5142 let Inst{23-22} = 0b00; // 32-bit FPR flag 5143 let scale{5} = 1; 5144 } 5145 5146 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_recip_f64_i32, asm, 5147 [(set FPR64:$Rd, 5148 (fmul (node GPR32:$Rn), 5149 fixedpoint_recip_f64_i32:$scale))]> { 5150 let Inst{31} = 0; // 32-bit GPR flag 5151 let Inst{23-22} = 0b01; // 64-bit FPR flag 5152 let scale{5} = 1; 5153 } 5154 5155 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_recip_f16_i64, asm, 5156 [(set (f16 FPR16:$Rd), 5157 (fmul (node GPR64:$Rn), 5158 fixedpoint_recip_f16_i64:$scale))]> { 5159 let Inst{31} = 1; // 64-bit GPR flag 5160 let Inst{23-22} = 0b11; // 16-bit FPR flag 5161 let Predicates = [HasFullFP16]; 5162 } 5163 5164 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_recip_f32_i64, asm, 5165 [(set FPR32:$Rd, 5166 (fmul (node GPR64:$Rn), 5167 fixedpoint_recip_f32_i64:$scale))]> { 5168 let Inst{31} = 1; // 64-bit GPR flag 5169 let Inst{23-22} = 0b00; // 32-bit FPR flag 5170 } 5171 5172 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_recip_f64_i64, asm, 5173 [(set FPR64:$Rd, 5174 (fmul (node GPR64:$Rn), 5175 fixedpoint_recip_f64_i64:$scale))]> { 5176 let Inst{31} = 1; // 64-bit GPR flag 5177 let Inst{23-22} = 0b01; // 64-bit FPR flag 5178 } 5179} 5180 5181//--- 5182// Unscaled integer <-> floating point conversion (i.e. FMOV) 5183//--- 5184 5185let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5186class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 5187 RegisterClass srcType, RegisterClass dstType, 5188 string asm> 5189 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 5190 // We use COPY_TO_REGCLASS for these bitconvert operations. 5191 // copyPhysReg() expands the resultant COPY instructions after 5192 // regalloc is done. This gives greater freedom for the allocator 5193 // and related passes (coalescing, copy propagation, et. al.) to 5194 // be more effective. 5195 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 5196 Sched<[WriteFCopy]> { 5197 bits<5> Rd; 5198 bits<5> Rn; 5199 let Inst{30-24} = 0b0011110; 5200 let Inst{21} = 1; 5201 let Inst{20-19} = rmode; 5202 let Inst{18-16} = opcode; 5203 let Inst{15-10} = 0b000000; 5204 let Inst{9-5} = Rn; 5205 let Inst{4-0} = Rd; 5206} 5207 5208let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5209class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 5210 RegisterClass srcType, RegisterOperand dstType, string asm, 5211 string kind> 5212 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5213 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 5214 Sched<[WriteFCopy]> { 5215 bits<5> Rd; 5216 bits<5> Rn; 5217 let Inst{30-23} = 0b00111101; 5218 let Inst{21} = 1; 5219 let Inst{20-19} = rmode; 5220 let Inst{18-16} = opcode; 5221 let Inst{15-10} = 0b000000; 5222 let Inst{9-5} = Rn; 5223 let Inst{4-0} = Rd; 5224 5225 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5226} 5227 5228let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5229class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 5230 RegisterOperand srcType, RegisterClass dstType, string asm, 5231 string kind> 5232 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 5233 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 5234 Sched<[WriteFCopy]> { 5235 bits<5> Rd; 5236 bits<5> Rn; 5237 let Inst{30-23} = 0b00111101; 5238 let Inst{21} = 1; 5239 let Inst{20-19} = rmode; 5240 let Inst{18-16} = opcode; 5241 let Inst{15-10} = 0b000000; 5242 let Inst{9-5} = Rn; 5243 let Inst{4-0} = Rd; 5244 5245 let DecoderMethod = "DecodeFMOVLaneInstruction"; 5246} 5247 5248 5249multiclass UnscaledConversion<string asm> { 5250 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 5251 let Inst{31} = 0; // 32-bit GPR flag 5252 let Inst{23-22} = 0b11; // 16-bit FPR flag 5253 let Predicates = [HasFullFP16]; 5254 } 5255 5256 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 5257 let Inst{31} = 1; // 64-bit GPR flag 5258 let Inst{23-22} = 0b11; // 16-bit FPR flag 5259 let Predicates = [HasFullFP16]; 5260 } 5261 5262 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 5263 let Inst{31} = 0; // 32-bit GPR flag 5264 let Inst{23-22} = 0b00; // 32-bit FPR flag 5265 } 5266 5267 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 5268 let Inst{31} = 1; // 64-bit GPR flag 5269 let Inst{23-22} = 0b01; // 64-bit FPR flag 5270 } 5271 5272 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 5273 let Inst{31} = 0; // 32-bit GPR flag 5274 let Inst{23-22} = 0b11; // 16-bit FPR flag 5275 let Predicates = [HasFullFP16]; 5276 } 5277 5278 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 5279 let Inst{31} = 1; // 64-bit GPR flag 5280 let Inst{23-22} = 0b11; // 16-bit FPR flag 5281 let Predicates = [HasFullFP16]; 5282 } 5283 5284 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 5285 let Inst{31} = 0; // 32-bit GPR flag 5286 let Inst{23-22} = 0b00; // 32-bit FPR flag 5287 } 5288 5289 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 5290 let Inst{31} = 1; // 64-bit GPR flag 5291 let Inst{23-22} = 0b01; // 64-bit FPR flag 5292 } 5293 5294 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 5295 asm, ".d"> { 5296 let Inst{31} = 1; 5297 let Inst{22} = 0; 5298 } 5299 5300 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 5301 asm, ".d"> { 5302 let Inst{31} = 1; 5303 let Inst{22} = 0; 5304 } 5305} 5306 5307//--- 5308// Floating point conversion 5309//--- 5310 5311let mayRaiseFPException = 1, Uses = [FPCR] in 5312class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 5313 RegisterClass srcType, string asm, list<dag> pattern> 5314 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 5315 Sched<[WriteFCvt]> { 5316 bits<5> Rd; 5317 bits<5> Rn; 5318 let Inst{31-24} = 0b00011110; 5319 let Inst{23-22} = type; 5320 let Inst{21-17} = 0b10001; 5321 let Inst{16-15} = opcode; 5322 let Inst{14-10} = 0b10000; 5323 let Inst{9-5} = Rn; 5324 let Inst{4-0} = Rd; 5325} 5326 5327multiclass FPConversion<string asm> { 5328 // Double-precision to Half-precision 5329 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 5330 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>; 5331 5332 // Double-precision to Single-precision 5333 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 5334 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>; 5335 5336 // Half-precision to Double-precision 5337 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 5338 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5339 5340 // Half-precision to Single-precision 5341 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 5342 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>; 5343 5344 // Single-precision to Double-precision 5345 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 5346 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>; 5347 5348 // Single-precision to Half-precision 5349 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 5350 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>; 5351} 5352 5353//--- 5354// Single operand floating point data processing 5355//--- 5356 5357let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5358class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 5359 ValueType vt, string asm, SDPatternOperator node> 5360 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 5361 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 5362 Sched<[WriteF]> { 5363 bits<5> Rd; 5364 bits<5> Rn; 5365 let Inst{31-24} = 0b00011110; 5366 let Inst{21} = 0b1; 5367 let Inst{20-15} = opcode; 5368 let Inst{14-10} = 0b10000; 5369 let Inst{9-5} = Rn; 5370 let Inst{4-0} = Rd; 5371} 5372 5373multiclass SingleOperandFPData<bits<4> opcode, string asm, 5374 SDPatternOperator node = null_frag, 5375 int fpexceptions = 1> { 5376 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 5377 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 5378 let Inst{23-22} = 0b11; // 16-bit size flag 5379 let Predicates = [HasFullFP16]; 5380 } 5381 5382 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 5383 let Inst{23-22} = 0b00; // 32-bit size flag 5384 } 5385 5386 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 5387 let Inst{23-22} = 0b01; // 64-bit size flag 5388 } 5389 } 5390} 5391 5392multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm, 5393 SDPatternOperator node = null_frag> 5394 : SingleOperandFPData<opcode, asm, node, 0>; 5395 5396let mayRaiseFPException = 1, Uses = [FPCR] in 5397multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 5398 SDPatternOperator node = null_frag>{ 5399 5400 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 5401 let Inst{23-22} = 0b00; // 32-bit registers 5402 } 5403 5404 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 5405 let Inst{23-22} = 0b01; // 64-bit registers 5406 } 5407} 5408 5409// FRInt[32|64][Z|N] instructions 5410multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 5411 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 5412 5413//--- 5414// Two operand floating point data processing 5415//--- 5416 5417let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5418class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 5419 string asm, list<dag> pat> 5420 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 5421 asm, "\t$Rd, $Rn, $Rm", "", pat>, 5422 Sched<[WriteF]> { 5423 bits<5> Rd; 5424 bits<5> Rn; 5425 bits<5> Rm; 5426 let Inst{31-24} = 0b00011110; 5427 let Inst{21} = 1; 5428 let Inst{20-16} = Rm; 5429 let Inst{15-12} = opcode; 5430 let Inst{11-10} = 0b10; 5431 let Inst{9-5} = Rn; 5432 let Inst{4-0} = Rd; 5433} 5434 5435multiclass TwoOperandFPData<bits<4> opcode, string asm, 5436 SDPatternOperator node = null_frag> { 5437 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5438 [(set (f16 FPR16:$Rd), 5439 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 5440 let Inst{23-22} = 0b11; // 16-bit size flag 5441 let Predicates = [HasFullFP16]; 5442 } 5443 5444 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5445 [(set (f32 FPR32:$Rd), 5446 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 5447 let Inst{23-22} = 0b00; // 32-bit size flag 5448 } 5449 5450 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5451 [(set (f64 FPR64:$Rd), 5452 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 5453 let Inst{23-22} = 0b01; // 64-bit size flag 5454 } 5455} 5456 5457multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, 5458 SDPatternOperator node> { 5459 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 5460 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> { 5461 let Inst{23-22} = 0b11; // 16-bit size flag 5462 let Predicates = [HasFullFP16]; 5463 } 5464 5465 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 5466 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 5467 let Inst{23-22} = 0b00; // 32-bit size flag 5468 } 5469 5470 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 5471 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 5472 let Inst{23-22} = 0b01; // 64-bit size flag 5473 } 5474} 5475 5476 5477//--- 5478// Three operand floating point data processing 5479//--- 5480 5481let mayRaiseFPException = 1, Uses = [FPCR] in 5482class BaseThreeOperandFPData<bit isNegated, bit isSub, 5483 RegisterClass regtype, string asm, list<dag> pat> 5484 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 5485 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 5486 Sched<[WriteFMul]> { 5487 bits<5> Rd; 5488 bits<5> Rn; 5489 bits<5> Rm; 5490 bits<5> Ra; 5491 let Inst{31-24} = 0b00011111; 5492 let Inst{21} = isNegated; 5493 let Inst{20-16} = Rm; 5494 let Inst{15} = isSub; 5495 let Inst{14-10} = Ra; 5496 let Inst{9-5} = Rn; 5497 let Inst{4-0} = Rd; 5498} 5499 5500multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 5501 SDPatternOperator node> { 5502 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 5503 [(set (f16 FPR16:$Rd), 5504 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 5505 let Inst{23-22} = 0b11; // 16-bit size flag 5506 let Predicates = [HasFullFP16]; 5507 } 5508 5509 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 5510 [(set FPR32:$Rd, 5511 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 5512 let Inst{23-22} = 0b00; // 32-bit size flag 5513 } 5514 5515 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 5516 [(set FPR64:$Rd, 5517 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 5518 let Inst{23-22} = 0b01; // 64-bit size flag 5519 } 5520 5521 let Predicates = [HasFullFP16] in { 5522 def : Pat<(f16 (node (f16 FPR16:$Rn), 5523 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))), 5524 (f16 FPR16:$Ra))), 5525 (!cast<Instruction>(NAME # Hrrr) 5526 FPR16:$Rn, (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>; 5527 5528 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))), 5529 (f16 FPR16:$Rm), 5530 (f16 FPR16:$Ra))), 5531 (!cast<Instruction>(NAME # Hrrr) 5532 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>; 5533 } 5534 5535 def : Pat<(f32 (node (f32 FPR32:$Rn), 5536 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))), 5537 (f32 FPR32:$Ra))), 5538 (!cast<Instruction>(NAME # Srrr) 5539 FPR32:$Rn, (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>; 5540 5541 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))), 5542 (f32 FPR32:$Rm), 5543 (f32 FPR32:$Ra))), 5544 (!cast<Instruction>(NAME # Srrr) 5545 (EXTRACT_SUBREG V128:$Rn, ssub), FPR32:$Rm, FPR32:$Ra)>; 5546 5547 def : Pat<(f64 (node (f64 FPR64:$Rn), 5548 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))), 5549 (f64 FPR64:$Ra))), 5550 (!cast<Instruction>(NAME # Drrr) 5551 FPR64:$Rn, (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>; 5552 5553 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))), 5554 (f64 FPR64:$Rm), 5555 (f64 FPR64:$Ra))), 5556 (!cast<Instruction>(NAME # Drrr) 5557 (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>; 5558} 5559 5560//--- 5561// Floating point data comparisons 5562//--- 5563 5564let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5565class BaseOneOperandFPComparison<bit signalAllNans, 5566 RegisterClass regtype, string asm, 5567 list<dag> pat> 5568 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 5569 Sched<[WriteFCmp]> { 5570 bits<5> Rn; 5571 let Inst{31-24} = 0b00011110; 5572 let Inst{21} = 1; 5573 5574 let Inst{15-10} = 0b001000; 5575 let Inst{9-5} = Rn; 5576 let Inst{4} = signalAllNans; 5577 let Inst{3-0} = 0b1000; 5578 5579 // Rm should be 0b00000 canonically, but we need to accept any value. 5580 let PostEncoderMethod = "fixOneOperandFPComparison"; 5581} 5582 5583let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5584class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 5585 string asm, list<dag> pat> 5586 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 5587 Sched<[WriteFCmp]> { 5588 bits<5> Rm; 5589 bits<5> Rn; 5590 let Inst{31-24} = 0b00011110; 5591 let Inst{21} = 1; 5592 let Inst{20-16} = Rm; 5593 let Inst{15-10} = 0b001000; 5594 let Inst{9-5} = Rn; 5595 let Inst{4} = signalAllNans; 5596 let Inst{3-0} = 0b0000; 5597} 5598 5599multiclass FPComparison<bit signalAllNans, string asm, 5600 SDPatternOperator OpNode = null_frag> { 5601 let Defs = [NZCV] in { 5602 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 5603 [(OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)), (implicit NZCV)]> { 5604 let Inst{23-22} = 0b11; 5605 let Predicates = [HasFullFP16]; 5606 } 5607 5608 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 5609 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 5610 let Inst{23-22} = 0b11; 5611 let Predicates = [HasFullFP16]; 5612 } 5613 5614 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 5615 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 5616 let Inst{23-22} = 0b00; 5617 } 5618 5619 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 5620 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 5621 let Inst{23-22} = 0b00; 5622 } 5623 5624 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 5625 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 5626 let Inst{23-22} = 0b01; 5627 } 5628 5629 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 5630 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 5631 let Inst{23-22} = 0b01; 5632 } 5633 } // Defs = [NZCV] 5634} 5635 5636//--- 5637// Floating point conditional comparisons 5638//--- 5639 5640let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 5641class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 5642 string mnemonic, list<dag> pat> 5643 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 5644 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 5645 Sched<[WriteFCmp]> { 5646 let Uses = [NZCV]; 5647 let Defs = [NZCV]; 5648 5649 bits<5> Rn; 5650 bits<5> Rm; 5651 bits<4> nzcv; 5652 bits<4> cond; 5653 5654 let Inst{31-24} = 0b00011110; 5655 let Inst{21} = 1; 5656 let Inst{20-16} = Rm; 5657 let Inst{15-12} = cond; 5658 let Inst{11-10} = 0b01; 5659 let Inst{9-5} = Rn; 5660 let Inst{4} = signalAllNans; 5661 let Inst{3-0} = nzcv; 5662} 5663 5664multiclass FPCondComparison<bit signalAllNans, string mnemonic, 5665 SDPatternOperator OpNode = null_frag> { 5666 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 5667 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 5668 (i32 imm:$cond), NZCV))]> { 5669 let Inst{23-22} = 0b11; 5670 let Predicates = [HasFullFP16]; 5671 } 5672 5673 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 5674 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 5675 (i32 imm:$cond), NZCV))]> { 5676 let Inst{23-22} = 0b00; 5677 } 5678 5679 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 5680 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 5681 (i32 imm:$cond), NZCV))]> { 5682 let Inst{23-22} = 0b01; 5683 } 5684} 5685 5686//--- 5687// Floating point conditional select 5688//--- 5689 5690class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 5691 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 5692 asm, "\t$Rd, $Rn, $Rm, $cond", "", 5693 [(set regtype:$Rd, 5694 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 5695 (i32 imm:$cond), NZCV))]>, 5696 Sched<[WriteF]> { 5697 bits<5> Rd; 5698 bits<5> Rn; 5699 bits<5> Rm; 5700 bits<4> cond; 5701 5702 let Inst{31-24} = 0b00011110; 5703 let Inst{21} = 1; 5704 let Inst{20-16} = Rm; 5705 let Inst{15-12} = cond; 5706 let Inst{11-10} = 0b11; 5707 let Inst{9-5} = Rn; 5708 let Inst{4-0} = Rd; 5709} 5710 5711multiclass FPCondSelect<string asm> { 5712 let Uses = [NZCV] in { 5713 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 5714 let Inst{23-22} = 0b11; 5715 let Predicates = [HasFullFP16]; 5716 } 5717 5718 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 5719 let Inst{23-22} = 0b00; 5720 } 5721 5722 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 5723 let Inst{23-22} = 0b01; 5724 } 5725 } // Uses = [NZCV] 5726} 5727 5728//--- 5729// Floating move immediate 5730//--- 5731 5732class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 5733 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 5734 [(set regtype:$Rd, fpimmtype:$imm)]>, 5735 Sched<[WriteFImm]> { 5736 bits<5> Rd; 5737 bits<8> imm; 5738 let Inst{31-24} = 0b00011110; 5739 let Inst{21} = 1; 5740 let Inst{20-13} = imm; 5741 let Inst{12-5} = 0b10000000; 5742 let Inst{4-0} = Rd; 5743} 5744 5745multiclass FPMoveImmediate<string asm> { 5746 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 5747 let Inst{23-22} = 0b11; 5748 let Predicates = [HasFullFP16]; 5749 } 5750 5751 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 5752 let Inst{23-22} = 0b00; 5753 } 5754 5755 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 5756 let Inst{23-22} = 0b01; 5757 } 5758} 5759} // end of 'let Predicates = [HasFPARMv8]' 5760 5761//---------------------------------------------------------------------------- 5762// AdvSIMD 5763//---------------------------------------------------------------------------- 5764 5765let Predicates = [HasNEON] in { 5766 5767//---------------------------------------------------------------------------- 5768// AdvSIMD three register vector instructions 5769//---------------------------------------------------------------------------- 5770 5771let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5772class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 5773 RegisterOperand regtype, string asm, string kind, 5774 list<dag> pattern> 5775 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5776 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5777 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5778 Sched<[!if(Q, WriteVq, WriteVd)]> { 5779 bits<5> Rd; 5780 bits<5> Rn; 5781 bits<5> Rm; 5782 let Inst{31} = 0; 5783 let Inst{30} = Q; 5784 let Inst{29} = U; 5785 let Inst{28-24} = 0b01110; 5786 let Inst{23-21} = size; 5787 let Inst{20-16} = Rm; 5788 let Inst{15-11} = opcode; 5789 let Inst{10} = 1; 5790 let Inst{9-5} = Rn; 5791 let Inst{4-0} = Rd; 5792} 5793 5794let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5795class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5796 RegisterOperand regtype, string asm, string kind, 5797 list<dag> pattern> 5798 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5799 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5800 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5801 Sched<[!if(Q, WriteVq, WriteVd)]> { 5802 bits<5> Rd; 5803 bits<5> Rn; 5804 bits<5> Rm; 5805 let Inst{31} = 0; 5806 let Inst{30} = Q; 5807 let Inst{29} = U; 5808 let Inst{28-24} = 0b01110; 5809 let Inst{23-21} = size; 5810 let Inst{20-16} = Rm; 5811 let Inst{15-11} = opcode; 5812 let Inst{10} = 1; 5813 let Inst{9-5} = Rn; 5814 let Inst{4-0} = Rd; 5815} 5816 5817let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5818class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern> 5819 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>, 5820 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>; 5821 5822multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> { 5823 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64, 5824 [(set (v8i8 V64:$dst), 5825 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5826 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128, 5827 [(set (v16i8 V128:$dst), 5828 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5829 (v16i8 V128:$Rm)))]>; 5830 5831 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5832 (v4i16 V64:$RHS))), 5833 (!cast<Instruction>(NAME#"v8i8") 5834 V64:$LHS, V64:$MHS, V64:$RHS)>; 5835 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5836 (v2i32 V64:$RHS))), 5837 (!cast<Instruction>(NAME#"v8i8") 5838 V64:$LHS, V64:$MHS, V64:$RHS)>; 5839 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5840 (v1i64 V64:$RHS))), 5841 (!cast<Instruction>(NAME#"v8i8") 5842 V64:$LHS, V64:$MHS, V64:$RHS)>; 5843 5844 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5845 (v8i16 V128:$RHS))), 5846 (!cast<Instruction>(NAME#"v16i8") 5847 V128:$LHS, V128:$MHS, V128:$RHS)>; 5848 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5849 (v4i32 V128:$RHS))), 5850 (!cast<Instruction>(NAME#"v16i8") 5851 V128:$LHS, V128:$MHS, V128:$RHS)>; 5852 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5853 (v2i64 V128:$RHS))), 5854 (!cast<Instruction>(NAME#"v16i8") 5855 V128:$LHS, V128:$MHS, V128:$RHS)>; 5856} 5857 5858// All operand sizes distinguished in the encoding. 5859multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5860 SDPatternOperator OpNode> { 5861 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5862 asm, ".8b", 5863 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5864 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5865 asm, ".16b", 5866 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5867 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5868 asm, ".4h", 5869 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5870 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5871 asm, ".8h", 5872 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5873 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5874 asm, ".2s", 5875 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5876 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5877 asm, ".4s", 5878 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5879 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5880 asm, ".2d", 5881 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5882} 5883 5884multiclass SIMDThreeSameVectorExtraPatterns<string inst, SDPatternOperator OpNode> { 5885 def : Pat<(v8i8 (OpNode V64:$LHS, V64:$RHS)), 5886 (!cast<Instruction>(inst#"v8i8") V64:$LHS, V64:$RHS)>; 5887 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5888 (!cast<Instruction>(inst#"v4i16") V64:$LHS, V64:$RHS)>; 5889 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5890 (!cast<Instruction>(inst#"v2i32") V64:$LHS, V64:$RHS)>; 5891 5892 def : Pat<(v16i8 (OpNode V128:$LHS, V128:$RHS)), 5893 (!cast<Instruction>(inst#"v16i8") V128:$LHS, V128:$RHS)>; 5894 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5895 (!cast<Instruction>(inst#"v8i16") V128:$LHS, V128:$RHS)>; 5896 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5897 (!cast<Instruction>(inst#"v4i32") V128:$LHS, V128:$RHS)>; 5898 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5899 (!cast<Instruction>(inst#"v2i64") V128:$LHS, V128:$RHS)>; 5900} 5901 5902// As above, but D sized elements unsupported. 5903multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5904 SDPatternOperator OpNode> { 5905 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5906 asm, ".8b", 5907 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5908 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5909 asm, ".16b", 5910 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5911 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5912 asm, ".4h", 5913 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5914 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5915 asm, ".8h", 5916 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5917 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5918 asm, ".2s", 5919 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5920 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5921 asm, ".4s", 5922 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5923} 5924 5925multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5926 SDPatternOperator OpNode> { 5927 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5928 asm, ".8b", 5929 [(set (v8i8 V64:$dst), 5930 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5931 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5932 asm, ".16b", 5933 [(set (v16i8 V128:$dst), 5934 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5935 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5936 asm, ".4h", 5937 [(set (v4i16 V64:$dst), 5938 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5939 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5940 asm, ".8h", 5941 [(set (v8i16 V128:$dst), 5942 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5943 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5944 asm, ".2s", 5945 [(set (v2i32 V64:$dst), 5946 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5947 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5948 asm, ".4s", 5949 [(set (v4i32 V128:$dst), 5950 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5951} 5952 5953// As above, but only B sized elements supported. 5954multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5955 SDPatternOperator OpNode> { 5956 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5957 asm, ".8b", 5958 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5959 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5960 asm, ".16b", 5961 [(set (v16i8 V128:$Rd), 5962 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5963} 5964 5965// As above, but only floating point elements supported. 5966let mayRaiseFPException = 1, Uses = [FPCR] in 5967multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5968 string asm, SDPatternOperator OpNode> { 5969 let Predicates = [HasNEON, HasFullFP16] in { 5970 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5971 asm, ".4h", 5972 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5973 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5974 asm, ".8h", 5975 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5976 } // Predicates = [HasNEON, HasFullFP16] 5977 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5978 asm, ".2s", 5979 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5980 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5981 asm, ".4s", 5982 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5983 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5984 asm, ".2d", 5985 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5986} 5987 5988let mayRaiseFPException = 1, Uses = [FPCR] in 5989multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5990 string asm, 5991 SDPatternOperator OpNode> { 5992 let Predicates = [HasNEON, HasFullFP16] in { 5993 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5994 asm, ".4h", 5995 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5996 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5997 asm, ".8h", 5998 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5999 } // Predicates = [HasNEON, HasFullFP16] 6000 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 6001 asm, ".2s", 6002 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6003 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 6004 asm, ".4s", 6005 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6006 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 6007 asm, ".2d", 6008 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6009} 6010 6011let mayRaiseFPException = 1, Uses = [FPCR] in 6012multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 6013 string asm, SDPatternOperator OpNode> { 6014 let Predicates = [HasNEON, HasFullFP16] in { 6015 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 6016 asm, ".4h", 6017 [(set (v4f16 V64:$dst), 6018 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 6019 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 6020 asm, ".8h", 6021 [(set (v8f16 V128:$dst), 6022 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 6023 } // Predicates = [HasNEON, HasFullFP16] 6024 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 6025 asm, ".2s", 6026 [(set (v2f32 V64:$dst), 6027 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 6028 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 6029 asm, ".4s", 6030 [(set (v4f32 V128:$dst), 6031 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 6032 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 6033 asm, ".2d", 6034 [(set (v2f64 V128:$dst), 6035 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 6036} 6037 6038// As above, but D and B sized elements unsupported. 6039let mayRaiseFPException = 1, Uses = [FPCR] in 6040multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 6041 SDPatternOperator OpNode> { 6042 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 6043 asm, ".4h", 6044 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6045 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 6046 asm, ".8h", 6047 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6048 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 6049 asm, ".2s", 6050 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6051 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 6052 asm, ".4s", 6053 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6054} 6055 6056// Logical three vector ops share opcode bits, and only use B sized elements. 6057multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 6058 SDPatternOperator OpNode = null_frag> { 6059 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 6060 asm, ".8b", 6061 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 6062 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 6063 asm, ".16b", 6064 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 6065 6066 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 6067 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6068 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 6069 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6070 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 6071 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 6072 6073 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 6074 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6075 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 6076 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6077 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 6078 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 6079} 6080 6081multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 6082 string asm, SDPatternOperator OpNode = null_frag> { 6083 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 6084 asm, ".8b", 6085 [(set (v8i8 V64:$dst), 6086 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6087 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 6088 asm, ".16b", 6089 [(set (v16i8 V128:$dst), 6090 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 6091 (v16i8 V128:$Rm)))]>; 6092 6093 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 6094 (v4i16 V64:$RHS))), 6095 (!cast<Instruction>(NAME#"v8i8") 6096 V64:$LHS, V64:$MHS, V64:$RHS)>; 6097 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 6098 (v2i32 V64:$RHS))), 6099 (!cast<Instruction>(NAME#"v8i8") 6100 V64:$LHS, V64:$MHS, V64:$RHS)>; 6101 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 6102 (v1i64 V64:$RHS))), 6103 (!cast<Instruction>(NAME#"v8i8") 6104 V64:$LHS, V64:$MHS, V64:$RHS)>; 6105 6106 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 6107 (v8i16 V128:$RHS))), 6108 (!cast<Instruction>(NAME#"v16i8") 6109 V128:$LHS, V128:$MHS, V128:$RHS)>; 6110 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 6111 (v4i32 V128:$RHS))), 6112 (!cast<Instruction>(NAME#"v16i8") 6113 V128:$LHS, V128:$MHS, V128:$RHS)>; 6114 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 6115 (v2i64 V128:$RHS))), 6116 (!cast<Instruction>(NAME#"v16i8") 6117 V128:$LHS, V128:$MHS, V128:$RHS)>; 6118} 6119 6120// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 6121// bytes from S-sized elements. 6122class BaseSIMDThreeSameVectorDot<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 6123 string kind1, string kind2, RegisterOperand RegType, 6124 ValueType AccumType, ValueType InputType, 6125 SDPatternOperator OpNode> : 6126 BaseSIMDThreeSameVectorTied<Q, U, {sz, 0b0}, {0b1, opc}, RegType, asm, kind1, 6127 [(set (AccumType RegType:$dst), 6128 (OpNode (AccumType RegType:$Rd), 6129 (InputType RegType:$Rn), 6130 (InputType RegType:$Rm)))]> { 6131 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6132} 6133 6134multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> { 6135 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, 0b10, {0b001, Mixed}, asm, ".2s", ".8b", V64, 6136 v2i32, v8i8, OpNode>; 6137 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, 0b10, {0b001, Mixed}, asm, ".4s", ".16b", V128, 6138 v4i32, v16i8, OpNode>; 6139} 6140 6141// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 6142// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 6143// 8H to 4S, when Q=1). 6144let mayRaiseFPException = 1, Uses = [FPCR] in 6145class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 6146 string kind2, RegisterOperand RegType, 6147 ValueType AccumType, ValueType InputType, 6148 SDPatternOperator OpNode> : 6149 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 6150 [(set (AccumType RegType:$dst), 6151 (OpNode (AccumType RegType:$Rd), 6152 (InputType RegType:$Rn), 6153 (InputType RegType:$Rm)))]> { 6154 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 6155 let Inst{13} = b13; 6156} 6157 6158multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 6159 SDPatternOperator OpNode> { 6160 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 6161 v2f32, v4f16, OpNode>; 6162 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 6163 v4f32, v8f16, OpNode>; 6164} 6165 6166multiclass SIMDThreeSameVectorMLA<bit Q, string asm>{ 6167 def v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b", 6168 V128, v8f16, v16i8, null_frag>; 6169} 6170 6171multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm>{ 6172 def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b", 6173 V128, v4f32, v16i8, null_frag>; 6174} 6175 6176// FP8 assembly/disassembly classes 6177 6178//---------------------------------------------------------------------------- 6179// FP8 Advanced SIMD three-register extension 6180//---------------------------------------------------------------------------- 6181class BaseSIMDThreeVectors<bit Q, bit U, bits<2> size, bits<4> op, 6182 RegisterOperand regtype1, 6183 RegisterOperand regtype2, string asm, 6184 string kind1, string kind2> 6185 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, regtype2:$Rm), asm, 6186 "\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2, "", []>, Sched<[]> { 6187 bits<5> Rd; 6188 bits<5> Rn; 6189 bits<5> Rm; 6190 let Inst{31} = 0; 6191 let Inst{30} = Q; 6192 let Inst{29} = U; 6193 let Inst{28-24} = 0b01110; 6194 let Inst{23-22} = size; 6195 let Inst{21} = 0b0; 6196 let Inst{20-16} = Rm; 6197 let Inst{15} = 0b1; 6198 let Inst{14-11} = op; 6199 let Inst{10} = 0b1; 6200 let Inst{9-5} = Rn; 6201 let Inst{4-0} = Rd; 6202} 6203 6204 6205// FCVTN (FP16 to FP8) 6206multiclass SIMDThreeSameSizeVectorCvt<string asm> { 6207 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b01, 0b1110, V64, V64, asm, ".8b",".4h">; 6208 def v16f8 : BaseSIMDThreeVectors<0b1, 0b0, 0b01, 0b1110, V128, V128, asm, ".16b", ".8h">; 6209} 6210 6211// TODO : Create v16f8 value type 6212// FCVTN, FCVTN2 (FP32 to FP8) 6213multiclass SIMDThreeVectorCvt<string asm> { 6214 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b00, 0b1110, V64, V128, asm, ".8b", ".4s">; 6215 def 2v16f8 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1110, asm#2, ".16b", ".4s", 6216 V128, v16i8, v4f32, null_frag>; 6217} 6218 6219// TODO: Create a new Value Type v8f8 and v16f8 6220multiclass SIMDThreeSameVectorDOT2<string asm> { 6221 def v4f16 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b01, 0b1111, asm, ".4h", ".8b", 6222 V64, v4f16, v8i8, null_frag>; 6223 def v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1111, asm, ".8h", ".16b", 6224 V128, v8f16, v16i8, null_frag>; 6225} 6226 6227multiclass SIMDThreeSameVectorDOT4<string asm> { 6228 def v2f32 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b00, 0b1111, asm, ".2s", ".8b", 6229 V64, v2f32, v8i8, null_frag>; 6230 def v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1111, asm, ".4s", ".16b", 6231 V128, v4f32, v16i8, null_frag>; 6232} 6233 6234//---------------------------------------------------------------------------- 6235// AdvSIMD two register vector instructions. 6236//---------------------------------------------------------------------------- 6237 6238let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6239class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6240 bits<2> size2, RegisterOperand regtype, string asm, 6241 string dstkind, string srckind, list<dag> pattern> 6242 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6243 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6244 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 6245 Sched<[!if(Q, WriteVq, WriteVd)]> { 6246 bits<5> Rd; 6247 bits<5> Rn; 6248 let Inst{31} = 0; 6249 let Inst{30} = Q; 6250 let Inst{29} = U; 6251 let Inst{28-24} = 0b01110; 6252 let Inst{23-22} = size; 6253 let Inst{21} = 0b1; 6254 let Inst{20-19} = size2; 6255 let Inst{18-17} = 0b00; 6256 let Inst{16-12} = opcode; 6257 let Inst{11-10} = 0b10; 6258 let Inst{9-5} = Rn; 6259 let Inst{4-0} = Rd; 6260} 6261 6262let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6263class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6264 bits<2> size2, RegisterOperand regtype, 6265 string asm, string dstkind, string srckind, 6266 list<dag> pattern> 6267 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 6268 "{\t$Rd" # dstkind # ", $Rn" # srckind # 6269 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6270 Sched<[!if(Q, WriteVq, WriteVd)]> { 6271 bits<5> Rd; 6272 bits<5> Rn; 6273 let Inst{31} = 0; 6274 let Inst{30} = Q; 6275 let Inst{29} = U; 6276 let Inst{28-24} = 0b01110; 6277 let Inst{23-22} = size; 6278 let Inst{21} = 0b1; 6279 let Inst{20-19} = size2; 6280 let Inst{18-17} = 0b00; 6281 let Inst{16-12} = opcode; 6282 let Inst{11-10} = 0b10; 6283 let Inst{9-5} = Rn; 6284 let Inst{4-0} = Rd; 6285} 6286 6287// Supports B, H, and S element sizes. 6288multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 6289 SDPatternOperator OpNode> { 6290 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6291 asm, ".8b", ".8b", 6292 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6293 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6294 asm, ".16b", ".16b", 6295 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6296 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6297 asm, ".4h", ".4h", 6298 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6299 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6300 asm, ".8h", ".8h", 6301 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6302 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6303 asm, ".2s", ".2s", 6304 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6305 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6306 asm, ".4s", ".4s", 6307 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6308} 6309 6310class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 6311 RegisterOperand regtype, string asm, string dstkind, 6312 string srckind, string amount> 6313 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 6314 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 6315 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 6316 Sched<[WriteVq]> { 6317 bits<5> Rd; 6318 bits<5> Rn; 6319 let Inst{31} = 0; 6320 let Inst{30} = Q; 6321 let Inst{29-24} = 0b101110; 6322 let Inst{23-22} = size; 6323 let Inst{21-10} = 0b100001001110; 6324 let Inst{9-5} = Rn; 6325 let Inst{4-0} = Rd; 6326} 6327 6328multiclass SIMDVectorLShiftLongBySizeBHS { 6329 let hasSideEffects = 0 in { 6330 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 6331 "shll", ".8h", ".8b", "8">; 6332 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 6333 "shll2", ".8h", ".16b", "8">; 6334 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 6335 "shll", ".4s", ".4h", "16">; 6336 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 6337 "shll2", ".4s", ".8h", "16">; 6338 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 6339 "shll", ".2d", ".2s", "32">; 6340 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 6341 "shll2", ".2d", ".4s", "32">; 6342 } 6343} 6344 6345// Supports all element sizes. 6346multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 6347 SDPatternOperator OpNode> { 6348 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6349 asm, ".4h", ".8b", 6350 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6351 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6352 asm, ".8h", ".16b", 6353 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6354 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6355 asm, ".2s", ".4h", 6356 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6357 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6358 asm, ".4s", ".8h", 6359 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6360 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6361 asm, ".1d", ".2s", 6362 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6363 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6364 asm, ".2d", ".4s", 6365 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6366} 6367 6368multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 6369 SDPatternOperator OpNode> { 6370 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6371 asm, ".4h", ".8b", 6372 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 6373 (v8i8 V64:$Rn)))]>; 6374 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6375 asm, ".8h", ".16b", 6376 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 6377 (v16i8 V128:$Rn)))]>; 6378 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6379 asm, ".2s", ".4h", 6380 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 6381 (v4i16 V64:$Rn)))]>; 6382 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6383 asm, ".4s", ".8h", 6384 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 6385 (v8i16 V128:$Rn)))]>; 6386 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6387 asm, ".1d", ".2s", 6388 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 6389 (v2i32 V64:$Rn)))]>; 6390 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6391 asm, ".2d", ".4s", 6392 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 6393 (v4i32 V128:$Rn)))]>; 6394} 6395 6396// Supports all element sizes, except 1xD. 6397multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 6398 SDPatternOperator OpNode> { 6399 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 6400 asm, ".8b", ".8b", 6401 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 6402 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 6403 asm, ".16b", ".16b", 6404 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 6405 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 6406 asm, ".4h", ".4h", 6407 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 6408 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 6409 asm, ".8h", ".8h", 6410 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 6411 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 6412 asm, ".2s", ".2s", 6413 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 6414 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 6415 asm, ".4s", ".4s", 6416 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 6417 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 6418 asm, ".2d", ".2d", 6419 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 6420} 6421 6422multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 6423 SDPatternOperator OpNode = null_frag> { 6424 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6425 asm, ".8b", ".8b", 6426 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6427 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6428 asm, ".16b", ".16b", 6429 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6430 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6431 asm, ".4h", ".4h", 6432 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6433 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6434 asm, ".8h", ".8h", 6435 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6436 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 6437 asm, ".2s", ".2s", 6438 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6439 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 6440 asm, ".4s", ".4s", 6441 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6442 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 6443 asm, ".2d", ".2d", 6444 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6445} 6446 6447 6448// Supports only B element sizes. 6449multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 6450 SDPatternOperator OpNode> { 6451 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 6452 asm, ".8b", ".8b", 6453 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 6454 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 6455 asm, ".16b", ".16b", 6456 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 6457 6458} 6459 6460// Supports only B and H element sizes. 6461multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 6462 SDPatternOperator OpNode> { 6463 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 6464 asm, ".8b", ".8b", 6465 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 6466 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 6467 asm, ".16b", ".16b", 6468 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 6469 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 6470 asm, ".4h", ".4h", 6471 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 6472 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 6473 asm, ".8h", ".8h", 6474 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 6475} 6476 6477// Supports H, S and D element sizes, uses high bit of the size field 6478// as an extra opcode bit. 6479multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 6480 SDPatternOperator OpNode, 6481 int fpexceptions = 1> { 6482 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in { 6483 let Predicates = [HasNEON, HasFullFP16] in { 6484 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6485 asm, ".4h", ".4h", 6486 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6487 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6488 asm, ".8h", ".8h", 6489 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6490 } // Predicates = [HasNEON, HasFullFP16] 6491 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6492 asm, ".2s", ".2s", 6493 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6494 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6495 asm, ".4s", ".4s", 6496 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6497 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6498 asm, ".2d", ".2d", 6499 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6500 } 6501} 6502 6503multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm, 6504 SDPatternOperator OpNode> 6505 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>; 6506 6507// Supports only S and D element sizes 6508let mayRaiseFPException = 1, Uses = [FPCR] in 6509multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 6510 SDPatternOperator OpNode = null_frag> { 6511 6512 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 6513 asm, ".2s", ".2s", 6514 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6515 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 6516 asm, ".4s", ".4s", 6517 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6518 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 6519 asm, ".2d", ".2d", 6520 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6521} 6522 6523multiclass FRIntNNTVector<bit U, bit op, string asm, 6524 SDPatternOperator OpNode = null_frag> : 6525 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 6526 6527// Supports only S element size. 6528multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 6529 SDPatternOperator OpNode> { 6530 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6531 asm, ".2s", ".2s", 6532 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6533 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6534 asm, ".4s", ".4s", 6535 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6536} 6537 6538let mayRaiseFPException = 1, Uses = [FPCR] in 6539multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 6540 SDPatternOperator OpNode> { 6541 let Predicates = [HasNEON, HasFullFP16] in { 6542 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6543 asm, ".4h", ".4h", 6544 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 6545 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6546 asm, ".8h", ".8h", 6547 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 6548 } // Predicates = [HasNEON, HasFullFP16] 6549 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6550 asm, ".2s", ".2s", 6551 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 6552 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6553 asm, ".4s", ".4s", 6554 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 6555 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6556 asm, ".2d", ".2d", 6557 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6558} 6559 6560let mayRaiseFPException = 1, Uses = [FPCR] in 6561multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 6562 SDPatternOperator OpNode> { 6563 let Predicates = [HasNEON, HasFullFP16] in { 6564 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 6565 asm, ".4h", ".4h", 6566 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 6567 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 6568 asm, ".8h", ".8h", 6569 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6570 } // Predicates = [HasNEON, HasFullFP16] 6571 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 6572 asm, ".2s", ".2s", 6573 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 6574 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 6575 asm, ".4s", ".4s", 6576 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6577 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 6578 asm, ".2d", ".2d", 6579 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6580} 6581 6582let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6583class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6584 RegisterOperand inreg, RegisterOperand outreg, 6585 string asm, string outkind, string inkind, 6586 list<dag> pattern> 6587 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 6588 "{\t$Rd" # outkind # ", $Rn" # inkind # 6589 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 6590 Sched<[WriteVq]> { 6591 bits<5> Rd; 6592 bits<5> Rn; 6593 let Inst{31} = 0; 6594 let Inst{30} = Q; 6595 let Inst{29} = U; 6596 let Inst{28-24} = 0b01110; 6597 let Inst{23-22} = size; 6598 let Inst{21-17} = 0b10000; 6599 let Inst{16-12} = opcode; 6600 let Inst{11-10} = 0b10; 6601 let Inst{9-5} = Rn; 6602 let Inst{4-0} = Rd; 6603} 6604 6605let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6606class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6607 RegisterOperand inreg, RegisterOperand outreg, 6608 string asm, string outkind, string inkind, 6609 list<dag> pattern> 6610 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 6611 "{\t$Rd" # outkind # ", $Rn" # inkind # 6612 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 6613 Sched<[WriteVq]> { 6614 bits<5> Rd; 6615 bits<5> Rn; 6616 let Inst{31} = 0; 6617 let Inst{30} = Q; 6618 let Inst{29} = U; 6619 let Inst{28-24} = 0b01110; 6620 let Inst{23-22} = size; 6621 let Inst{21-17} = 0b10000; 6622 let Inst{16-12} = opcode; 6623 let Inst{11-10} = 0b10; 6624 let Inst{9-5} = Rn; 6625 let Inst{4-0} = Rd; 6626} 6627 6628multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 6629 SDPatternOperator OpNode> { 6630 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 6631 asm, ".8b", ".8h", 6632 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 6633 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 6634 asm#"2", ".16b", ".8h", []>; 6635 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 6636 asm, ".4h", ".4s", 6637 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 6638 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 6639 asm#"2", ".8h", ".4s", []>; 6640 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 6641 asm, ".2s", ".2d", 6642 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 6643 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 6644 asm#"2", ".4s", ".2d", []>; 6645 6646 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 6647 (!cast<Instruction>(NAME # "v16i8") 6648 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6649 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 6650 (!cast<Instruction>(NAME # "v8i16") 6651 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6652 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 6653 (!cast<Instruction>(NAME # "v4i32") 6654 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6655} 6656 6657//---------------------------------------------------------------------------- 6658// FP8 Advanced SIMD two-register miscellaneous 6659//---------------------------------------------------------------------------- 6660multiclass SIMDMixedTwoVectorFP8<bits<2>sz, string asm> { 6661 def v8f16 : BaseSIMDMixedTwoVector<0b0, 0b1, sz, 0b10111, V64, V128, 6662 asm, ".8h", ".8b", []>; 6663 def 2v8f16 : BaseSIMDMixedTwoVector<0b1, 0b1, sz, 0b10111, V128, V128, 6664 asm#2, ".8h", ".16b", []>; 6665} 6666 6667class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 6668 bits<5> opcode, RegisterOperand regtype, string asm, 6669 string kind, string zero, ValueType dty, 6670 ValueType sty, SDNode OpNode> 6671 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6672 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 6673 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 6674 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 6675 Sched<[!if(Q, WriteVq, WriteVd)]> { 6676 bits<5> Rd; 6677 bits<5> Rn; 6678 let Inst{31} = 0; 6679 let Inst{30} = Q; 6680 let Inst{29} = U; 6681 let Inst{28-24} = 0b01110; 6682 let Inst{23-22} = size; 6683 let Inst{21} = 0b1; 6684 let Inst{20-19} = size2; 6685 let Inst{18-17} = 0b00; 6686 let Inst{16-12} = opcode; 6687 let Inst{11-10} = 0b10; 6688 let Inst{9-5} = Rn; 6689 let Inst{4-0} = Rd; 6690} 6691 6692// Comparisons support all element sizes, except 1xD. 6693multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 6694 SDNode OpNode> { 6695 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 6696 asm, ".8b", "0", 6697 v8i8, v8i8, OpNode>; 6698 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 6699 asm, ".16b", "0", 6700 v16i8, v16i8, OpNode>; 6701 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 6702 asm, ".4h", "0", 6703 v4i16, v4i16, OpNode>; 6704 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 6705 asm, ".8h", "0", 6706 v8i16, v8i16, OpNode>; 6707 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 6708 asm, ".2s", "0", 6709 v2i32, v2i32, OpNode>; 6710 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 6711 asm, ".4s", "0", 6712 v4i32, v4i32, OpNode>; 6713 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 6714 asm, ".2d", "0", 6715 v2i64, v2i64, OpNode>; 6716} 6717 6718// FP Comparisons support only S and D element sizes (and H for v8.2a). 6719multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 6720 string asm, SDNode OpNode> { 6721 6722 let mayRaiseFPException = 1, Uses = [FPCR] in { 6723 let Predicates = [HasNEON, HasFullFP16] in { 6724 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 6725 asm, ".4h", "0.0", 6726 v4i16, v4f16, OpNode>; 6727 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 6728 asm, ".8h", "0.0", 6729 v8i16, v8f16, OpNode>; 6730 } // Predicates = [HasNEON, HasFullFP16] 6731 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 6732 asm, ".2s", "0.0", 6733 v2i32, v2f32, OpNode>; 6734 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 6735 asm, ".4s", "0.0", 6736 v4i32, v4f32, OpNode>; 6737 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 6738 asm, ".2d", "0.0", 6739 v2i64, v2f64, OpNode>; 6740 } 6741 6742 let Predicates = [HasNEON, HasFullFP16] in { 6743 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 6744 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6745 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 6746 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6747 } 6748 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 6749 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6750 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 6751 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6752 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 6753 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6754 let Predicates = [HasNEON, HasFullFP16] in { 6755 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 6756 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 6757 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 6758 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 6759 } 6760 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 6761 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 6762 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 6763 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 6764 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 6765 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 6766} 6767 6768let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6769class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 6770 RegisterOperand outtype, RegisterOperand intype, 6771 string asm, string VdTy, string VnTy, 6772 list<dag> pattern> 6773 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 6774 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 6775 Sched<[WriteVq]> { 6776 bits<5> Rd; 6777 bits<5> Rn; 6778 let Inst{31} = 0; 6779 let Inst{30} = Q; 6780 let Inst{29} = U; 6781 let Inst{28-24} = 0b01110; 6782 let Inst{23-22} = size; 6783 let Inst{21-17} = 0b10000; 6784 let Inst{16-12} = opcode; 6785 let Inst{11-10} = 0b10; 6786 let Inst{9-5} = Rn; 6787 let Inst{4-0} = Rd; 6788} 6789 6790let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 6791class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 6792 RegisterOperand outtype, RegisterOperand intype, 6793 string asm, string VdTy, string VnTy, 6794 list<dag> pattern> 6795 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 6796 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 6797 Sched<[WriteVq]> { 6798 bits<5> Rd; 6799 bits<5> Rn; 6800 let Inst{31} = 0; 6801 let Inst{30} = Q; 6802 let Inst{29} = U; 6803 let Inst{28-24} = 0b01110; 6804 let Inst{23-22} = size; 6805 let Inst{21-17} = 0b10000; 6806 let Inst{16-12} = opcode; 6807 let Inst{11-10} = 0b10; 6808 let Inst{9-5} = Rn; 6809 let Inst{4-0} = Rd; 6810} 6811 6812multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 6813 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 6814 asm, ".4s", ".4h", []>; 6815 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 6816 asm#"2", ".4s", ".8h", []>; 6817 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 6818 asm, ".2d", ".2s", []>; 6819 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 6820 asm#"2", ".2d", ".4s", []>; 6821} 6822 6823multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 6824 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 6825 asm, ".4h", ".4s", []>; 6826 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 6827 asm#"2", ".8h", ".4s", []>; 6828 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6829 asm, ".2s", ".2d", []>; 6830 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6831 asm#"2", ".4s", ".2d", []>; 6832} 6833 6834multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 6835 SDPatternOperator OpNode> { 6836 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 6837 asm, ".2s", ".2d", 6838 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 6839 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 6840 asm#"2", ".4s", ".2d", []>; 6841 6842 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 6843 (!cast<Instruction>(NAME # "v4f32") 6844 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 6845} 6846 6847//---------------------------------------------------------------------------- 6848// AdvSIMD three register different-size vector instructions. 6849//---------------------------------------------------------------------------- 6850 6851let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6852class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 6853 RegisterOperand outtype, RegisterOperand intype1, 6854 RegisterOperand intype2, string asm, 6855 string outkind, string inkind1, string inkind2, 6856 list<dag> pattern> 6857 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 6858 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6859 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 6860 Sched<[WriteVq]> { 6861 bits<5> Rd; 6862 bits<5> Rn; 6863 bits<5> Rm; 6864 let Inst{31} = 0; 6865 let Inst{30} = size{0}; 6866 let Inst{29} = U; 6867 let Inst{28-24} = 0b01110; 6868 let Inst{23-22} = size{2-1}; 6869 let Inst{21} = 1; 6870 let Inst{20-16} = Rm; 6871 let Inst{15-12} = opcode; 6872 let Inst{11-10} = 0b00; 6873 let Inst{9-5} = Rn; 6874 let Inst{4-0} = Rd; 6875} 6876 6877let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6878class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 6879 RegisterOperand outtype, RegisterOperand intype1, 6880 RegisterOperand intype2, string asm, 6881 string outkind, string inkind1, string inkind2, 6882 list<dag> pattern> 6883 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 6884 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 6885 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 6886 Sched<[WriteVq]> { 6887 bits<5> Rd; 6888 bits<5> Rn; 6889 bits<5> Rm; 6890 let Inst{31} = 0; 6891 let Inst{30} = size{0}; 6892 let Inst{29} = U; 6893 let Inst{28-24} = 0b01110; 6894 let Inst{23-22} = size{2-1}; 6895 let Inst{21} = 1; 6896 let Inst{20-16} = Rm; 6897 let Inst{15-12} = opcode; 6898 let Inst{11-10} = 0b00; 6899 let Inst{9-5} = Rn; 6900 let Inst{4-0} = Rd; 6901} 6902 6903// FIXME: TableGen doesn't know how to deal with expanded types that also 6904// change the element count (in this case, placing the results in 6905// the high elements of the result register rather than the low 6906// elements). Until that's fixed, we can't code-gen those. 6907multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 6908 Intrinsic IntOp> { 6909 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6910 V64, V128, V128, 6911 asm, ".8b", ".8h", ".8h", 6912 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 6913 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6914 V128, V128, V128, 6915 asm#"2", ".16b", ".8h", ".8h", 6916 []>; 6917 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6918 V64, V128, V128, 6919 asm, ".4h", ".4s", ".4s", 6920 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 6921 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6922 V128, V128, V128, 6923 asm#"2", ".8h", ".4s", ".4s", 6924 []>; 6925 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6926 V64, V128, V128, 6927 asm, ".2s", ".2d", ".2d", 6928 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6929 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6930 V128, V128, V128, 6931 asm#"2", ".4s", ".2d", ".2d", 6932 []>; 6933 6934 6935 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6936 // a version attached to an instruction. 6937 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6938 (v8i16 V128:$Rm))), 6939 (!cast<Instruction>(NAME # "v8i16_v16i8") 6940 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6941 V128:$Rn, V128:$Rm)>; 6942 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6943 (v4i32 V128:$Rm))), 6944 (!cast<Instruction>(NAME # "v4i32_v8i16") 6945 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6946 V128:$Rn, V128:$Rm)>; 6947 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6948 (v2i64 V128:$Rm))), 6949 (!cast<Instruction>(NAME # "v2i64_v4i32") 6950 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6951 V128:$Rn, V128:$Rm)>; 6952} 6953 6954multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6955 SDPatternOperator OpNode> { 6956 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6957 V128, V64, V64, 6958 asm, ".8h", ".8b", ".8b", 6959 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6960 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6961 V128, V128, V128, 6962 asm#"2", ".8h", ".16b", ".16b", []>; 6963 let Predicates = [HasAES] in { 6964 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6965 V128, V64, V64, 6966 asm, ".1q", ".1d", ".1d", 6967 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>; 6968 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6969 V128, V128, V128, 6970 asm#"2", ".1q", ".2d", ".2d", 6971 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)), 6972 (extract_high_v2i64 (v2i64 V128:$Rm))))]>; 6973 } 6974 6975 def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))), 6976 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))), 6977 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6978} 6979 6980multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6981 SDPatternOperator OpNode> { 6982 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6983 V128, V64, V64, 6984 asm, ".4s", ".4h", ".4h", 6985 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6986 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6987 V128, V128, V128, 6988 asm#"2", ".4s", ".8h", ".8h", 6989 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 6990 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 6991 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6992 V128, V64, V64, 6993 asm, ".2d", ".2s", ".2s", 6994 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6995 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6996 V128, V128, V128, 6997 asm#"2", ".2d", ".4s", ".4s", 6998 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 6999 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7000} 7001 7002multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 7003 SDPatternOperator OpNode = null_frag> { 7004 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7005 V128, V64, V64, 7006 asm, ".8h", ".8b", ".8b", 7007 [(set (v8i16 V128:$Rd), 7008 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 7009 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7010 V128, V128, V128, 7011 asm#"2", ".8h", ".16b", ".16b", 7012 [(set (v8i16 V128:$Rd), 7013 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7014 (extract_high_v16i8 (v16i8 V128:$Rm))))))]>; 7015 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7016 V128, V64, V64, 7017 asm, ".4s", ".4h", ".4h", 7018 [(set (v4i32 V128:$Rd), 7019 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 7020 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7021 V128, V128, V128, 7022 asm#"2", ".4s", ".8h", ".8h", 7023 [(set (v4i32 V128:$Rd), 7024 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7025 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7026 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7027 V128, V64, V64, 7028 asm, ".2d", ".2s", ".2s", 7029 [(set (v2i64 V128:$Rd), 7030 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 7031 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7032 V128, V128, V128, 7033 asm#"2", ".2d", ".4s", ".4s", 7034 [(set (v2i64 V128:$Rd), 7035 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7036 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7037} 7038 7039multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 7040 string asm, 7041 SDPatternOperator OpNode> { 7042 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7043 V128, V64, V64, 7044 asm, ".8h", ".8b", ".8b", 7045 [(set (v8i16 V128:$dst), 7046 (add (v8i16 V128:$Rd), 7047 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 7048 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7049 V128, V128, V128, 7050 asm#"2", ".8h", ".16b", ".16b", 7051 [(set (v8i16 V128:$dst), 7052 (add (v8i16 V128:$Rd), 7053 (zext (v8i8 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7054 (extract_high_v16i8 (v16i8 V128:$Rm)))))))]>; 7055 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7056 V128, V64, V64, 7057 asm, ".4s", ".4h", ".4h", 7058 [(set (v4i32 V128:$dst), 7059 (add (v4i32 V128:$Rd), 7060 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 7061 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7062 V128, V128, V128, 7063 asm#"2", ".4s", ".8h", ".8h", 7064 [(set (v4i32 V128:$dst), 7065 (add (v4i32 V128:$Rd), 7066 (zext (v4i16 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7067 (extract_high_v8i16 (v8i16 V128:$Rm)))))))]>; 7068 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7069 V128, V64, V64, 7070 asm, ".2d", ".2s", ".2s", 7071 [(set (v2i64 V128:$dst), 7072 (add (v2i64 V128:$Rd), 7073 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 7074 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7075 V128, V128, V128, 7076 asm#"2", ".2d", ".4s", ".4s", 7077 [(set (v2i64 V128:$dst), 7078 (add (v2i64 V128:$Rd), 7079 (zext (v2i32 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7080 (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; 7081} 7082 7083multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 7084 SDPatternOperator OpNode = null_frag> { 7085 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7086 V128, V64, V64, 7087 asm, ".8h", ".8b", ".8b", 7088 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7089 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7090 V128, V128, V128, 7091 asm#"2", ".8h", ".16b", ".16b", 7092 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), 7093 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7094 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7095 V128, V64, V64, 7096 asm, ".4s", ".4h", ".4h", 7097 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7098 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7099 V128, V128, V128, 7100 asm#"2", ".4s", ".8h", ".8h", 7101 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 7102 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7103 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7104 V128, V64, V64, 7105 asm, ".2d", ".2s", ".2s", 7106 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7107 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7108 V128, V128, V128, 7109 asm#"2", ".2d", ".4s", ".4s", 7110 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 7111 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7112} 7113 7114multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 7115 string asm, 7116 SDPatternOperator OpNode> { 7117 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 7118 V128, V64, V64, 7119 asm, ".8h", ".8b", ".8b", 7120 [(set (v8i16 V128:$dst), 7121 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 7122 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 7123 V128, V128, V128, 7124 asm#"2", ".8h", ".16b", ".16b", 7125 [(set (v8i16 V128:$dst), 7126 (OpNode (v8i16 V128:$Rd), 7127 (extract_high_v16i8 (v16i8 V128:$Rn)), 7128 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7129 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7130 V128, V64, V64, 7131 asm, ".4s", ".4h", ".4h", 7132 [(set (v4i32 V128:$dst), 7133 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 7134 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7135 V128, V128, V128, 7136 asm#"2", ".4s", ".8h", ".8h", 7137 [(set (v4i32 V128:$dst), 7138 (OpNode (v4i32 V128:$Rd), 7139 (extract_high_v8i16 (v8i16 V128:$Rn)), 7140 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7141 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7142 V128, V64, V64, 7143 asm, ".2d", ".2s", ".2s", 7144 [(set (v2i64 V128:$dst), 7145 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 7146 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7147 V128, V128, V128, 7148 asm#"2", ".2d", ".4s", ".4s", 7149 [(set (v2i64 V128:$dst), 7150 (OpNode (v2i64 V128:$Rd), 7151 (extract_high_v4i32 (v4i32 V128:$Rn)), 7152 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7153} 7154 7155multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 7156 SDPatternOperator Accum> { 7157 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 7158 V128, V64, V64, 7159 asm, ".4s", ".4h", ".4h", 7160 [(set (v4i32 V128:$dst), 7161 (Accum (v4i32 V128:$Rd), 7162 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 7163 (v4i16 V64:$Rm)))))]>; 7164 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 7165 V128, V128, V128, 7166 asm#"2", ".4s", ".8h", ".8h", 7167 [(set (v4i32 V128:$dst), 7168 (Accum (v4i32 V128:$Rd), 7169 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)), 7170 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>; 7171 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 7172 V128, V64, V64, 7173 asm, ".2d", ".2s", ".2s", 7174 [(set (v2i64 V128:$dst), 7175 (Accum (v2i64 V128:$Rd), 7176 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 7177 (v2i32 V64:$Rm)))))]>; 7178 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 7179 V128, V128, V128, 7180 asm#"2", ".2d", ".4s", ".4s", 7181 [(set (v2i64 V128:$dst), 7182 (Accum (v2i64 V128:$Rd), 7183 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)), 7184 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>; 7185} 7186 7187multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 7188 SDPatternOperator OpNode> { 7189 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 7190 V128, V128, V64, 7191 asm, ".8h", ".8h", ".8b", 7192 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 7193 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 7194 V128, V128, V128, 7195 asm#"2", ".8h", ".8h", ".16b", 7196 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7197 (extract_high_v16i8 (v16i8 V128:$Rm))))]>; 7198 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 7199 V128, V128, V64, 7200 asm, ".4s", ".4s", ".4h", 7201 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 7202 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 7203 V128, V128, V128, 7204 asm#"2", ".4s", ".4s", ".8h", 7205 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7206 (extract_high_v8i16 (v8i16 V128:$Rm))))]>; 7207 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 7208 V128, V128, V64, 7209 asm, ".2d", ".2d", ".2s", 7210 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 7211 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 7212 V128, V128, V128, 7213 asm#"2", ".2d", ".2d", ".4s", 7214 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7215 (extract_high_v4i32 (v4i32 V128:$Rm))))]>; 7216} 7217 7218//---------------------------------------------------------------------------- 7219// AdvSIMD bitwise extract from vector 7220//---------------------------------------------------------------------------- 7221 7222class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 7223 string asm, string kind> 7224 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 7225 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 7226 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 7227 [(set (vty regtype:$Rd), 7228 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 7229 Sched<[!if(size, WriteVq, WriteVd)]> { 7230 bits<5> Rd; 7231 bits<5> Rn; 7232 bits<5> Rm; 7233 bits<4> imm; 7234 let Inst{31} = 0; 7235 let Inst{30} = size; 7236 let Inst{29-21} = 0b101110000; 7237 let Inst{20-16} = Rm; 7238 let Inst{15} = 0; 7239 let Inst{14-11} = imm; 7240 let Inst{10} = 0; 7241 let Inst{9-5} = Rn; 7242 let Inst{4-0} = Rd; 7243} 7244 7245 7246multiclass SIMDBitwiseExtract<string asm> { 7247 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 7248 let imm{3} = 0; 7249 } 7250 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 7251} 7252 7253//---------------------------------------------------------------------------- 7254// AdvSIMD zip vector 7255//---------------------------------------------------------------------------- 7256 7257class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 7258 string asm, string kind, SDNode OpNode, ValueType valty> 7259 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7260 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 7261 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 7262 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 7263 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> { 7264 bits<5> Rd; 7265 bits<5> Rn; 7266 bits<5> Rm; 7267 let Inst{31} = 0; 7268 let Inst{30} = size{0}; 7269 let Inst{29-24} = 0b001110; 7270 let Inst{23-22} = size{2-1}; 7271 let Inst{21} = 0; 7272 let Inst{20-16} = Rm; 7273 let Inst{15} = 0; 7274 let Inst{14-12} = opc; 7275 let Inst{11-10} = 0b10; 7276 let Inst{9-5} = Rn; 7277 let Inst{4-0} = Rd; 7278} 7279 7280multiclass SIMDZipVector<bits<3>opc, string asm, 7281 SDNode OpNode> { 7282 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 7283 asm, ".8b", OpNode, v8i8>; 7284 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 7285 asm, ".16b", OpNode, v16i8>; 7286 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 7287 asm, ".4h", OpNode, v4i16>; 7288 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 7289 asm, ".8h", OpNode, v8i16>; 7290 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 7291 asm, ".2s", OpNode, v2i32>; 7292 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 7293 asm, ".4s", OpNode, v4i32>; 7294 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 7295 asm, ".2d", OpNode, v2i64>; 7296 7297 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 7298 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7299 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)), 7300 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 7301 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 7302 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7303 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)), 7304 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 7305 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 7306 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 7307 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 7308 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 7309 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 7310 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 7311} 7312 7313//---------------------------------------------------------------------------- 7314// AdvSIMD three register scalar instructions 7315//---------------------------------------------------------------------------- 7316 7317let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7318class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 7319 RegisterClass regtype, string asm, 7320 list<dag> pattern> 7321 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 7322 "\t$Rd, $Rn, $Rm", "", pattern>, 7323 Sched<[WriteVd]> { 7324 bits<5> Rd; 7325 bits<5> Rn; 7326 bits<5> Rm; 7327 let Inst{31-30} = 0b01; 7328 let Inst{29} = U; 7329 let Inst{28-24} = 0b11110; 7330 let Inst{23-21} = size; 7331 let Inst{20-16} = Rm; 7332 let Inst{15-11} = opcode; 7333 let Inst{10} = 1; 7334 let Inst{9-5} = Rn; 7335 let Inst{4-0} = Rd; 7336} 7337 7338let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7339class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 7340 dag oops, dag iops, string asm, 7341 list<dag> pattern> 7342 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 7343 Sched<[WriteVd]> { 7344 bits<5> Rd; 7345 bits<5> Rn; 7346 bits<5> Rm; 7347 let Inst{31-30} = 0b01; 7348 let Inst{29} = U; 7349 let Inst{28-24} = 0b11110; 7350 let Inst{23-22} = size; 7351 let Inst{21} = R; 7352 let Inst{20-16} = Rm; 7353 let Inst{15-11} = opcode; 7354 let Inst{10} = 1; 7355 let Inst{9-5} = Rn; 7356 let Inst{4-0} = Rd; 7357} 7358 7359multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 7360 SDPatternOperator OpNode> { 7361 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7362 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7363} 7364 7365multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 7366 SDPatternOperator OpNode> { 7367 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 7368 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 7369 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 7370 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7371 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 7372 7373 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 7374 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 7375 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 7376 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 7377} 7378 7379multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 7380 SDPatternOperator OpNode> { 7381 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 7382 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7383 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 7384} 7385 7386multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> { 7387 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 7388 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 7389 asm, []>; 7390 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 7391 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 7392 asm, []>; 7393} 7394 7395multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 7396 SDPatternOperator OpNode = null_frag, 7397 Predicate pred = HasNEON> { 7398 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7399 let Predicates = [pred] in { 7400 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7401 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7402 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7403 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 7404 } 7405 let Predicates = [pred, HasFullFP16] in { 7406 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7407 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>; 7408 } 7409 } 7410 7411 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7412 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7413} 7414 7415multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 7416 SDPatternOperator OpNode = null_frag> { 7417 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in { 7418 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 7419 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 7420 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 7421 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 7422 let Predicates = [HasNEON, HasFullFP16] in { 7423 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 7424 []>; 7425 } // Predicates = [HasNEON, HasFullFP16] 7426 } 7427 7428 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 7429 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 7430} 7431 7432class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 7433 dag oops, dag iops, string asm, string cstr, list<dag> pat> 7434 : I<oops, iops, asm, 7435 "\t$Rd, $Rn, $Rm", cstr, pat>, 7436 Sched<[WriteVd]> { 7437 bits<5> Rd; 7438 bits<5> Rn; 7439 bits<5> Rm; 7440 let Inst{31-30} = 0b01; 7441 let Inst{29} = U; 7442 let Inst{28-24} = 0b11110; 7443 let Inst{23-22} = size; 7444 let Inst{21} = 1; 7445 let Inst{20-16} = Rm; 7446 let Inst{15-11} = opcode; 7447 let Inst{10} = 0; 7448 let Inst{9-5} = Rn; 7449 let Inst{4-0} = Rd; 7450} 7451 7452let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7453multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 7454 SDPatternOperator OpNode = null_frag> { 7455 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7456 (outs FPR32:$Rd), 7457 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 7458 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7459 (outs FPR64:$Rd), 7460 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 7461 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7462} 7463 7464let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7465multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 7466 SDPatternOperator OpNode = null_frag> { 7467 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 7468 (outs FPR32:$dst), 7469 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 7470 asm, "$Rd = $dst", []>; 7471 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 7472 (outs FPR64:$dst), 7473 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 7474 asm, "$Rd = $dst", 7475 [(set (i64 FPR64:$dst), 7476 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 7477} 7478 7479//---------------------------------------------------------------------------- 7480// AdvSIMD two register scalar instructions 7481//---------------------------------------------------------------------------- 7482 7483let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7484class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7485 RegisterClass regtype, RegisterClass regtype2, 7486 string asm, list<dag> pat> 7487 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 7488 "\t$Rd, $Rn", "", pat>, 7489 Sched<[WriteVd]> { 7490 bits<5> Rd; 7491 bits<5> Rn; 7492 let Inst{31-30} = 0b01; 7493 let Inst{29} = U; 7494 let Inst{28-24} = 0b11110; 7495 let Inst{23-22} = size; 7496 let Inst{21} = 0b1; 7497 let Inst{20-19} = size2; 7498 let Inst{18-17} = 0b00; 7499 let Inst{16-12} = opcode; 7500 let Inst{11-10} = 0b10; 7501 let Inst{9-5} = Rn; 7502 let Inst{4-0} = Rd; 7503} 7504 7505let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7506class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 7507 RegisterClass regtype, RegisterClass regtype2, 7508 string asm, list<dag> pat> 7509 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 7510 "\t$Rd, $Rn", "$Rd = $dst", pat>, 7511 Sched<[WriteVd]> { 7512 bits<5> Rd; 7513 bits<5> Rn; 7514 let Inst{31-30} = 0b01; 7515 let Inst{29} = U; 7516 let Inst{28-24} = 0b11110; 7517 let Inst{23-22} = size; 7518 let Inst{21-17} = 0b10000; 7519 let Inst{16-12} = opcode; 7520 let Inst{11-10} = 0b10; 7521 let Inst{9-5} = Rn; 7522 let Inst{4-0} = Rd; 7523} 7524 7525 7526let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7527class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 7528 RegisterClass regtype, string asm, string zero> 7529 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 7530 "\t$Rd, $Rn, #" # zero, "", []>, 7531 Sched<[WriteVd]> { 7532 bits<5> Rd; 7533 bits<5> Rn; 7534 let Inst{31-30} = 0b01; 7535 let Inst{29} = U; 7536 let Inst{28-24} = 0b11110; 7537 let Inst{23-22} = size; 7538 let Inst{21} = 0b1; 7539 let Inst{20-19} = size2; 7540 let Inst{18-17} = 0b00; 7541 let Inst{16-12} = opcode; 7542 let Inst{11-10} = 0b10; 7543 let Inst{9-5} = Rn; 7544 let Inst{4-0} = Rd; 7545} 7546 7547let mayRaiseFPException = 1, Uses = [FPCR] in 7548class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 7549 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 7550 [(set (f32 FPR32:$Rd), (AArch64fcvtxnsdr (f64 FPR64:$Rn)))]>, 7551 Sched<[WriteVd]> { 7552 bits<5> Rd; 7553 bits<5> Rn; 7554 let Inst{31-17} = 0b011111100110000; 7555 let Inst{16-12} = opcode; 7556 let Inst{11-10} = 0b10; 7557 let Inst{9-5} = Rn; 7558 let Inst{4-0} = Rd; 7559} 7560 7561multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 7562 SDPatternOperator OpNode> { 7563 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 7564 7565 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 7566 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7567} 7568 7569multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 7570 SDPatternOperator OpNode> { 7571 let mayRaiseFPException = 1, Uses = [FPCR] in { 7572 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 7573 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 7574 let Predicates = [HasNEON, HasFullFP16] in { 7575 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 7576 } 7577 } 7578 7579 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7580 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 7581 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7582 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 7583 let Predicates = [HasNEON, HasFullFP16] in { 7584 def : InstAlias<asm # "\t$Rd, $Rn, #0", 7585 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 7586 } 7587 7588 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 7589 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 7590} 7591 7592multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 7593 SDPatternOperator OpNode = null_frag, 7594 list<Predicate> preds = []> { 7595 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7596 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 7597 7598 let Predicates = preds in { 7599 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 7600 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 7601 } 7602} 7603 7604let mayRaiseFPException = 1, Uses = [FPCR] in 7605multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 7606 let Predicates = [HasNEONandIsStreamingSafe] 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 = [HasNEONandIsStreamingSafe, 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 let Predicates = [HasNEONandIsStreamingSafe] in { 7619 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 7620 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 7621 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 7622 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 7623 } 7624 let Predicates = [HasNEONandIsStreamingSafe, HasFullFP16] in { 7625 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 7626 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>; 7627 } 7628} 7629 7630multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 7631 SDPatternOperator OpNode = null_frag> { 7632 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7633 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 7634 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 7635 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 7636 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 7637 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 7638 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 7639 } 7640 7641 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 7642 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 7643} 7644 7645multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 7646 Intrinsic OpNode> { 7647 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7648 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 7649 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 7650 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 7651 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 7652 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 7653 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 7654 } 7655 7656 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 7657 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 7658} 7659 7660 7661 7662let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7663multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 7664 SDPatternOperator OpNode = null_frag> { 7665 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 7666 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>; 7667 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 7668 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 7669} 7670 7671//---------------------------------------------------------------------------- 7672// AdvSIMD scalar pairwise instructions 7673//---------------------------------------------------------------------------- 7674 7675let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7676class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 7677 RegisterOperand regtype, RegisterOperand vectype, 7678 string asm, string kind> 7679 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7680 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 7681 Sched<[WriteVd]> { 7682 bits<5> Rd; 7683 bits<5> Rn; 7684 let Inst{31-30} = 0b01; 7685 let Inst{29} = U; 7686 let Inst{28-24} = 0b11110; 7687 let Inst{23-22} = size; 7688 let Inst{21-17} = 0b11000; 7689 let Inst{16-12} = opcode; 7690 let Inst{11-10} = 0b10; 7691 let Inst{9-5} = Rn; 7692 let Inst{4-0} = Rd; 7693} 7694 7695multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 7696 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 7697 asm, ".2d">; 7698} 7699 7700let mayRaiseFPException = 1, Uses = [FPCR] in 7701multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 7702 let Predicates = [HasNEON, HasFullFP16] in { 7703 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 7704 asm, ".2h">; 7705 } 7706 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 7707 asm, ".2s">; 7708 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 7709 asm, ".2d">; 7710} 7711 7712//---------------------------------------------------------------------------- 7713// AdvSIMD across lanes instructions 7714//---------------------------------------------------------------------------- 7715 7716let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7717class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 7718 RegisterClass regtype, RegisterOperand vectype, 7719 string asm, string kind, list<dag> pattern> 7720 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 7721 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 7722 Sched<[!if(Q, WriteVq, WriteVd)]> { 7723 bits<5> Rd; 7724 bits<5> Rn; 7725 let Inst{31} = 0; 7726 let Inst{30} = Q; 7727 let Inst{29} = U; 7728 let Inst{28-24} = 0b01110; 7729 let Inst{23-22} = size; 7730 let Inst{21-17} = 0b11000; 7731 let Inst{16-12} = opcode; 7732 let Inst{11-10} = 0b10; 7733 let Inst{9-5} = Rn; 7734 let Inst{4-0} = Rd; 7735} 7736 7737multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 7738 string asm> { 7739 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 7740 asm, ".8b", []>; 7741 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 7742 asm, ".16b", []>; 7743 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 7744 asm, ".4h", []>; 7745 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 7746 asm, ".8h", []>; 7747 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 7748 asm, ".4s", []>; 7749} 7750 7751multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 7752 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 7753 asm, ".8b", []>; 7754 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 7755 asm, ".16b", []>; 7756 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 7757 asm, ".4h", []>; 7758 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 7759 asm, ".8h", []>; 7760 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 7761 asm, ".4s", []>; 7762} 7763 7764let mayRaiseFPException = 1, Uses = [FPCR] in 7765multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 7766 SDPatternOperator intOp> { 7767 let Predicates = [HasNEON, HasFullFP16] in { 7768 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 7769 asm, ".4h", 7770 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>; 7771 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 7772 asm, ".8h", 7773 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>; 7774 } // Predicates = [HasNEON, HasFullFP16] 7775 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 7776 asm, ".4s", 7777 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 7778} 7779 7780//---------------------------------------------------------------------------- 7781// AdvSIMD INS/DUP instructions 7782//---------------------------------------------------------------------------- 7783 7784// FIXME: There has got to be a better way to factor these. ugh. 7785 7786class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 7787 string operands, string constraints, list<dag> pattern> 7788 : I<outs, ins, asm, operands, constraints, pattern>, 7789 Sched<[!if(Q, WriteVq, WriteVd)]> { 7790 bits<5> Rd; 7791 bits<5> Rn; 7792 let Inst{31} = 0; 7793 let Inst{30} = Q; 7794 let Inst{29} = op; 7795 let Inst{28-21} = 0b01110000; 7796 let Inst{15} = 0; 7797 let Inst{10} = 1; 7798 let Inst{9-5} = Rn; 7799 let Inst{4-0} = Rd; 7800} 7801 7802class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 7803 RegisterOperand vecreg, RegisterClass regtype> 7804 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 7805 "{\t$Rd" # size # ", $Rn" # 7806 "|" # size # "\t$Rd, $Rn}", "", 7807 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 7808 let Inst{20-16} = imm5; 7809 let Inst{14-11} = 0b0001; 7810} 7811 7812class SIMDDupFromElement<bit Q, string dstkind, string srckind, 7813 ValueType vectype, ValueType insreg, 7814 RegisterOperand vecreg, Operand idxtype, 7815 SDNode OpNode> 7816 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 7817 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 7818 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 7819 [(set (vectype vecreg:$Rd), 7820 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 7821 let Inst{14-11} = 0b0000; 7822} 7823 7824class SIMDDup64FromElement 7825 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 7826 VectorIndexD, AArch64duplane64> { 7827 bits<1> idx; 7828 let Inst{20} = idx; 7829 let Inst{19-16} = 0b1000; 7830} 7831 7832class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 7833 RegisterOperand vecreg> 7834 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 7835 VectorIndexS, AArch64duplane32> { 7836 bits<2> idx; 7837 let Inst{20-19} = idx; 7838 let Inst{18-16} = 0b100; 7839} 7840 7841class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 7842 RegisterOperand vecreg> 7843 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 7844 VectorIndexH, AArch64duplane16> { 7845 bits<3> idx; 7846 let Inst{20-18} = idx; 7847 let Inst{17-16} = 0b10; 7848} 7849 7850class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 7851 RegisterOperand vecreg> 7852 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 7853 VectorIndexB, AArch64duplane8> { 7854 bits<4> idx; 7855 let Inst{20-17} = idx; 7856 let Inst{16} = 1; 7857} 7858 7859class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 7860 Operand idxtype, string asm, list<dag> pattern> 7861 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 7862 "{\t$Rd, $Rn" # size # "$idx" # 7863 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 7864 let Inst{14-11} = imm4; 7865} 7866 7867class SIMDSMov<bit Q, string size, RegisterClass regtype, 7868 Operand idxtype> 7869 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 7870class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 7871 Operand idxtype> 7872 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 7873 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 7874 7875class SIMDMovAlias<string asm, string size, Instruction inst, 7876 RegisterClass regtype, Operand idxtype> 7877 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 7878 "|" # size # "\t$dst, $src$idx}", 7879 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 7880 7881multiclass SMov { 7882 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7883 // streaming mode. 7884 let Predicates = [HasNEONandIsStreamingSafe] in { 7885 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> { 7886 let Inst{20-16} = 0b00001; 7887 } 7888 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> { 7889 let Inst{20-16} = 0b00001; 7890 } 7891 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> { 7892 let Inst{20-16} = 0b00010; 7893 } 7894 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> { 7895 let Inst{20-16} = 0b00010; 7896 } 7897 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> { 7898 let Inst{20-16} = 0b00100; 7899 } 7900 } 7901 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 7902 bits<4> idx; 7903 let Inst{20-17} = idx; 7904 let Inst{16} = 1; 7905 } 7906 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 7907 bits<4> idx; 7908 let Inst{20-17} = idx; 7909 let Inst{16} = 1; 7910 } 7911 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 7912 bits<3> idx; 7913 let Inst{20-18} = idx; 7914 let Inst{17-16} = 0b10; 7915 } 7916 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 7917 bits<3> idx; 7918 let Inst{20-18} = idx; 7919 let Inst{17-16} = 0b10; 7920 } 7921 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 7922 bits<2> idx; 7923 let Inst{20-19} = idx; 7924 let Inst{18-16} = 0b100; 7925 } 7926} 7927 7928multiclass UMov { 7929 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME) 7930 // streaming mode. 7931 let Predicates = [HasNEONandIsStreamingSafe] in { 7932 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> { 7933 let Inst{20-16} = 0b00001; 7934 } 7935 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> { 7936 let Inst{20-16} = 0b00010; 7937 } 7938 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> { 7939 let Inst{20-16} = 0b00100; 7940 } 7941 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> { 7942 let Inst{20-16} = 0b01000; 7943 } 7944 def : SIMDMovAlias<"mov", ".s", 7945 !cast<Instruction>(NAME # vi32_idx0), 7946 GPR32, VectorIndex0>; 7947 def : SIMDMovAlias<"mov", ".d", 7948 !cast<Instruction>(NAME # vi64_idx0), 7949 GPR64, VectorIndex0>; 7950 } 7951 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 7952 bits<4> idx; 7953 let Inst{20-17} = idx; 7954 let Inst{16} = 1; 7955 } 7956 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 7957 bits<3> idx; 7958 let Inst{20-18} = idx; 7959 let Inst{17-16} = 0b10; 7960 } 7961 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 7962 bits<2> idx; 7963 let Inst{20-19} = idx; 7964 let Inst{18-16} = 0b100; 7965 } 7966 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 7967 bits<1> idx; 7968 let Inst{20} = idx; 7969 let Inst{19-16} = 0b1000; 7970 } 7971 def : SIMDMovAlias<"mov", ".s", 7972 !cast<Instruction>(NAME#"vi32"), 7973 GPR32, VectorIndexS>; 7974 def : SIMDMovAlias<"mov", ".d", 7975 !cast<Instruction>(NAME#"vi64"), 7976 GPR64, VectorIndexD>; 7977} 7978 7979class SIMDInsFromMain<string size, ValueType vectype, 7980 RegisterClass regtype, Operand idxtype> 7981 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 7982 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 7983 "{\t$Rd" # size # "$idx, $Rn" # 7984 "|" # size # "\t$Rd$idx, $Rn}", 7985 "$Rd = $dst", 7986 [(set V128:$dst, 7987 (vector_insert (vectype V128:$Rd), regtype:$Rn, (i64 idxtype:$idx)))]> { 7988 let Inst{14-11} = 0b0011; 7989} 7990 7991class SIMDInsFromElement<string size, ValueType vectype, 7992 ValueType elttype, Operand idxtype> 7993 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7994 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7995 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7996 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7997 "$Rd = $dst", 7998 [(set V128:$dst, 7999 (vector_insert 8000 (vectype V128:$Rd), 8001 (elttype (vector_extract (vectype V128:$Rn), (i64 idxtype:$idx2))), 8002 (i64 idxtype:$idx)))]>; 8003 8004class SIMDInsMainMovAlias<string size, Instruction inst, 8005 RegisterClass regtype, Operand idxtype> 8006 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 8007 "|" # size #"\t$dst$idx, $src}", 8008 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 8009class SIMDInsElementMovAlias<string size, Instruction inst, 8010 Operand idxtype> 8011 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" 8012 # "|" # size #"\t$dst$idx, $src$idx2}", 8013 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 8014 8015 8016multiclass SIMDIns { 8017 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 8018 bits<4> idx; 8019 let Inst{20-17} = idx; 8020 let Inst{16} = 1; 8021 } 8022 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 8023 bits<3> idx; 8024 let Inst{20-18} = idx; 8025 let Inst{17-16} = 0b10; 8026 } 8027 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 8028 bits<2> idx; 8029 let Inst{20-19} = idx; 8030 let Inst{18-16} = 0b100; 8031 } 8032 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 8033 bits<1> idx; 8034 let Inst{20} = idx; 8035 let Inst{19-16} = 0b1000; 8036 } 8037 8038 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 8039 bits<4> idx; 8040 bits<4> idx2; 8041 let Inst{20-17} = idx; 8042 let Inst{16} = 1; 8043 let Inst{14-11} = idx2; 8044 } 8045 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 8046 bits<3> idx; 8047 bits<3> idx2; 8048 let Inst{20-18} = idx; 8049 let Inst{17-16} = 0b10; 8050 let Inst{14-12} = idx2; 8051 let Inst{11} = {?}; 8052 } 8053 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 8054 bits<2> idx; 8055 bits<2> idx2; 8056 let Inst{20-19} = idx; 8057 let Inst{18-16} = 0b100; 8058 let Inst{14-13} = idx2; 8059 let Inst{12-11} = {?,?}; 8060 } 8061 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 8062 bits<1> idx; 8063 bits<1> idx2; 8064 let Inst{20} = idx; 8065 let Inst{19-16} = 0b1000; 8066 let Inst{14} = idx2; 8067 let Inst{13-11} = {?,?,?}; 8068 } 8069 8070 // For all forms of the INS instruction, the "mov" mnemonic is the 8071 // preferred alias. Why they didn't just call the instruction "mov" in 8072 // the first place is a very good question indeed... 8073 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 8074 GPR32, VectorIndexB>; 8075 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 8076 GPR32, VectorIndexH>; 8077 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 8078 GPR32, VectorIndexS>; 8079 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 8080 GPR64, VectorIndexD>; 8081 8082 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 8083 VectorIndexB>; 8084 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 8085 VectorIndexH>; 8086 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 8087 VectorIndexS>; 8088 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 8089 VectorIndexD>; 8090} 8091 8092//---------------------------------------------------------------------------- 8093// AdvSIMD TBL/TBX 8094//---------------------------------------------------------------------------- 8095 8096let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8097class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8098 RegisterOperand listtype, string asm, string kind> 8099 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 8100 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 8101 Sched<[!if(Q, WriteVq, WriteVd)]> { 8102 bits<5> Vd; 8103 bits<5> Vn; 8104 bits<5> Vm; 8105 let Inst{31} = 0; 8106 let Inst{30} = Q; 8107 let Inst{29-21} = 0b001110000; 8108 let Inst{20-16} = Vm; 8109 let Inst{15} = 0; 8110 let Inst{14-13} = len; 8111 let Inst{12} = op; 8112 let Inst{11-10} = 0b00; 8113 let Inst{9-5} = Vn; 8114 let Inst{4-0} = Vd; 8115} 8116 8117let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8118class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 8119 RegisterOperand listtype, string asm, string kind> 8120 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 8121 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 8122 Sched<[!if(Q, WriteVq, WriteVd)]> { 8123 bits<5> Vd; 8124 bits<5> Vn; 8125 bits<5> Vm; 8126 let Inst{31} = 0; 8127 let Inst{30} = Q; 8128 let Inst{29-21} = 0b001110000; 8129 let Inst{20-16} = Vm; 8130 let Inst{15} = 0; 8131 let Inst{14-13} = len; 8132 let Inst{12} = op; 8133 let Inst{11-10} = 0b00; 8134 let Inst{9-5} = Vn; 8135 let Inst{4-0} = Vd; 8136} 8137 8138class SIMDTableLookupAlias<string asm, Instruction inst, 8139 RegisterOperand vectype, RegisterOperand listtype> 8140 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 8141 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 8142 8143multiclass SIMDTableLookup<bit op, string asm> { 8144 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 8145 asm, ".8b">; 8146 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 8147 asm, ".8b">; 8148 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 8149 asm, ".8b">; 8150 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 8151 asm, ".8b">; 8152 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 8153 asm, ".16b">; 8154 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 8155 asm, ".16b">; 8156 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 8157 asm, ".16b">; 8158 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 8159 asm, ".16b">; 8160 8161 def : SIMDTableLookupAlias<asm # ".8b", 8162 !cast<Instruction>(NAME#"v8i8One"), 8163 V64, VecListOne128>; 8164 def : SIMDTableLookupAlias<asm # ".8b", 8165 !cast<Instruction>(NAME#"v8i8Two"), 8166 V64, VecListTwo128>; 8167 def : SIMDTableLookupAlias<asm # ".8b", 8168 !cast<Instruction>(NAME#"v8i8Three"), 8169 V64, VecListThree128>; 8170 def : SIMDTableLookupAlias<asm # ".8b", 8171 !cast<Instruction>(NAME#"v8i8Four"), 8172 V64, VecListFour128>; 8173 def : SIMDTableLookupAlias<asm # ".16b", 8174 !cast<Instruction>(NAME#"v16i8One"), 8175 V128, VecListOne128>; 8176 def : SIMDTableLookupAlias<asm # ".16b", 8177 !cast<Instruction>(NAME#"v16i8Two"), 8178 V128, VecListTwo128>; 8179 def : SIMDTableLookupAlias<asm # ".16b", 8180 !cast<Instruction>(NAME#"v16i8Three"), 8181 V128, VecListThree128>; 8182 def : SIMDTableLookupAlias<asm # ".16b", 8183 !cast<Instruction>(NAME#"v16i8Four"), 8184 V128, VecListFour128>; 8185} 8186 8187multiclass SIMDTableLookupTied<bit op, string asm> { 8188 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 8189 asm, ".8b">; 8190 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 8191 asm, ".8b">; 8192 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 8193 asm, ".8b">; 8194 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 8195 asm, ".8b">; 8196 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 8197 asm, ".16b">; 8198 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 8199 asm, ".16b">; 8200 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 8201 asm, ".16b">; 8202 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 8203 asm, ".16b">; 8204 8205 def : SIMDTableLookupAlias<asm # ".8b", 8206 !cast<Instruction>(NAME#"v8i8One"), 8207 V64, VecListOne128>; 8208 def : SIMDTableLookupAlias<asm # ".8b", 8209 !cast<Instruction>(NAME#"v8i8Two"), 8210 V64, VecListTwo128>; 8211 def : SIMDTableLookupAlias<asm # ".8b", 8212 !cast<Instruction>(NAME#"v8i8Three"), 8213 V64, VecListThree128>; 8214 def : SIMDTableLookupAlias<asm # ".8b", 8215 !cast<Instruction>(NAME#"v8i8Four"), 8216 V64, VecListFour128>; 8217 def : SIMDTableLookupAlias<asm # ".16b", 8218 !cast<Instruction>(NAME#"v16i8One"), 8219 V128, VecListOne128>; 8220 def : SIMDTableLookupAlias<asm # ".16b", 8221 !cast<Instruction>(NAME#"v16i8Two"), 8222 V128, VecListTwo128>; 8223 def : SIMDTableLookupAlias<asm # ".16b", 8224 !cast<Instruction>(NAME#"v16i8Three"), 8225 V128, VecListThree128>; 8226 def : SIMDTableLookupAlias<asm # ".16b", 8227 !cast<Instruction>(NAME#"v16i8Four"), 8228 V128, VecListFour128>; 8229} 8230 8231//---------------------------------------------------------------------------- 8232// AdvSIMD LUT 8233//---------------------------------------------------------------------------- 8234let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8235class BaseSIMDTableLookupIndexed<bit Q, bits<5> opc, RegisterOperand vectype, 8236 RegisterOperand listtype, Operand idx_type, 8237 string asm, string kind> 8238 : I<(outs vectype:$Rd), 8239 (ins listtype:$Rn, vectype:$Rm, idx_type:$idx), 8240 asm, "\t$Rd" # kind # ", $Rn, $Rm$idx", "", []>, 8241 Sched<[]> { 8242 bits<5> Rd; 8243 bits<5> Rn; 8244 bits<5> Rm; 8245 let Inst{31} = 0; 8246 let Inst{30} = Q; 8247 let Inst{29-24} = 0b001110; 8248 let Inst{23-22} = opc{4-3}; 8249 let Inst{21} = 0; 8250 let Inst{20-16} = Rm; 8251 let Inst{15} = 0; 8252 let Inst{14-12} = opc{2-0}; 8253 let Inst{11-10} = 0b00; 8254 let Inst{9-5} = Rn; 8255 let Inst{4-0} = Rd; 8256} 8257 8258multiclass BaseSIMDTableLookupIndexed2<string asm> { 8259 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, V128, VecListOne16b, VectorIndexS, asm, ".16b"> { 8260 bits<2> idx; 8261 let Inst{14-13} = idx; 8262 } 8263 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, V128, VecListOne8h, VectorIndexH, asm, ".8h" > { 8264 bits<3> idx; 8265 let Inst{14-12} = idx; 8266 } 8267} 8268 8269multiclass BaseSIMDTableLookupIndexed4<string asm> { 8270 def v16f8 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, V128, VecListOne16b, VectorIndexD, asm, ".16b"> { 8271 bit idx; 8272 let Inst{14} = idx; 8273 } 8274 def v8f16 : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, V128, VecListTwo8h, VectorIndexS, asm, ".8h" > { 8275 bits<2> idx; 8276 let Inst{14-13} = idx; 8277 } 8278} 8279 8280//---------------------------------------------------------------------------- 8281// AdvSIMD scalar DUP 8282//---------------------------------------------------------------------------- 8283let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8284class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype, 8285 string asm, string kind, Operand idxtype> 8286 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm, 8287 "{\t$dst, $src" # kind # "$idx" # 8288 "|\t$dst, $src$idx}", "", []>, 8289 Sched<[WriteVd]> { 8290 bits<5> dst; 8291 bits<5> src; 8292 let Inst{31-21} = 0b01011110000; 8293 let Inst{15-10} = 0b000001; 8294 let Inst{9-5} = src; 8295 let Inst{4-0} = dst; 8296} 8297 8298class SIMDScalarDUPAlias<string asm, string size, Instruction inst, 8299 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 8300 : InstAlias<asm # "{\t$dst, $src" # size # "$index" 8301 # "|\t$dst, $src$index}", 8302 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 8303 8304 8305multiclass SIMDScalarDUP<string asm> { 8306 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> { 8307 bits<4> idx; 8308 let Inst{20-17} = idx; 8309 let Inst{16} = 1; 8310 } 8311 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> { 8312 bits<3> idx; 8313 let Inst{20-18} = idx; 8314 let Inst{17-16} = 0b10; 8315 } 8316 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> { 8317 bits<2> idx; 8318 let Inst{20-19} = idx; 8319 let Inst{18-16} = 0b100; 8320 } 8321 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> { 8322 bits<1> idx; 8323 let Inst{20} = idx; 8324 let Inst{19-16} = 0b1000; 8325 } 8326 8327 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 8328 VectorIndexD:$idx)))), 8329 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 8330 8331 // 'DUP' mnemonic aliases. 8332 def : SIMDScalarDUPAlias<"dup", ".b", 8333 !cast<Instruction>(NAME#"i8"), 8334 FPR8, V128, VectorIndexB>; 8335 def : SIMDScalarDUPAlias<"dup", ".h", 8336 !cast<Instruction>(NAME#"i16"), 8337 FPR16, V128, VectorIndexH>; 8338 def : SIMDScalarDUPAlias<"dup", ".s", 8339 !cast<Instruction>(NAME#"i32"), 8340 FPR32, V128, VectorIndexS>; 8341 def : SIMDScalarDUPAlias<"dup", ".d", 8342 !cast<Instruction>(NAME#"i64"), 8343 FPR64, V128, VectorIndexD>; 8344} 8345 8346//---------------------------------------------------------------------------- 8347// AdvSIMD modified immediate instructions 8348//---------------------------------------------------------------------------- 8349 8350class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 8351 string asm, string op_string, 8352 string cstr, list<dag> pattern> 8353 : I<oops, iops, asm, op_string, cstr, pattern>, 8354 Sched<[!if(Q, WriteVq, WriteVd)]> { 8355 bits<5> Rd; 8356 bits<8> imm8; 8357 let Inst{31} = 0; 8358 let Inst{30} = Q; 8359 let Inst{29} = op; 8360 let Inst{28-19} = 0b0111100000; 8361 let Inst{18-16} = imm8{7-5}; 8362 let Inst{11} = op2; 8363 let Inst{10} = 1; 8364 let Inst{9-5} = imm8{4-0}; 8365 let Inst{4-0} = Rd; 8366} 8367 8368class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 8369 Operand immtype, dag opt_shift_iop, 8370 string opt_shift, string asm, string kind, 8371 list<dag> pattern> 8372 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 8373 !con((ins immtype:$imm8), opt_shift_iop), asm, 8374 "{\t$Rd" # kind # ", $imm8" # opt_shift # 8375 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8376 "", pattern> { 8377 let DecoderMethod = "DecodeModImmInstruction"; 8378} 8379 8380class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 8381 Operand immtype, dag opt_shift_iop, 8382 string opt_shift, string asm, string kind, 8383 list<dag> pattern> 8384 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 8385 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 8386 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 8387 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 8388 "$Rd = $dst", pattern> { 8389 let DecoderMethod = "DecodeModImmTiedInstruction"; 8390} 8391 8392class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 8393 RegisterOperand vectype, string asm, 8394 string kind, list<dag> pattern> 8395 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8396 (ins logical_vec_shift:$shift), 8397 "$shift", asm, kind, pattern> { 8398 bits<2> shift; 8399 let Inst{15} = b15_b12{1}; 8400 let Inst{14-13} = shift; 8401 let Inst{12} = b15_b12{0}; 8402} 8403 8404class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 8405 RegisterOperand vectype, string asm, 8406 string kind, list<dag> pattern> 8407 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8408 (ins logical_vec_shift:$shift), 8409 "$shift", asm, kind, pattern> { 8410 bits<2> shift; 8411 let Inst{15} = b15_b12{1}; 8412 let Inst{14-13} = shift; 8413 let Inst{12} = b15_b12{0}; 8414} 8415 8416 8417class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 8418 RegisterOperand vectype, string asm, 8419 string kind, list<dag> pattern> 8420 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8421 (ins logical_vec_hw_shift:$shift), 8422 "$shift", asm, kind, pattern> { 8423 bits<2> shift; 8424 let Inst{15} = b15_b12{1}; 8425 let Inst{14} = 0; 8426 let Inst{13} = shift{0}; 8427 let Inst{12} = b15_b12{0}; 8428} 8429 8430class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 8431 RegisterOperand vectype, string asm, 8432 string kind, list<dag> pattern> 8433 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 8434 (ins logical_vec_hw_shift:$shift), 8435 "$shift", asm, kind, pattern> { 8436 bits<2> shift; 8437 let Inst{15} = b15_b12{1}; 8438 let Inst{14} = 0; 8439 let Inst{13} = shift{0}; 8440 let Inst{12} = b15_b12{0}; 8441} 8442 8443multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 8444 string asm> { 8445 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 8446 asm, ".4h", []>; 8447 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 8448 asm, ".8h", []>; 8449 8450 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 8451 asm, ".2s", []>; 8452 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 8453 asm, ".4s", []>; 8454} 8455 8456multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 8457 bits<2> w_cmode, string asm, 8458 SDNode OpNode> { 8459 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 8460 asm, ".4h", 8461 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 8462 imm0_255:$imm8, 8463 (i32 imm:$shift)))]>; 8464 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 8465 asm, ".8h", 8466 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 8467 imm0_255:$imm8, 8468 (i32 imm:$shift)))]>; 8469 8470 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 8471 asm, ".2s", 8472 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 8473 imm0_255:$imm8, 8474 (i32 imm:$shift)))]>; 8475 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 8476 asm, ".4s", 8477 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 8478 imm0_255:$imm8, 8479 (i32 imm:$shift)))]>; 8480} 8481 8482class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 8483 RegisterOperand vectype, string asm, 8484 string kind, list<dag> pattern> 8485 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 8486 (ins move_vec_shift:$shift), 8487 "$shift", asm, kind, pattern> { 8488 bits<1> shift; 8489 let Inst{15-13} = cmode{3-1}; 8490 let Inst{12} = shift; 8491} 8492 8493class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 8494 RegisterOperand vectype, 8495 Operand imm_type, string asm, 8496 string kind, list<dag> pattern> 8497 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 8498 asm, kind, pattern> { 8499 let Inst{15-12} = cmode; 8500} 8501 8502class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 8503 list<dag> pattern> 8504 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 8505 "\t$Rd, $imm8", "", pattern> { 8506 let Inst{15-12} = cmode; 8507 let DecoderMethod = "DecodeModImmInstruction"; 8508} 8509 8510//---------------------------------------------------------------------------- 8511// AdvSIMD indexed element 8512//---------------------------------------------------------------------------- 8513 8514let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8515class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8516 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8517 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8518 string apple_kind, string dst_kind, string lhs_kind, 8519 string rhs_kind, list<dag> pattern> 8520 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 8521 asm, 8522 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8523 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 8524 Sched<[WriteVd]> { 8525 bits<5> Rd; 8526 bits<5> Rn; 8527 bits<5> Rm; 8528 8529 let Inst{31} = 0; 8530 let Inst{30} = Q; 8531 let Inst{29} = U; 8532 let Inst{28} = Scalar; 8533 let Inst{27-24} = 0b1111; 8534 let Inst{23-22} = size; 8535 // Bit 21 must be set by the derived class. 8536 let Inst{20-16} = Rm; 8537 let Inst{15-12} = opc; 8538 // Bit 11 must be set by the derived class. 8539 let Inst{10} = 0; 8540 let Inst{9-5} = Rn; 8541 let Inst{4-0} = Rd; 8542} 8543 8544let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8545class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 8546 RegisterOperand dst_reg, RegisterOperand lhs_reg, 8547 RegisterOperand rhs_reg, Operand vec_idx, string asm, 8548 string apple_kind, string dst_kind, string lhs_kind, 8549 string rhs_kind, list<dag> pattern> 8550 : I<(outs dst_reg:$dst), 8551 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 8552 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 8553 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 8554 Sched<[WriteVd]> { 8555 bits<5> Rd; 8556 bits<5> Rn; 8557 bits<5> Rm; 8558 8559 let Inst{31} = 0; 8560 let Inst{30} = Q; 8561 let Inst{29} = U; 8562 let Inst{28} = Scalar; 8563 let Inst{27-24} = 0b1111; 8564 let Inst{23-22} = size; 8565 // Bit 21 must be set by the derived class. 8566 let Inst{20-16} = Rm; 8567 let Inst{15-12} = opc; 8568 // Bit 11 must be set by the derived class. 8569 let Inst{10} = 0; 8570 let Inst{9-5} = Rn; 8571 let Inst{4-0} = Rd; 8572} 8573 8574 8575//---------------------------------------------------------------------------- 8576// Armv8.6 BFloat16 Extension 8577//---------------------------------------------------------------------------- 8578let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in { 8579 8580class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1, 8581 string kind2, RegisterOperand RegType, 8582 ValueType AccumType, ValueType InputType> 8583 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst), 8584 (int_aarch64_neon_bfdot (AccumType RegType:$Rd), 8585 (InputType RegType:$Rn), 8586 (InputType RegType:$Rm)))]> { 8587 let AsmString = !strconcat(asm, 8588 "{\t$Rd" # kind1 # ", $Rn" # kind2 # 8589 ", $Rm" # kind2 # "}"); 8590} 8591 8592multiclass SIMDThreeSameVectorBFDot<bit U, string asm> { 8593 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64, 8594 v2f32, v4bf16>; 8595 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128, 8596 v4f32, v8bf16>; 8597} 8598 8599class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm, 8600 string dst_kind, string lhs_kind, 8601 string rhs_kind, 8602 RegisterOperand RegType, 8603 ValueType AccumType, 8604 ValueType InputType> 8605 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111, 8606 RegType, RegType, V128, VectorIndexS, 8607 asm, "", dst_kind, lhs_kind, rhs_kind, 8608 [(set (AccumType RegType:$dst), 8609 (AccumType (int_aarch64_neon_bfdot 8610 (AccumType RegType:$Rd), 8611 (InputType RegType:$Rn), 8612 (InputType (bitconvert (AccumType 8613 (AArch64duplane32 (v4f32 V128:$Rm), 8614 VectorIndexS:$idx)))))))]> { 8615 8616 bits<2> idx; 8617 let Inst{21} = idx{0}; // L 8618 let Inst{11} = idx{1}; // H 8619} 8620 8621multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> { 8622 8623 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h", 8624 ".2h", V64, v2f32, v4bf16>; 8625 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h", 8626 ".2h", V128, v4f32, v8bf16>; 8627} 8628 8629let mayRaiseFPException = 1, Uses = [FPCR] in 8630class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode> 8631 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s", 8632 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 8633 (v8bf16 V128:$Rn), 8634 (v8bf16 V128:$Rm)))]> { 8635 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h}"); 8636} 8637 8638let mayRaiseFPException = 1, Uses = [FPCR] in 8639class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode> 8640 : I<(outs V128:$dst), 8641 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm, 8642 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst", 8643 [(set (v4f32 V128:$dst), 8644 (v4f32 (OpNode (v4f32 V128:$Rd), 8645 (v8bf16 V128:$Rn), 8646 (v8bf16 8647 (AArch64duplane16 (v8bf16 V128_lo:$Rm), 8648 VectorIndexH:$idx)))))]>, 8649 Sched<[WriteVq]> { 8650 bits<5> Rd; 8651 bits<5> Rn; 8652 bits<4> Rm; 8653 bits<3> idx; 8654 8655 let Inst{31} = 0; 8656 let Inst{30} = Q; 8657 let Inst{29-22} = 0b00111111; 8658 let Inst{21-20} = idx{1-0}; 8659 let Inst{19-16} = Rm; 8660 let Inst{15-12} = 0b1111; 8661 let Inst{11} = idx{2}; // H 8662 let Inst{10} = 0; 8663 let Inst{9-5} = Rn; 8664 let Inst{4-0} = Rd; 8665} 8666 8667class SIMDThreeSameVectorBF16MatrixMul<string asm> 8668 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101, 8669 V128, asm, ".4s", 8670 [(set (v4f32 V128:$dst), 8671 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd), 8672 (v8bf16 V128:$Rn), 8673 (v8bf16 V128:$Rm)))]> { 8674 let AsmString = !strconcat(asm, "{\t$Rd", ".4s", ", $Rn", ".8h", 8675 ", $Rm", ".8h", "}"); 8676} 8677 8678let mayRaiseFPException = 1, Uses = [FPCR] in 8679class SIMD_BFCVTN 8680 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V128, 8681 "bfcvtn", ".4h", ".4s", 8682 [(set (v8bf16 V128:$Rd), 8683 (int_aarch64_neon_bfcvtn (v4f32 V128:$Rn)))]>; 8684 8685let mayRaiseFPException = 1, Uses = [FPCR] in 8686class SIMD_BFCVTN2 8687 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128, 8688 "bfcvtn2", ".8h", ".4s", 8689 [(set (v8bf16 V128:$dst), 8690 (int_aarch64_neon_bfcvtn2 (v8bf16 V128:$Rd), (v4f32 V128:$Rn)))]>; 8691 8692let mayRaiseFPException = 1, Uses = [FPCR] in 8693class BF16ToSinglePrecision<string asm> 8694 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "", 8695 [(set (bf16 FPR16:$Rd), (int_aarch64_neon_bfcvt (f32 FPR32:$Rn)))]>, 8696 Sched<[WriteFCvt]> { 8697 bits<5> Rd; 8698 bits<5> Rn; 8699 let Inst{31-10} = 0b0001111001100011010000; 8700 let Inst{9-5} = Rn; 8701 let Inst{4-0} = Rd; 8702} 8703} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0 8704 8705//---------------------------------------------------------------------------- 8706class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc, 8707 string asm, string dst_kind, 8708 RegisterOperand RegType, 8709 RegisterOperand RegType_lo> 8710 : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc, 8711 RegType, RegType, RegType_lo, VectorIndexB, 8712 asm, "", dst_kind, ".16b", ".b", []> { 8713 8714 // idx = H:L:M 8715 bits<4> idx; 8716 let Inst{11} = idx{3}; 8717 let Inst{21-19} = idx{2-0}; 8718} 8719 8720multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm> { 8721 def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h", 8722 V128, V128_0to7>; 8723} 8724 8725multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm> { 8726 def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s", 8727 V128, V128_0to7>; 8728} 8729 8730//---------------------------------------------------------------------------- 8731// Armv8.6 Matrix Multiply Extension 8732//---------------------------------------------------------------------------- 8733 8734class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode> 8735 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s", 8736 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 8737 (v16i8 V128:$Rn), 8738 (v16i8 V128:$Rm)))]> { 8739 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b}"; 8740} 8741 8742//---------------------------------------------------------------------------- 8743// ARMv8.2-A Dot Product Instructions (Indexed) 8744class BaseSIMDThreeSameVectorIndexS<bit Q, bit U, bits<2> size, bits<4> opc, string asm, 8745 string dst_kind, string lhs_kind, string rhs_kind, 8746 RegisterOperand RegType, 8747 ValueType AccumType, ValueType InputType, 8748 SDPatternOperator OpNode> : 8749 BaseSIMDIndexedTied<Q, U, 0b0, size, opc, RegType, RegType, V128, 8750 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 8751 [(set (AccumType RegType:$dst), 8752 (AccumType (OpNode (AccumType RegType:$Rd), 8753 (InputType RegType:$Rn), 8754 (InputType (bitconvert (AccumType 8755 (AArch64duplane32 (v4i32 V128:$Rm), 8756 VectorIndexS:$idx)))))))]> { 8757 bits<2> idx; 8758 let Inst{21} = idx{0}; // L 8759 let Inst{11} = idx{1}; // H 8760} 8761 8762multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm, 8763 SDPatternOperator OpNode> { 8764 def v8i8 : BaseSIMDThreeSameVectorIndexS<0, U, size, {0b111, Mixed}, asm, ".2s", ".8b", ".4b", 8765 V64, v2i32, v8i8, OpNode>; 8766 def v16i8 : BaseSIMDThreeSameVectorIndexS<1, U, size, {0b111, Mixed}, asm, ".4s", ".16b", ".4b", 8767 V128, v4i32, v16i8, OpNode>; 8768} 8769 8770// TODO: The vectors v8i8 and v16i8 should be v8f8 and v16f8 8771multiclass SIMDThreeSameVectorFP8DOT4Index<string asm> { 8772 def v8f8 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b00, 0b0000, asm, ".2s", ".8b", ".4b", 8773 V64, v2f32, v8i8, null_frag>; 8774 def v16f8 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b00, 0b0000, asm, ".4s", ".16b",".4b", 8775 V128, v4f32, v16i8, null_frag>; 8776} 8777 8778// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 8779let mayRaiseFPException = 1, Uses = [FPCR] in 8780class BaseSIMDThreeSameVectorIndexH<bit Q, bit U, bits<2> sz, bits<4> opc, string asm, 8781 string dst_kind, string lhs_kind, 8782 string rhs_kind, RegisterOperand RegType, 8783 RegisterOperand RegType_lo, ValueType AccumType, 8784 ValueType InputType, SDPatternOperator OpNode> : 8785 BaseSIMDIndexedTied<Q, U, 0, sz, opc, RegType, RegType, RegType_lo, 8786 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 8787 [(set (AccumType RegType:$dst), 8788 (AccumType (OpNode (AccumType RegType:$Rd), 8789 (InputType RegType:$Rn), 8790 (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm), 8791 VectorIndexH:$idx)))))]> { 8792 // idx = H:L:M 8793 bits<3> idx; 8794 let Inst{11} = idx{2}; // H 8795 let Inst{21} = idx{1}; // L 8796 let Inst{20} = idx{0}; // M 8797} 8798 8799multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 8800 SDPatternOperator OpNode> { 8801 def v4f16 : BaseSIMDThreeSameVectorIndexH<0, U, 0b10, opc, asm, ".2s", ".2h", ".h", 8802 V64, V128_lo, v2f32, v4f16, OpNode>; 8803 def v8f16 : BaseSIMDThreeSameVectorIndexH<1, U, 0b10, opc, asm, ".4s", ".4h", ".h", 8804 V128, V128_lo, v4f32, v8f16, OpNode>; 8805} 8806 8807//---------------------------------------------------------------------------- 8808// FP8 Advanced SIMD vector x indexed element 8809// TODO: Replace value types v8i8 and v16i8 by v8f8 and v16f8 8810multiclass SIMDThreeSameVectorFP8DOT2Index<string asm> { 8811 def v4f16 : BaseSIMDThreeSameVectorIndexH<0b0, 0b0, 0b01, 0b0000, asm, ".4h", ".8b", ".2b", 8812 V64, V128_lo, v4f16, v8i8, null_frag>; 8813 def v8f16 : BaseSIMDThreeSameVectorIndexH<0b1, 0b0, 0b01, 0b0000, asm, ".8h", ".16b", ".2b", 8814 V128, V128_lo, v8f16, v8i16, null_frag>; 8815} 8816 8817multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 8818 SDPatternOperator OpNode> { 8819 let mayRaiseFPException = 1, Uses = [FPCR] in { 8820 let Predicates = [HasNEON, HasFullFP16] in { 8821 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 8822 V64, V64, 8823 V128_lo, VectorIndexH, 8824 asm, ".4h", ".4h", ".4h", ".h", 8825 [(set (v4f16 V64:$Rd), 8826 (OpNode (v4f16 V64:$Rn), 8827 (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 8828 bits<3> idx; 8829 let Inst{11} = idx{2}; 8830 let Inst{21} = idx{1}; 8831 let Inst{20} = idx{0}; 8832 } 8833 8834 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 8835 V128, V128, 8836 V128_lo, VectorIndexH, 8837 asm, ".8h", ".8h", ".8h", ".h", 8838 [(set (v8f16 V128:$Rd), 8839 (OpNode (v8f16 V128:$Rn), 8840 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8841 bits<3> idx; 8842 let Inst{11} = idx{2}; 8843 let Inst{21} = idx{1}; 8844 let Inst{20} = idx{0}; 8845 } 8846 } // Predicates = [HasNEON, HasFullFP16] 8847 8848 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8849 V64, V64, 8850 V128, VectorIndexS, 8851 asm, ".2s", ".2s", ".2s", ".s", 8852 [(set (v2f32 V64:$Rd), 8853 (OpNode (v2f32 V64:$Rn), 8854 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> { 8855 bits<2> idx; 8856 let Inst{11} = idx{1}; 8857 let Inst{21} = idx{0}; 8858 } 8859 8860 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8861 V128, V128, 8862 V128, VectorIndexS, 8863 asm, ".4s", ".4s", ".4s", ".s", 8864 [(set (v4f32 V128:$Rd), 8865 (OpNode (v4f32 V128:$Rn), 8866 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 8867 bits<2> idx; 8868 let Inst{11} = idx{1}; 8869 let Inst{21} = idx{0}; 8870 } 8871 8872 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 8873 V128, V128, 8874 V128, VectorIndexD, 8875 asm, ".2d", ".2d", ".2d", ".d", 8876 [(set (v2f64 V128:$Rd), 8877 (OpNode (v2f64 V128:$Rn), 8878 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 8879 bits<1> idx; 8880 let Inst{11} = idx{0}; 8881 let Inst{21} = 0; 8882 } 8883 8884 let Predicates = [HasNEON, HasFullFP16] in { 8885 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 8886 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 8887 asm, ".h", "", "", ".h", 8888 [(set (f16 FPR16Op:$Rd), 8889 (OpNode (f16 FPR16Op:$Rn), 8890 (f16 (vector_extract (v8f16 V128_lo:$Rm), 8891 VectorIndexH:$idx))))]> { 8892 bits<3> idx; 8893 let Inst{11} = idx{2}; 8894 let Inst{21} = idx{1}; 8895 let Inst{20} = idx{0}; 8896 } 8897 } // Predicates = [HasNEON, HasFullFP16] 8898 8899 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8900 FPR32Op, FPR32Op, V128, VectorIndexS, 8901 asm, ".s", "", "", ".s", 8902 [(set (f32 FPR32Op:$Rd), 8903 (OpNode (f32 FPR32Op:$Rn), 8904 (f32 (vector_extract (v4f32 V128:$Rm), 8905 VectorIndexS:$idx))))]> { 8906 bits<2> idx; 8907 let Inst{11} = idx{1}; 8908 let Inst{21} = idx{0}; 8909 } 8910 8911 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 8912 FPR64Op, FPR64Op, V128, VectorIndexD, 8913 asm, ".d", "", "", ".d", 8914 [(set (f64 FPR64Op:$Rd), 8915 (OpNode (f64 FPR64Op:$Rn), 8916 (f64 (vector_extract (v2f64 V128:$Rm), 8917 VectorIndexD:$idx))))]> { 8918 bits<1> idx; 8919 let Inst{11} = idx{0}; 8920 let Inst{21} = 0; 8921 } 8922 } // mayRaiseFPException = 1, Uses = [FPCR] 8923 8924 let Predicates = [HasNEON, HasFullFP16] in { 8925 def : Pat<(f16 (OpNode 8926 (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))), 8927 (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))), 8928 (!cast<Instruction>(NAME # v1i16_indexed) 8929 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128:$Rm, VectorIndexH:$idx)>; 8930 } 8931 8932 let Predicates = [HasNEON] in { 8933 def : Pat<(f32 (OpNode 8934 (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))), 8935 (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))), 8936 (!cast<Instruction>(NAME # v1i32_indexed) 8937 (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>; 8938 8939 def : Pat<(f64 (OpNode 8940 (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))), 8941 (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))), 8942 (!cast<Instruction>(NAME # v1i64_indexed) 8943 (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>; 8944 } 8945} 8946 8947multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 8948 let Predicates = [HasNEON, HasFullFP16] in { 8949 // Patterns for f16: DUPLANE, DUP scalar and vector_extract. 8950 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8951 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8952 VectorIndexH:$idx))), 8953 (!cast<Instruction>(INST # "v8i16_indexed") 8954 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8955 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), 8956 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8957 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn, 8958 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8959 8960 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8961 (AArch64duplane16 (v8f16 V128_lo:$Rm), 8962 VectorIndexH:$idx))), 8963 (!cast<Instruction>(INST # "v4i16_indexed") 8964 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>; 8965 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), 8966 (AArch64dup (f16 FPR16Op_lo:$Rm)))), 8967 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn, 8968 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>; 8969 8970 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn), 8971 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))), 8972 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn, 8973 V128_lo:$Rm, VectorIndexH:$idx)>; 8974 } // Predicates = [HasNEON, HasFullFP16] 8975 8976 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 8977 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8978 (AArch64duplane32 (v4f32 V128:$Rm), 8979 VectorIndexS:$idx))), 8980 (!cast<Instruction>(INST # v2i32_indexed) 8981 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8982 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 8983 (AArch64dup (f32 FPR32Op:$Rm)))), 8984 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 8985 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8986 8987 8988 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 8989 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8990 (AArch64duplane32 (v4f32 V128:$Rm), 8991 VectorIndexS:$idx))), 8992 (!cast<Instruction>(INST # "v4i32_indexed") 8993 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 8994 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 8995 (AArch64dup (f32 FPR32Op:$Rm)))), 8996 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 8997 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 8998 8999 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 9000 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 9001 (AArch64duplane64 (v2f64 V128:$Rm), 9002 VectorIndexD:$idx))), 9003 (!cast<Instruction>(INST # "v2i64_indexed") 9004 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 9005 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 9006 (AArch64dup (f64 FPR64Op:$Rm)))), 9007 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 9008 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 9009 9010 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s 9011 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 9012 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 9013 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 9014 V128:$Rm, VectorIndexS:$idx)>; 9015 9016 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 9017 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 9018 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 9019 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 9020 V128:$Rm, VectorIndexD:$idx)>; 9021} 9022 9023let mayRaiseFPException = 1, Uses = [FPCR] in 9024multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 9025 let Predicates = [HasNEON, HasFullFP16] in { 9026 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 9027 V128_lo, VectorIndexH, 9028 asm, ".4h", ".4h", ".4h", ".h", []> { 9029 bits<3> idx; 9030 let Inst{11} = idx{2}; 9031 let Inst{21} = idx{1}; 9032 let Inst{20} = idx{0}; 9033 } 9034 9035 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 9036 V128, V128, 9037 V128_lo, VectorIndexH, 9038 asm, ".8h", ".8h", ".8h", ".h", []> { 9039 bits<3> idx; 9040 let Inst{11} = idx{2}; 9041 let Inst{21} = idx{1}; 9042 let Inst{20} = idx{0}; 9043 } 9044 } // Predicates = [HasNEON, HasFullFP16] 9045 9046 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 9047 V128, VectorIndexS, 9048 asm, ".2s", ".2s", ".2s", ".s", []> { 9049 bits<2> idx; 9050 let Inst{11} = idx{1}; 9051 let Inst{21} = idx{0}; 9052 } 9053 9054 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9055 V128, V128, 9056 V128, VectorIndexS, 9057 asm, ".4s", ".4s", ".4s", ".s", []> { 9058 bits<2> idx; 9059 let Inst{11} = idx{1}; 9060 let Inst{21} = idx{0}; 9061 } 9062 9063 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 9064 V128, V128, 9065 V128, VectorIndexD, 9066 asm, ".2d", ".2d", ".2d", ".d", []> { 9067 bits<1> idx; 9068 let Inst{11} = idx{0}; 9069 let Inst{21} = 0; 9070 } 9071 9072 let Predicates = [HasNEON, HasFullFP16] in { 9073 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 9074 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9075 asm, ".h", "", "", ".h", []> { 9076 bits<3> idx; 9077 let Inst{11} = idx{2}; 9078 let Inst{21} = idx{1}; 9079 let Inst{20} = idx{0}; 9080 } 9081 } // Predicates = [HasNEON, HasFullFP16] 9082 9083 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9084 FPR32Op, FPR32Op, V128, VectorIndexS, 9085 asm, ".s", "", "", ".s", []> { 9086 bits<2> idx; 9087 let Inst{11} = idx{1}; 9088 let Inst{21} = idx{0}; 9089 } 9090 9091 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 9092 FPR64Op, FPR64Op, V128, VectorIndexD, 9093 asm, ".d", "", "", ".d", []> { 9094 bits<1> idx; 9095 let Inst{11} = idx{0}; 9096 let Inst{21} = 0; 9097 } 9098} 9099 9100multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane, 9101 SDPatternOperator OpNodeLaneQ> { 9102 9103 def : Pat<(v4i16 (OpNodeLane 9104 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm), 9105 VectorIndexS32b:$idx)), 9106 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, 9107 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub), 9108 (UImmS1XForm $idx))>; 9109 9110 def : Pat<(v4i16 (OpNodeLaneQ 9111 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm), 9112 VectorIndexH32b:$idx)), 9113 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm, 9114 (UImmS1XForm $idx))>; 9115 9116 def : Pat<(v8i16 (OpNodeLane 9117 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm), 9118 VectorIndexS32b:$idx)), 9119 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, 9120 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9121 (UImmS1XForm $idx))>; 9122 9123 def : Pat<(v8i16 (OpNodeLaneQ 9124 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm), 9125 VectorIndexH32b:$idx)), 9126 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm, 9127 (UImmS1XForm $idx))>; 9128 9129 def : Pat<(v2i32 (OpNodeLane 9130 (v2i32 V64:$Rn), (v2i32 V64:$Rm), 9131 VectorIndexD32b:$idx)), 9132 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, 9133 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub), 9134 (UImmS1XForm $idx))>; 9135 9136 def : Pat<(v2i32 (OpNodeLaneQ 9137 (v2i32 V64:$Rn), (v4i32 V128:$Rm), 9138 VectorIndexS32b:$idx)), 9139 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm, 9140 (UImmS1XForm $idx))>; 9141 9142 def : Pat<(v4i32 (OpNodeLane 9143 (v4i32 V128:$Rn), (v2i32 V64:$Rm), 9144 VectorIndexD32b:$idx)), 9145 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, 9146 (SUBREG_TO_REG (i32 0), $Rm, dsub), 9147 (UImmS1XForm $idx))>; 9148 9149 def : Pat<(v4i32 (OpNodeLaneQ 9150 (v4i32 V128:$Rn), 9151 (v4i32 V128:$Rm), 9152 VectorIndexS32b:$idx)), 9153 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm, 9154 (UImmS1XForm $idx))>; 9155 9156} 9157 9158multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 9159 SDPatternOperator OpNode> { 9160 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 9161 V128_lo, VectorIndexH, 9162 asm, ".4h", ".4h", ".4h", ".h", 9163 [(set (v4i16 V64:$Rd), 9164 (OpNode (v4i16 V64:$Rn), 9165 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9166 bits<3> idx; 9167 let Inst{11} = idx{2}; 9168 let Inst{21} = idx{1}; 9169 let Inst{20} = idx{0}; 9170 } 9171 9172 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9173 V128, V128, 9174 V128_lo, VectorIndexH, 9175 asm, ".8h", ".8h", ".8h", ".h", 9176 [(set (v8i16 V128:$Rd), 9177 (OpNode (v8i16 V128:$Rn), 9178 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9179 bits<3> idx; 9180 let Inst{11} = idx{2}; 9181 let Inst{21} = idx{1}; 9182 let Inst{20} = idx{0}; 9183 } 9184 9185 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9186 V64, V64, 9187 V128, VectorIndexS, 9188 asm, ".2s", ".2s", ".2s", ".s", 9189 [(set (v2i32 V64:$Rd), 9190 (OpNode (v2i32 V64:$Rn), 9191 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9192 bits<2> idx; 9193 let Inst{11} = idx{1}; 9194 let Inst{21} = idx{0}; 9195 } 9196 9197 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9198 V128, V128, 9199 V128, VectorIndexS, 9200 asm, ".4s", ".4s", ".4s", ".s", 9201 [(set (v4i32 V128:$Rd), 9202 (OpNode (v4i32 V128:$Rn), 9203 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9204 bits<2> idx; 9205 let Inst{11} = idx{1}; 9206 let Inst{21} = idx{0}; 9207 } 9208 9209 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9210 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 9211 asm, ".h", "", "", ".h", []> { 9212 bits<3> idx; 9213 let Inst{11} = idx{2}; 9214 let Inst{21} = idx{1}; 9215 let Inst{20} = idx{0}; 9216 } 9217 9218 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9219 FPR32Op, FPR32Op, V128, VectorIndexS, 9220 asm, ".s", "", "", ".s", 9221 [(set (i32 FPR32Op:$Rd), 9222 (OpNode FPR32Op:$Rn, 9223 (i32 (vector_extract (v4i32 V128:$Rm), 9224 VectorIndexS:$idx))))]> { 9225 bits<2> idx; 9226 let Inst{11} = idx{1}; 9227 let Inst{21} = idx{0}; 9228 } 9229} 9230 9231multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 9232 SDPatternOperator OpNode> { 9233 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9234 V64, V64, 9235 V128_lo, VectorIndexH, 9236 asm, ".4h", ".4h", ".4h", ".h", 9237 [(set (v4i16 V64:$Rd), 9238 (OpNode (v4i16 V64:$Rn), 9239 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9240 bits<3> idx; 9241 let Inst{11} = idx{2}; 9242 let Inst{21} = idx{1}; 9243 let Inst{20} = idx{0}; 9244 } 9245 9246 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9247 V128, V128, 9248 V128_lo, VectorIndexH, 9249 asm, ".8h", ".8h", ".8h", ".h", 9250 [(set (v8i16 V128:$Rd), 9251 (OpNode (v8i16 V128:$Rn), 9252 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9253 bits<3> idx; 9254 let Inst{11} = idx{2}; 9255 let Inst{21} = idx{1}; 9256 let Inst{20} = idx{0}; 9257 } 9258 9259 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9260 V64, V64, 9261 V128, VectorIndexS, 9262 asm, ".2s", ".2s", ".2s", ".s", 9263 [(set (v2i32 V64:$Rd), 9264 (OpNode (v2i32 V64:$Rn), 9265 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9266 bits<2> idx; 9267 let Inst{11} = idx{1}; 9268 let Inst{21} = idx{0}; 9269 } 9270 9271 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9272 V128, V128, 9273 V128, VectorIndexS, 9274 asm, ".4s", ".4s", ".4s", ".s", 9275 [(set (v4i32 V128:$Rd), 9276 (OpNode (v4i32 V128:$Rn), 9277 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9278 bits<2> idx; 9279 let Inst{11} = idx{1}; 9280 let Inst{21} = idx{0}; 9281 } 9282} 9283 9284multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 9285 SDPatternOperator OpNode> { 9286 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 9287 V128_lo, VectorIndexH, 9288 asm, ".4h", ".4h", ".4h", ".h", 9289 [(set (v4i16 V64:$dst), 9290 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 9291 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9292 bits<3> idx; 9293 let Inst{11} = idx{2}; 9294 let Inst{21} = idx{1}; 9295 let Inst{20} = idx{0}; 9296 } 9297 9298 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9299 V128, V128, 9300 V128_lo, VectorIndexH, 9301 asm, ".8h", ".8h", ".8h", ".h", 9302 [(set (v8i16 V128:$dst), 9303 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 9304 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 9305 bits<3> idx; 9306 let Inst{11} = idx{2}; 9307 let Inst{21} = idx{1}; 9308 let Inst{20} = idx{0}; 9309 } 9310 9311 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9312 V64, V64, 9313 V128, VectorIndexS, 9314 asm, ".2s", ".2s", ".2s", ".s", 9315 [(set (v2i32 V64:$dst), 9316 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 9317 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9318 bits<2> idx; 9319 let Inst{11} = idx{1}; 9320 let Inst{21} = idx{0}; 9321 } 9322 9323 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9324 V128, V128, 9325 V128, VectorIndexS, 9326 asm, ".4s", ".4s", ".4s", ".s", 9327 [(set (v4i32 V128:$dst), 9328 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9329 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 9330 bits<2> idx; 9331 let Inst{11} = idx{1}; 9332 let Inst{21} = idx{0}; 9333 } 9334} 9335 9336multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 9337 SDPatternOperator OpNode> { 9338 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9339 V128, V64, 9340 V128_lo, VectorIndexH, 9341 asm, ".4s", ".4s", ".4h", ".h", 9342 [(set (v4i32 V128:$Rd), 9343 (OpNode (v4i16 V64:$Rn), 9344 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9345 bits<3> idx; 9346 let Inst{11} = idx{2}; 9347 let Inst{21} = idx{1}; 9348 let Inst{20} = idx{0}; 9349 } 9350 9351 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9352 V128, V128, 9353 V128_lo, VectorIndexH, 9354 asm#"2", ".4s", ".4s", ".8h", ".h", 9355 [(set (v4i32 V128:$Rd), 9356 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9357 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9358 9359 bits<3> idx; 9360 let Inst{11} = idx{2}; 9361 let Inst{21} = idx{1}; 9362 let Inst{20} = idx{0}; 9363 } 9364 9365 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9366 V128, V64, 9367 V128, VectorIndexS, 9368 asm, ".2d", ".2d", ".2s", ".s", 9369 [(set (v2i64 V128:$Rd), 9370 (OpNode (v2i32 V64:$Rn), 9371 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9372 bits<2> idx; 9373 let Inst{11} = idx{1}; 9374 let Inst{21} = idx{0}; 9375 } 9376 9377 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9378 V128, V128, 9379 V128, VectorIndexS, 9380 asm#"2", ".2d", ".2d", ".4s", ".s", 9381 [(set (v2i64 V128:$Rd), 9382 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9383 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9384 bits<2> idx; 9385 let Inst{11} = idx{1}; 9386 let Inst{21} = idx{0}; 9387 } 9388 9389 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 9390 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9391 asm, ".h", "", "", ".h", []> { 9392 bits<3> idx; 9393 let Inst{11} = idx{2}; 9394 let Inst{21} = idx{1}; 9395 let Inst{20} = idx{0}; 9396 } 9397 9398 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 9399 FPR64Op, FPR32Op, V128, VectorIndexS, 9400 asm, ".s", "", "", ".s", []> { 9401 bits<2> idx; 9402 let Inst{11} = idx{1}; 9403 let Inst{21} = idx{0}; 9404 } 9405} 9406 9407multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 9408 SDPatternOperator Accum> { 9409 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9410 V128, V64, 9411 V128_lo, VectorIndexH, 9412 asm, ".4s", ".4s", ".4h", ".h", 9413 [(set (v4i32 V128:$dst), 9414 (Accum (v4i32 V128:$Rd), 9415 (v4i32 (int_aarch64_neon_sqdmull 9416 (v4i16 V64:$Rn), 9417 (dup_v8i16 (v8i16 V128_lo:$Rm), 9418 VectorIndexH:$idx)))))]> { 9419 bits<3> idx; 9420 let Inst{11} = idx{2}; 9421 let Inst{21} = idx{1}; 9422 let Inst{20} = idx{0}; 9423 } 9424 9425 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9426 V128, V128, 9427 V128_lo, VectorIndexH, 9428 asm#"2", ".4s", ".4s", ".8h", ".h", 9429 [(set (v4i32 V128:$dst), 9430 (Accum (v4i32 V128:$Rd), 9431 (v4i32 (int_aarch64_neon_sqdmull 9432 (extract_high_v8i16 (v8i16 V128:$Rn)), 9433 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> { 9434 bits<3> idx; 9435 let Inst{11} = idx{2}; 9436 let Inst{21} = idx{1}; 9437 let Inst{20} = idx{0}; 9438 } 9439 9440 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9441 V128, V64, 9442 V128, VectorIndexS, 9443 asm, ".2d", ".2d", ".2s", ".s", 9444 [(set (v2i64 V128:$dst), 9445 (Accum (v2i64 V128:$Rd), 9446 (v2i64 (int_aarch64_neon_sqdmull 9447 (v2i32 V64:$Rn), 9448 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9449 bits<2> idx; 9450 let Inst{11} = idx{1}; 9451 let Inst{21} = idx{0}; 9452 } 9453 9454 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9455 V128, V128, 9456 V128, VectorIndexS, 9457 asm#"2", ".2d", ".2d", ".4s", ".s", 9458 [(set (v2i64 V128:$dst), 9459 (Accum (v2i64 V128:$Rd), 9460 (v2i64 (int_aarch64_neon_sqdmull 9461 (extract_high_v4i32 (v4i32 V128:$Rn)), 9462 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> { 9463 bits<2> idx; 9464 let Inst{11} = idx{1}; 9465 let Inst{21} = idx{0}; 9466 } 9467 9468 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9469 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 9470 asm, ".h", "", "", ".h", []> { 9471 bits<3> idx; 9472 let Inst{11} = idx{2}; 9473 let Inst{21} = idx{1}; 9474 let Inst{20} = idx{0}; 9475 } 9476 9477 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9478 (i32 (vector_extract 9479 (v4i32 (int_aarch64_neon_sqdmull 9480 (v4i16 V64:$Rn), 9481 (v4i16 V64:$Rm))), 9482 (i64 0))))), 9483 (!cast<Instruction>(NAME # v1i32_indexed) 9484 FPR32Op:$Rd, 9485 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9486 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub), 9487 (i64 0))>; 9488 9489 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9490 (i32 (vector_extract 9491 (v4i32 (int_aarch64_neon_sqdmull 9492 (v4i16 V64:$Rn), 9493 (dup_v8i16 (v8i16 V128_lo:$Rm), 9494 VectorIndexH:$idx))), 9495 (i64 0))))), 9496 (!cast<Instruction>(NAME # v1i32_indexed) 9497 FPR32Op:$Rd, 9498 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)), 9499 V128_lo:$Rm, 9500 VectorIndexH:$idx)>; 9501 9502 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9503 FPR64Op, FPR32Op, V128, VectorIndexS, 9504 asm, ".s", "", "", ".s", 9505 [(set (i64 FPR64Op:$dst), 9506 (Accum (i64 FPR64Op:$Rd), 9507 (i64 (int_aarch64_neon_sqdmulls_scalar 9508 (i32 FPR32Op:$Rn), 9509 (i32 (vector_extract (v4i32 V128:$Rm), 9510 VectorIndexS:$idx))))))]> { 9511 9512 bits<2> idx; 9513 let Inst{11} = idx{1}; 9514 let Inst{21} = idx{0}; 9515 } 9516} 9517 9518multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 9519 SDPatternOperator OpNode> { 9520 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9521 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 9522 V128, V64, 9523 V128_lo, VectorIndexH, 9524 asm, ".4s", ".4s", ".4h", ".h", 9525 [(set (v4i32 V128:$Rd), 9526 (OpNode (v4i16 V64:$Rn), 9527 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9528 bits<3> idx; 9529 let Inst{11} = idx{2}; 9530 let Inst{21} = idx{1}; 9531 let Inst{20} = idx{0}; 9532 } 9533 9534 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 9535 V128, V128, 9536 V128_lo, VectorIndexH, 9537 asm#"2", ".4s", ".4s", ".8h", ".h", 9538 [(set (v4i32 V128:$Rd), 9539 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), 9540 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9541 9542 bits<3> idx; 9543 let Inst{11} = idx{2}; 9544 let Inst{21} = idx{1}; 9545 let Inst{20} = idx{0}; 9546 } 9547 9548 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 9549 V128, V64, 9550 V128, VectorIndexS, 9551 asm, ".2d", ".2d", ".2s", ".s", 9552 [(set (v2i64 V128:$Rd), 9553 (OpNode (v2i32 V64:$Rn), 9554 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9555 bits<2> idx; 9556 let Inst{11} = idx{1}; 9557 let Inst{21} = idx{0}; 9558 } 9559 9560 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 9561 V128, V128, 9562 V128, VectorIndexS, 9563 asm#"2", ".2d", ".2d", ".4s", ".s", 9564 [(set (v2i64 V128:$Rd), 9565 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), 9566 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9567 bits<2> idx; 9568 let Inst{11} = idx{1}; 9569 let Inst{21} = idx{0}; 9570 } 9571 } 9572} 9573 9574multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 9575 SDPatternOperator OpNode> { 9576 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9577 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9578 V128, V64, 9579 V128_lo, VectorIndexH, 9580 asm, ".4s", ".4s", ".4h", ".h", 9581 [(set (v4i32 V128:$dst), 9582 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 9583 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9584 bits<3> idx; 9585 let Inst{11} = idx{2}; 9586 let Inst{21} = idx{1}; 9587 let Inst{20} = idx{0}; 9588 } 9589 9590 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9591 V128, V128, 9592 V128_lo, VectorIndexH, 9593 asm#"2", ".4s", ".4s", ".8h", ".h", 9594 [(set (v4i32 V128:$dst), 9595 (OpNode (v4i32 V128:$Rd), 9596 (extract_high_v8i16 (v8i16 V128:$Rn)), 9597 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> { 9598 bits<3> idx; 9599 let Inst{11} = idx{2}; 9600 let Inst{21} = idx{1}; 9601 let Inst{20} = idx{0}; 9602 } 9603 9604 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9605 V128, V64, 9606 V128, VectorIndexS, 9607 asm, ".2d", ".2d", ".2s", ".s", 9608 [(set (v2i64 V128:$dst), 9609 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 9610 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9611 bits<2> idx; 9612 let Inst{11} = idx{1}; 9613 let Inst{21} = idx{0}; 9614 } 9615 9616 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9617 V128, V128, 9618 V128, VectorIndexS, 9619 asm#"2", ".2d", ".2d", ".4s", ".s", 9620 [(set (v2i64 V128:$dst), 9621 (OpNode (v2i64 V128:$Rd), 9622 (extract_high_v4i32 (v4i32 V128:$Rn)), 9623 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> { 9624 bits<2> idx; 9625 let Inst{11} = idx{1}; 9626 let Inst{21} = idx{0}; 9627 } 9628 } 9629} 9630 9631//---------------------------------------------------------------------------- 9632// AdvSIMD scalar shift by immediate 9633//---------------------------------------------------------------------------- 9634 9635let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9636class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 9637 RegisterClass regtype1, RegisterClass regtype2, 9638 Operand immtype, string asm, list<dag> pattern> 9639 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 9640 asm, "\t$Rd, $Rn, $imm", "", pattern>, 9641 Sched<[WriteVd]> { 9642 bits<5> Rd; 9643 bits<5> Rn; 9644 bits<7> imm; 9645 let Inst{31-30} = 0b01; 9646 let Inst{29} = U; 9647 let Inst{28-23} = 0b111110; 9648 let Inst{22-16} = fixed_imm; 9649 let Inst{15-11} = opc; 9650 let Inst{10} = 1; 9651 let Inst{9-5} = Rn; 9652 let Inst{4-0} = Rd; 9653} 9654 9655let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9656class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 9657 RegisterClass regtype1, RegisterClass regtype2, 9658 Operand immtype, string asm, list<dag> pattern> 9659 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 9660 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 9661 Sched<[WriteVd]> { 9662 bits<5> Rd; 9663 bits<5> Rn; 9664 bits<7> imm; 9665 let Inst{31-30} = 0b01; 9666 let Inst{29} = U; 9667 let Inst{28-23} = 0b111110; 9668 let Inst{22-16} = fixed_imm; 9669 let Inst{15-11} = opc; 9670 let Inst{10} = 1; 9671 let Inst{9-5} = Rn; 9672 let Inst{4-0} = Rd; 9673} 9674 9675 9676multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 9677 let Predicates = [HasNEON, HasFullFP16] in { 9678 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9679 FPR16, FPR16, vecshiftR16, asm, []> { 9680 let Inst{19-16} = imm{3-0}; 9681 } 9682 } // Predicates = [HasNEON, HasFullFP16] 9683 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9684 FPR32, FPR32, vecshiftR32, asm, []> { 9685 let Inst{20-16} = imm{4-0}; 9686 } 9687 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9688 FPR64, FPR64, vecshiftR64, asm, []> { 9689 let Inst{21-16} = imm{5-0}; 9690 } 9691} 9692 9693multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 9694 SDPatternOperator OpNode> { 9695 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9696 FPR64, FPR64, vecshiftR64, asm, 9697 [(set (i64 FPR64:$Rd), 9698 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 9699 let Inst{21-16} = imm{5-0}; 9700 } 9701 9702 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 9703 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 9704} 9705 9706multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 9707 SDPatternOperator OpNode = null_frag> { 9708 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9709 FPR64, FPR64, vecshiftR64, asm, 9710 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 9711 (i32 vecshiftR64:$imm)))]> { 9712 let Inst{21-16} = imm{5-0}; 9713 } 9714 9715 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 9716 (i32 vecshiftR64:$imm))), 9717 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 9718 vecshiftR64:$imm)>; 9719} 9720 9721multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 9722 SDPatternOperator OpNode> { 9723 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9724 FPR64, FPR64, vecshiftL64, asm, 9725 [(set (i64 FPR64:$Rd), 9726 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9727 let Inst{21-16} = imm{5-0}; 9728 } 9729 9730 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9731 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9732} 9733 9734let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9735multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 9736 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 9737 FPR64, FPR64, vecshiftL64, asm, []> { 9738 let Inst{21-16} = imm{5-0}; 9739 } 9740} 9741 9742let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9743multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 9744 SDPatternOperator OpNode = null_frag> { 9745 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9746 FPR8, FPR16, vecshiftR8, asm, []> { 9747 let Inst{18-16} = imm{2-0}; 9748 } 9749 9750 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9751 FPR16, FPR32, vecshiftR16, asm, []> { 9752 let Inst{19-16} = imm{3-0}; 9753 } 9754 9755 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9756 FPR32, FPR64, vecshiftR32, asm, 9757 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 9758 let Inst{20-16} = imm{4-0}; 9759 } 9760} 9761 9762multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 9763 SDPatternOperator OpNode> { 9764 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9765 FPR8, FPR8, vecshiftL8, asm, []> { 9766 let Inst{18-16} = imm{2-0}; 9767 } 9768 9769 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9770 FPR16, FPR16, vecshiftL16, asm, []> { 9771 let Inst{19-16} = imm{3-0}; 9772 } 9773 9774 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9775 FPR32, FPR32, vecshiftL32, asm, 9776 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 9777 let Inst{20-16} = imm{4-0}; 9778 } 9779 9780 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9781 FPR64, FPR64, vecshiftL64, asm, 9782 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 9783 let Inst{21-16} = imm{5-0}; 9784 } 9785 9786 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 9787 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 9788} 9789 9790multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 9791 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 9792 FPR8, FPR8, vecshiftR8, asm, []> { 9793 let Inst{18-16} = imm{2-0}; 9794 } 9795 9796 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 9797 FPR16, FPR16, vecshiftR16, asm, []> { 9798 let Inst{19-16} = imm{3-0}; 9799 } 9800 9801 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 9802 FPR32, FPR32, vecshiftR32, asm, []> { 9803 let Inst{20-16} = imm{4-0}; 9804 } 9805 9806 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 9807 FPR64, FPR64, vecshiftR64, asm, []> { 9808 let Inst{21-16} = imm{5-0}; 9809 } 9810} 9811 9812//---------------------------------------------------------------------------- 9813// AdvSIMD vector x indexed element 9814//---------------------------------------------------------------------------- 9815 9816let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9817class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9818 RegisterOperand dst_reg, RegisterOperand src_reg, 9819 Operand immtype, 9820 string asm, string dst_kind, string src_kind, 9821 list<dag> pattern> 9822 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 9823 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9824 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 9825 Sched<[!if(Q, WriteVq, WriteVd)]> { 9826 bits<5> Rd; 9827 bits<5> Rn; 9828 let Inst{31} = 0; 9829 let Inst{30} = Q; 9830 let Inst{29} = U; 9831 let Inst{28-23} = 0b011110; 9832 let Inst{22-16} = fixed_imm; 9833 let Inst{15-11} = opc; 9834 let Inst{10} = 1; 9835 let Inst{9-5} = Rn; 9836 let Inst{4-0} = Rd; 9837} 9838 9839let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 9840class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 9841 RegisterOperand vectype1, RegisterOperand vectype2, 9842 Operand immtype, 9843 string asm, string dst_kind, string src_kind, 9844 list<dag> pattern> 9845 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 9846 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 9847 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 9848 Sched<[!if(Q, WriteVq, WriteVd)]> { 9849 bits<5> Rd; 9850 bits<5> Rn; 9851 let Inst{31} = 0; 9852 let Inst{30} = Q; 9853 let Inst{29} = U; 9854 let Inst{28-23} = 0b011110; 9855 let Inst{22-16} = fixed_imm; 9856 let Inst{15-11} = opc; 9857 let Inst{10} = 1; 9858 let Inst{9-5} = Rn; 9859 let Inst{4-0} = Rd; 9860} 9861 9862multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 9863 Intrinsic OpNode> { 9864 let Predicates = [HasNEON, HasFullFP16] in { 9865 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9866 V64, V64, vecshiftR16, 9867 asm, ".4h", ".4h", 9868 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 9869 bits<4> imm; 9870 let Inst{19-16} = imm; 9871 } 9872 9873 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9874 V128, V128, vecshiftR16, 9875 asm, ".8h", ".8h", 9876 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 9877 bits<4> imm; 9878 let Inst{19-16} = imm; 9879 } 9880 } // Predicates = [HasNEON, HasFullFP16] 9881 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9882 V64, V64, vecshiftR32, 9883 asm, ".2s", ".2s", 9884 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 9885 bits<5> imm; 9886 let Inst{20-16} = imm; 9887 } 9888 9889 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9890 V128, V128, vecshiftR32, 9891 asm, ".4s", ".4s", 9892 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 9893 bits<5> imm; 9894 let Inst{20-16} = imm; 9895 } 9896 9897 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9898 V128, V128, vecshiftR64, 9899 asm, ".2d", ".2d", 9900 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 9901 bits<6> imm; 9902 let Inst{21-16} = imm; 9903 } 9904} 9905 9906multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 9907 Intrinsic OpNode> { 9908 let Predicates = [HasNEON, HasFullFP16] in { 9909 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9910 V64, V64, vecshiftR16, 9911 asm, ".4h", ".4h", 9912 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 9913 bits<4> imm; 9914 let Inst{19-16} = imm; 9915 } 9916 9917 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 9918 V128, V128, vecshiftR16, 9919 asm, ".8h", ".8h", 9920 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 9921 bits<4> imm; 9922 let Inst{19-16} = imm; 9923 } 9924 } // Predicates = [HasNEON, HasFullFP16] 9925 9926 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9927 V64, V64, vecshiftR32, 9928 asm, ".2s", ".2s", 9929 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 9930 bits<5> imm; 9931 let Inst{20-16} = imm; 9932 } 9933 9934 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9935 V128, V128, vecshiftR32, 9936 asm, ".4s", ".4s", 9937 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 9938 bits<5> imm; 9939 let Inst{20-16} = imm; 9940 } 9941 9942 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 9943 V128, V128, vecshiftR64, 9944 asm, ".2d", ".2d", 9945 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 9946 bits<6> imm; 9947 let Inst{21-16} = imm; 9948 } 9949} 9950 9951multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 9952 SDPatternOperator OpNode> { 9953 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 9954 V64, V128, vecshiftR16Narrow, 9955 asm, ".8b", ".8h", 9956 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 9957 bits<3> imm; 9958 let Inst{18-16} = imm; 9959 } 9960 9961 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 9962 V128, V128, vecshiftR16Narrow, 9963 asm#"2", ".16b", ".8h", []> { 9964 bits<3> imm; 9965 let Inst{18-16} = imm; 9966 let hasSideEffects = 0; 9967 } 9968 9969 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 9970 V64, V128, vecshiftR32Narrow, 9971 asm, ".4h", ".4s", 9972 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 9973 bits<4> imm; 9974 let Inst{19-16} = imm; 9975 } 9976 9977 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 9978 V128, V128, vecshiftR32Narrow, 9979 asm#"2", ".8h", ".4s", []> { 9980 bits<4> imm; 9981 let Inst{19-16} = imm; 9982 let hasSideEffects = 0; 9983 } 9984 9985 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 9986 V64, V128, vecshiftR64Narrow, 9987 asm, ".2s", ".2d", 9988 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 9989 bits<5> imm; 9990 let Inst{20-16} = imm; 9991 } 9992 9993 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 9994 V128, V128, vecshiftR64Narrow, 9995 asm#"2", ".4s", ".2d", []> { 9996 bits<5> imm; 9997 let Inst{20-16} = imm; 9998 let hasSideEffects = 0; 9999 } 10000 10001 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 10002 // themselves, so put them here instead. 10003 10004 // Patterns involving what's effectively an insert high and a normal 10005 // intrinsic, represented by CONCAT_VECTORS. 10006 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 10007 vecshiftR16Narrow:$imm)), 10008 (!cast<Instruction>(NAME # "v16i8_shift") 10009 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10010 V128:$Rn, vecshiftR16Narrow:$imm)>; 10011 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 10012 vecshiftR32Narrow:$imm)), 10013 (!cast<Instruction>(NAME # "v8i16_shift") 10014 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10015 V128:$Rn, vecshiftR32Narrow:$imm)>; 10016 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 10017 vecshiftR64Narrow:$imm)), 10018 (!cast<Instruction>(NAME # "v4i32_shift") 10019 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 10020 V128:$Rn, vecshiftR64Narrow:$imm)>; 10021} 10022 10023multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 10024 SDPatternOperator OpNode> { 10025 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10026 V64, V64, vecshiftL8, 10027 asm, ".8b", ".8b", 10028 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10029 (i32 vecshiftL8:$imm)))]> { 10030 bits<3> imm; 10031 let Inst{18-16} = imm; 10032 } 10033 10034 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10035 V128, V128, vecshiftL8, 10036 asm, ".16b", ".16b", 10037 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10038 (i32 vecshiftL8:$imm)))]> { 10039 bits<3> imm; 10040 let Inst{18-16} = imm; 10041 } 10042 10043 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10044 V64, V64, vecshiftL16, 10045 asm, ".4h", ".4h", 10046 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10047 (i32 vecshiftL16:$imm)))]> { 10048 bits<4> imm; 10049 let Inst{19-16} = imm; 10050 } 10051 10052 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10053 V128, V128, vecshiftL16, 10054 asm, ".8h", ".8h", 10055 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10056 (i32 vecshiftL16:$imm)))]> { 10057 bits<4> imm; 10058 let Inst{19-16} = imm; 10059 } 10060 10061 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10062 V64, V64, vecshiftL32, 10063 asm, ".2s", ".2s", 10064 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10065 (i32 vecshiftL32:$imm)))]> { 10066 bits<5> imm; 10067 let Inst{20-16} = imm; 10068 } 10069 10070 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10071 V128, V128, vecshiftL32, 10072 asm, ".4s", ".4s", 10073 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10074 (i32 vecshiftL32:$imm)))]> { 10075 bits<5> imm; 10076 let Inst{20-16} = imm; 10077 } 10078 10079 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10080 V128, V128, vecshiftL64, 10081 asm, ".2d", ".2d", 10082 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10083 (i32 vecshiftL64:$imm)))]> { 10084 bits<6> imm; 10085 let Inst{21-16} = imm; 10086 } 10087} 10088 10089multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 10090 SDPatternOperator OpNode> { 10091 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10092 V64, V64, vecshiftR8, 10093 asm, ".8b", ".8b", 10094 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 10095 (i32 vecshiftR8:$imm)))]> { 10096 bits<3> imm; 10097 let Inst{18-16} = imm; 10098 } 10099 10100 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10101 V128, V128, vecshiftR8, 10102 asm, ".16b", ".16b", 10103 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 10104 (i32 vecshiftR8:$imm)))]> { 10105 bits<3> imm; 10106 let Inst{18-16} = imm; 10107 } 10108 10109 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10110 V64, V64, vecshiftR16, 10111 asm, ".4h", ".4h", 10112 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 10113 (i32 vecshiftR16:$imm)))]> { 10114 bits<4> imm; 10115 let Inst{19-16} = imm; 10116 } 10117 10118 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10119 V128, V128, vecshiftR16, 10120 asm, ".8h", ".8h", 10121 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 10122 (i32 vecshiftR16:$imm)))]> { 10123 bits<4> imm; 10124 let Inst{19-16} = imm; 10125 } 10126 10127 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10128 V64, V64, vecshiftR32, 10129 asm, ".2s", ".2s", 10130 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 10131 (i32 vecshiftR32:$imm)))]> { 10132 bits<5> imm; 10133 let Inst{20-16} = imm; 10134 } 10135 10136 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10137 V128, V128, vecshiftR32, 10138 asm, ".4s", ".4s", 10139 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 10140 (i32 vecshiftR32:$imm)))]> { 10141 bits<5> imm; 10142 let Inst{20-16} = imm; 10143 } 10144 10145 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 10146 V128, V128, vecshiftR64, 10147 asm, ".2d", ".2d", 10148 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 10149 (i32 vecshiftR64:$imm)))]> { 10150 bits<6> imm; 10151 let Inst{21-16} = imm; 10152 } 10153} 10154 10155let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10156multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 10157 SDPatternOperator OpNode = null_frag> { 10158 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10159 V64, V64, vecshiftR8, asm, ".8b", ".8b", 10160 [(set (v8i8 V64:$dst), 10161 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10162 (i32 vecshiftR8:$imm)))]> { 10163 bits<3> imm; 10164 let Inst{18-16} = imm; 10165 } 10166 10167 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10168 V128, V128, vecshiftR8, asm, ".16b", ".16b", 10169 [(set (v16i8 V128:$dst), 10170 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10171 (i32 vecshiftR8:$imm)))]> { 10172 bits<3> imm; 10173 let Inst{18-16} = imm; 10174 } 10175 10176 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10177 V64, V64, vecshiftR16, asm, ".4h", ".4h", 10178 [(set (v4i16 V64:$dst), 10179 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10180 (i32 vecshiftR16:$imm)))]> { 10181 bits<4> imm; 10182 let Inst{19-16} = imm; 10183 } 10184 10185 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10186 V128, V128, vecshiftR16, asm, ".8h", ".8h", 10187 [(set (v8i16 V128:$dst), 10188 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10189 (i32 vecshiftR16:$imm)))]> { 10190 bits<4> imm; 10191 let Inst{19-16} = imm; 10192 } 10193 10194 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10195 V64, V64, vecshiftR32, asm, ".2s", ".2s", 10196 [(set (v2i32 V64:$dst), 10197 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10198 (i32 vecshiftR32:$imm)))]> { 10199 bits<5> imm; 10200 let Inst{20-16} = imm; 10201 } 10202 10203 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10204 V128, V128, vecshiftR32, asm, ".4s", ".4s", 10205 [(set (v4i32 V128:$dst), 10206 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10207 (i32 vecshiftR32:$imm)))]> { 10208 bits<5> imm; 10209 let Inst{20-16} = imm; 10210 } 10211 10212 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10213 V128, V128, vecshiftR64, 10214 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 10215 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10216 (i32 vecshiftR64:$imm)))]> { 10217 bits<6> imm; 10218 let Inst{21-16} = imm; 10219 } 10220} 10221 10222multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 10223 SDPatternOperator OpNode = null_frag> { 10224 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 10225 V64, V64, vecshiftL8, 10226 asm, ".8b", ".8b", 10227 [(set (v8i8 V64:$dst), 10228 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 10229 (i32 vecshiftL8:$imm)))]> { 10230 bits<3> imm; 10231 let Inst{18-16} = imm; 10232 } 10233 10234 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 10235 V128, V128, vecshiftL8, 10236 asm, ".16b", ".16b", 10237 [(set (v16i8 V128:$dst), 10238 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 10239 (i32 vecshiftL8:$imm)))]> { 10240 bits<3> imm; 10241 let Inst{18-16} = imm; 10242 } 10243 10244 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 10245 V64, V64, vecshiftL16, 10246 asm, ".4h", ".4h", 10247 [(set (v4i16 V64:$dst), 10248 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 10249 (i32 vecshiftL16:$imm)))]> { 10250 bits<4> imm; 10251 let Inst{19-16} = imm; 10252 } 10253 10254 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 10255 V128, V128, vecshiftL16, 10256 asm, ".8h", ".8h", 10257 [(set (v8i16 V128:$dst), 10258 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 10259 (i32 vecshiftL16:$imm)))]> { 10260 bits<4> imm; 10261 let Inst{19-16} = imm; 10262 } 10263 10264 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 10265 V64, V64, vecshiftL32, 10266 asm, ".2s", ".2s", 10267 [(set (v2i32 V64:$dst), 10268 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 10269 (i32 vecshiftL32:$imm)))]> { 10270 bits<5> imm; 10271 let Inst{20-16} = imm; 10272 } 10273 10274 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 10275 V128, V128, vecshiftL32, 10276 asm, ".4s", ".4s", 10277 [(set (v4i32 V128:$dst), 10278 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10279 (i32 vecshiftL32:$imm)))]> { 10280 bits<5> imm; 10281 let Inst{20-16} = imm; 10282 } 10283 10284 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 10285 V128, V128, vecshiftL64, 10286 asm, ".2d", ".2d", 10287 [(set (v2i64 V128:$dst), 10288 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 10289 (i32 vecshiftL64:$imm)))]> { 10290 bits<6> imm; 10291 let Inst{21-16} = imm; 10292 } 10293} 10294 10295multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 10296 SDPatternOperator OpNode> { 10297 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 10298 V128, V64, vecshiftL8, asm, ".8h", ".8b", 10299 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 10300 bits<3> imm; 10301 let Inst{18-16} = imm; 10302 } 10303 10304 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 10305 V128, V128, vecshiftL8, 10306 asm#"2", ".8h", ".16b", 10307 [(set (v8i16 V128:$Rd), 10308 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> { 10309 bits<3> imm; 10310 let Inst{18-16} = imm; 10311 } 10312 10313 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 10314 V128, V64, vecshiftL16, asm, ".4s", ".4h", 10315 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 10316 bits<4> imm; 10317 let Inst{19-16} = imm; 10318 } 10319 10320 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 10321 V128, V128, vecshiftL16, 10322 asm#"2", ".4s", ".8h", 10323 [(set (v4i32 V128:$Rd), 10324 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> { 10325 10326 bits<4> imm; 10327 let Inst{19-16} = imm; 10328 } 10329 10330 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 10331 V128, V64, vecshiftL32, asm, ".2d", ".2s", 10332 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 10333 bits<5> imm; 10334 let Inst{20-16} = imm; 10335 } 10336 10337 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 10338 V128, V128, vecshiftL32, 10339 asm#"2", ".2d", ".4s", 10340 [(set (v2i64 V128:$Rd), 10341 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> { 10342 bits<5> imm; 10343 let Inst{20-16} = imm; 10344 } 10345} 10346 10347 10348//--- 10349// Vector load/store 10350//--- 10351// SIMD ldX/stX no-index memory references don't allow the optional 10352// ", #0" constant and handle post-indexing explicitly, so we use 10353// a more specialized parse method for them. Otherwise, it's the same as 10354// the general GPR64sp handling. 10355 10356class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 10357 string asm, dag oops, dag iops, list<dag> pattern> 10358 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 10359 bits<5> Vt; 10360 bits<5> Rn; 10361 let Inst{31} = 0; 10362 let Inst{30} = Q; 10363 let Inst{29-23} = 0b0011000; 10364 let Inst{22} = L; 10365 let Inst{21-16} = 0b000000; 10366 let Inst{15-12} = opcode; 10367 let Inst{11-10} = size; 10368 let Inst{9-5} = Rn; 10369 let Inst{4-0} = Vt; 10370} 10371 10372class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 10373 string asm, dag oops, dag iops> 10374 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 10375 bits<5> Vt; 10376 bits<5> Rn; 10377 bits<5> Xm; 10378 let Inst{31} = 0; 10379 let Inst{30} = Q; 10380 let Inst{29-23} = 0b0011001; 10381 let Inst{22} = L; 10382 let Inst{21} = 0; 10383 let Inst{20-16} = Xm; 10384 let Inst{15-12} = opcode; 10385 let Inst{11-10} = size; 10386 let Inst{9-5} = Rn; 10387 let Inst{4-0} = Vt; 10388} 10389 10390// The immediate form of AdvSIMD post-indexed addressing is encoded with 10391// register post-index addressing from the zero register. 10392multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 10393 int Offset, int Size> { 10394 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 10395 // "ld1\t$Vt, [$Rn], #16" 10396 // may get mapped to 10397 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 10398 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10399 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10400 GPR64sp:$Rn, 10401 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10402 XZR), 1>; 10403 10404 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 10405 // "ld1.8b\t$Vt, [$Rn], #16" 10406 // may get mapped to 10407 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 10408 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10409 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10410 GPR64sp:$Rn, 10411 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10412 XZR), 0>; 10413 10414 // E.g. "ld1.8b { v0, v1 }, [x1]" 10415 // "ld1\t$Vt, [$Rn]" 10416 // may get mapped to 10417 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 10418 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10419 (!cast<Instruction>(BaseName # Count # "v" # layout) 10420 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10421 GPR64sp:$Rn), 0>; 10422 10423 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 10424 // "ld1\t$Vt, [$Rn], $Xm" 10425 // may get mapped to 10426 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 10427 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10428 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 10429 GPR64sp:$Rn, 10430 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10431 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10432} 10433 10434multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 10435 int Offset128, int Offset64, bits<4> opcode> { 10436 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10437 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 10438 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 10439 (ins GPR64sp:$Rn), []>; 10440 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 10441 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 10442 (ins GPR64sp:$Rn), []>; 10443 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 10444 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 10445 (ins GPR64sp:$Rn), []>; 10446 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 10447 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 10448 (ins GPR64sp:$Rn), []>; 10449 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 10450 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 10451 (ins GPR64sp:$Rn), []>; 10452 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 10453 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 10454 (ins GPR64sp:$Rn), []>; 10455 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 10456 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 10457 (ins GPR64sp:$Rn), []>; 10458 10459 10460 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 10461 (outs GPR64sp:$wback, 10462 !cast<RegisterOperand>(veclist # "16b"):$Vt), 10463 (ins GPR64sp:$Rn, 10464 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10465 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 10466 (outs GPR64sp:$wback, 10467 !cast<RegisterOperand>(veclist # "8h"):$Vt), 10468 (ins GPR64sp:$Rn, 10469 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10470 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 10471 (outs GPR64sp:$wback, 10472 !cast<RegisterOperand>(veclist # "4s"):$Vt), 10473 (ins GPR64sp:$Rn, 10474 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10475 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 10476 (outs GPR64sp:$wback, 10477 !cast<RegisterOperand>(veclist # "2d"):$Vt), 10478 (ins GPR64sp:$Rn, 10479 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10480 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 10481 (outs GPR64sp:$wback, 10482 !cast<RegisterOperand>(veclist # "8b"):$Vt), 10483 (ins GPR64sp:$Rn, 10484 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10485 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 10486 (outs GPR64sp:$wback, 10487 !cast<RegisterOperand>(veclist # "4h"):$Vt), 10488 (ins GPR64sp:$Rn, 10489 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10490 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 10491 (outs GPR64sp:$wback, 10492 !cast<RegisterOperand>(veclist # "2s"):$Vt), 10493 (ins GPR64sp:$Rn, 10494 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10495 } 10496 10497 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10498 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10499 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10500 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10501 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10502 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10503 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10504} 10505 10506// Only ld1/st1 has a v1d version. 10507multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 10508 int Offset128, int Offset64, bits<4> opcode> { 10509 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 10510 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 10511 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10512 GPR64sp:$Rn), []>; 10513 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 10514 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10515 GPR64sp:$Rn), []>; 10516 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 10517 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10518 GPR64sp:$Rn), []>; 10519 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 10520 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10521 GPR64sp:$Rn), []>; 10522 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 10523 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10524 GPR64sp:$Rn), []>; 10525 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 10526 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10527 GPR64sp:$Rn), []>; 10528 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 10529 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10530 GPR64sp:$Rn), []>; 10531 10532 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 10533 (outs GPR64sp:$wback), 10534 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 10535 GPR64sp:$Rn, 10536 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10537 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 10538 (outs GPR64sp:$wback), 10539 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 10540 GPR64sp:$Rn, 10541 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10542 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 10543 (outs GPR64sp:$wback), 10544 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 10545 GPR64sp:$Rn, 10546 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10547 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 10548 (outs GPR64sp:$wback), 10549 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 10550 GPR64sp:$Rn, 10551 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 10552 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 10553 (outs GPR64sp:$wback), 10554 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 10555 GPR64sp:$Rn, 10556 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10557 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 10558 (outs GPR64sp:$wback), 10559 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 10560 GPR64sp:$Rn, 10561 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10562 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 10563 (outs GPR64sp:$wback), 10564 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 10565 GPR64sp:$Rn, 10566 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10567 } 10568 10569 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 10570 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 10571 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 10572 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 10573 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 10574 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 10575 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 10576} 10577 10578multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 10579 int Offset128, int Offset64, bits<4> opcode> 10580 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10581 10582 // LD1 instructions have extra "1d" variants. 10583 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 10584 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 10585 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 10586 (ins GPR64sp:$Rn), []>; 10587 10588 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 10589 (outs GPR64sp:$wback, 10590 !cast<RegisterOperand>(veclist # "1d"):$Vt), 10591 (ins GPR64sp:$Rn, 10592 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10593 } 10594 10595 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10596} 10597 10598multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 10599 int Offset128, int Offset64, bits<4> opcode> 10600 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 10601 10602 // ST1 instructions have extra "1d" variants. 10603 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 10604 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 10605 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10606 GPR64sp:$Rn), []>; 10607 10608 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 10609 (outs GPR64sp:$wback), 10610 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 10611 GPR64sp:$Rn, 10612 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 10613 } 10614 10615 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 10616} 10617 10618multiclass SIMDLd1Multiple<string asm> { 10619 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10620 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10621 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10622 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10623} 10624 10625multiclass SIMDSt1Multiple<string asm> { 10626 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 10627 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 10628 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 10629 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 10630} 10631 10632multiclass SIMDLd2Multiple<string asm> { 10633 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10634} 10635 10636multiclass SIMDSt2Multiple<string asm> { 10637 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 10638} 10639 10640multiclass SIMDLd3Multiple<string asm> { 10641 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10642} 10643 10644multiclass SIMDSt3Multiple<string asm> { 10645 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 10646} 10647 10648multiclass SIMDLd4Multiple<string asm> { 10649 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10650} 10651 10652multiclass SIMDSt4Multiple<string asm> { 10653 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 10654} 10655 10656//--- 10657// AdvSIMD Load/store single-element 10658//--- 10659 10660class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 10661 string asm, string operands, string cst, 10662 dag oops, dag iops, list<dag> pattern> 10663 : I<oops, iops, asm, operands, cst, pattern> { 10664 bits<5> Vt; 10665 bits<5> Rn; 10666 let Inst{31} = 0; 10667 let Inst{29-24} = 0b001101; 10668 let Inst{22} = L; 10669 let Inst{21} = R; 10670 let Inst{15-13} = opcode; 10671 let Inst{9-5} = Rn; 10672 let Inst{4-0} = Vt; 10673} 10674 10675class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 10676 string asm, string operands, string cst, 10677 dag oops, dag iops, list<dag> pattern> 10678 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 10679 bits<5> Vt; 10680 bits<5> Rn; 10681 let Inst{31} = 0; 10682 let Inst{29-24} = 0b001101; 10683 let Inst{22} = L; 10684 let Inst{21} = R; 10685 let Inst{15-13} = opcode; 10686 let Inst{9-5} = Rn; 10687 let Inst{4-0} = Vt; 10688} 10689 10690 10691let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10692class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 10693 DAGOperand listtype> 10694 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 10695 (outs listtype:$Vt), (ins GPR64sp:$Rn), 10696 []> { 10697 let Inst{30} = Q; 10698 let Inst{23} = 0; 10699 let Inst{20-16} = 0b00000; 10700 let Inst{12} = S; 10701 let Inst{11-10} = size; 10702} 10703let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 10704class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 10705 string asm, DAGOperand listtype, DAGOperand GPR64pi> 10706 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 10707 "$Rn = $wback", 10708 (outs GPR64sp:$wback, listtype:$Vt), 10709 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 10710 bits<5> Xm; 10711 let Inst{30} = Q; 10712 let Inst{23} = 1; 10713 let Inst{20-16} = Xm; 10714 let Inst{12} = S; 10715 let Inst{11-10} = size; 10716} 10717 10718multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 10719 int Offset, int Size> { 10720 // E.g. "ld1r { v0.8b }, [x1], #1" 10721 // "ld1r.8b\t$Vt, [$Rn], #1" 10722 // may get mapped to 10723 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 10724 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 10725 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10726 GPR64sp:$Rn, 10727 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 10728 XZR), 1>; 10729 10730 // E.g. "ld1r.8b { v0 }, [x1], #1" 10731 // "ld1r.8b\t$Vt, [$Rn], #1" 10732 // may get mapped to 10733 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 10734 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 10735 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10736 GPR64sp:$Rn, 10737 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10738 XZR), 0>; 10739 10740 // E.g. "ld1r.8b { v0 }, [x1]" 10741 // "ld1r.8b\t$Vt, [$Rn]" 10742 // may get mapped to 10743 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 10744 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 10745 (!cast<Instruction>(BaseName # "v" # layout) 10746 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10747 GPR64sp:$Rn), 0>; 10748 10749 // E.g. "ld1r.8b { v0 }, [x1], x2" 10750 // "ld1r.8b\t$Vt, [$Rn], $Xm" 10751 // may get mapped to 10752 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 10753 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 10754 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 10755 GPR64sp:$Rn, 10756 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 10757 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 10758} 10759 10760multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 10761 int Offset1, int Offset2, int Offset4, int Offset8> { 10762 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 10763 !cast<DAGOperand>("VecList" # Count # "8b")>; 10764 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 10765 !cast<DAGOperand>("VecList" # Count #"16b")>; 10766 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 10767 !cast<DAGOperand>("VecList" # Count #"4h")>; 10768 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 10769 !cast<DAGOperand>("VecList" # Count #"8h")>; 10770 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 10771 !cast<DAGOperand>("VecList" # Count #"2s")>; 10772 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 10773 !cast<DAGOperand>("VecList" # Count #"4s")>; 10774 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 10775 !cast<DAGOperand>("VecList" # Count #"1d")>; 10776 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 10777 !cast<DAGOperand>("VecList" # Count #"2d")>; 10778 10779 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 10780 !cast<DAGOperand>("VecList" # Count # "8b"), 10781 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10782 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 10783 !cast<DAGOperand>("VecList" # Count # "16b"), 10784 !cast<DAGOperand>("GPR64pi" # Offset1)>; 10785 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 10786 !cast<DAGOperand>("VecList" # Count # "4h"), 10787 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10788 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 10789 !cast<DAGOperand>("VecList" # Count # "8h"), 10790 !cast<DAGOperand>("GPR64pi" # Offset2)>; 10791 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 10792 !cast<DAGOperand>("VecList" # Count # "2s"), 10793 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10794 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 10795 !cast<DAGOperand>("VecList" # Count # "4s"), 10796 !cast<DAGOperand>("GPR64pi" # Offset4)>; 10797 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 10798 !cast<DAGOperand>("VecList" # Count # "1d"), 10799 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10800 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 10801 !cast<DAGOperand>("VecList" # Count # "2d"), 10802 !cast<DAGOperand>("GPR64pi" # Offset8)>; 10803 10804 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 10805 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 10806 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 10807 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 10808 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 10809 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 10810 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 10811 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 10812} 10813 10814class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 10815 dag oops, dag iops, list<dag> pattern> 10816 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10817 pattern> { 10818 // idx encoded in Q:S:size fields. 10819 bits<4> idx; 10820 let Inst{30} = idx{3}; 10821 let Inst{23} = 0; 10822 let Inst{20-16} = 0b00000; 10823 let Inst{12} = idx{2}; 10824 let Inst{11-10} = idx{1-0}; 10825} 10826class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 10827 dag oops, dag iops, list<dag> pattern> 10828 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10829 oops, iops, pattern> { 10830 // idx encoded in Q:S:size fields. 10831 bits<4> idx; 10832 let Inst{30} = idx{3}; 10833 let Inst{23} = 0; 10834 let Inst{20-16} = 0b00000; 10835 let Inst{12} = idx{2}; 10836 let Inst{11-10} = idx{1-0}; 10837} 10838class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 10839 dag oops, dag iops> 10840 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10841 "$Rn = $wback", oops, iops, []> { 10842 // idx encoded in Q:S:size fields. 10843 bits<4> idx; 10844 bits<5> Xm; 10845 let Inst{30} = idx{3}; 10846 let Inst{23} = 1; 10847 let Inst{20-16} = Xm; 10848 let Inst{12} = idx{2}; 10849 let Inst{11-10} = idx{1-0}; 10850} 10851class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 10852 dag oops, dag iops> 10853 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10854 "$Rn = $wback", oops, iops, []> { 10855 // idx encoded in Q:S:size fields. 10856 bits<4> idx; 10857 bits<5> Xm; 10858 let Inst{30} = idx{3}; 10859 let Inst{23} = 1; 10860 let Inst{20-16} = Xm; 10861 let Inst{12} = idx{2}; 10862 let Inst{11-10} = idx{1-0}; 10863} 10864 10865class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 10866 dag oops, dag iops, list<dag> pattern> 10867 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10868 pattern> { 10869 // idx encoded in Q:S:size<1> fields. 10870 bits<3> idx; 10871 let Inst{30} = idx{2}; 10872 let Inst{23} = 0; 10873 let Inst{20-16} = 0b00000; 10874 let Inst{12} = idx{1}; 10875 let Inst{11} = idx{0}; 10876 let Inst{10} = size; 10877} 10878class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 10879 dag oops, dag iops, list<dag> pattern> 10880 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10881 oops, iops, pattern> { 10882 // idx encoded in Q:S:size<1> fields. 10883 bits<3> idx; 10884 let Inst{30} = idx{2}; 10885 let Inst{23} = 0; 10886 let Inst{20-16} = 0b00000; 10887 let Inst{12} = idx{1}; 10888 let Inst{11} = idx{0}; 10889 let Inst{10} = size; 10890} 10891 10892class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10893 dag oops, dag iops> 10894 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10895 "$Rn = $wback", oops, iops, []> { 10896 // idx encoded in Q:S:size<1> fields. 10897 bits<3> idx; 10898 bits<5> Xm; 10899 let Inst{30} = idx{2}; 10900 let Inst{23} = 1; 10901 let Inst{20-16} = Xm; 10902 let Inst{12} = idx{1}; 10903 let Inst{11} = idx{0}; 10904 let Inst{10} = size; 10905} 10906class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 10907 dag oops, dag iops> 10908 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10909 "$Rn = $wback", oops, iops, []> { 10910 // idx encoded in Q:S:size<1> fields. 10911 bits<3> idx; 10912 bits<5> Xm; 10913 let Inst{30} = idx{2}; 10914 let Inst{23} = 1; 10915 let Inst{20-16} = Xm; 10916 let Inst{12} = idx{1}; 10917 let Inst{11} = idx{0}; 10918 let Inst{10} = size; 10919} 10920class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10921 dag oops, dag iops, list<dag> pattern> 10922 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10923 pattern> { 10924 // idx encoded in Q:S fields. 10925 bits<2> idx; 10926 let Inst{30} = idx{1}; 10927 let Inst{23} = 0; 10928 let Inst{20-16} = 0b00000; 10929 let Inst{12} = idx{0}; 10930 let Inst{11-10} = size; 10931} 10932class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10933 dag oops, dag iops, list<dag> pattern> 10934 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10935 oops, iops, pattern> { 10936 // idx encoded in Q:S fields. 10937 bits<2> idx; 10938 let Inst{30} = idx{1}; 10939 let Inst{23} = 0; 10940 let Inst{20-16} = 0b00000; 10941 let Inst{12} = idx{0}; 10942 let Inst{11-10} = size; 10943} 10944class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 10945 string asm, dag oops, dag iops> 10946 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10947 "$Rn = $wback", oops, iops, []> { 10948 // idx encoded in Q:S fields. 10949 bits<2> idx; 10950 bits<5> Xm; 10951 let Inst{30} = idx{1}; 10952 let Inst{23} = 1; 10953 let Inst{20-16} = Xm; 10954 let Inst{12} = idx{0}; 10955 let Inst{11-10} = size; 10956} 10957class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 10958 string asm, dag oops, dag iops> 10959 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10960 "$Rn = $wback", oops, iops, []> { 10961 // idx encoded in Q:S fields. 10962 bits<2> idx; 10963 bits<5> Xm; 10964 let Inst{30} = idx{1}; 10965 let Inst{23} = 1; 10966 let Inst{20-16} = Xm; 10967 let Inst{12} = idx{0}; 10968 let Inst{11-10} = size; 10969} 10970class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10971 dag oops, dag iops, list<dag> pattern> 10972 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 10973 pattern> { 10974 // idx encoded in Q field. 10975 bits<1> idx; 10976 let Inst{30} = idx; 10977 let Inst{23} = 0; 10978 let Inst{20-16} = 0b00000; 10979 let Inst{12} = 0; 10980 let Inst{11-10} = size; 10981} 10982class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 10983 dag oops, dag iops, list<dag> pattern> 10984 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 10985 oops, iops, pattern> { 10986 // idx encoded in Q field. 10987 bits<1> idx; 10988 let Inst{30} = idx; 10989 let Inst{23} = 0; 10990 let Inst{20-16} = 0b00000; 10991 let Inst{12} = 0; 10992 let Inst{11-10} = size; 10993} 10994class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 10995 string asm, dag oops, dag iops> 10996 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 10997 "$Rn = $wback", oops, iops, []> { 10998 // idx encoded in Q field. 10999 bits<1> idx; 11000 bits<5> Xm; 11001 let Inst{30} = idx; 11002 let Inst{23} = 1; 11003 let Inst{20-16} = Xm; 11004 let Inst{12} = 0; 11005 let Inst{11-10} = size; 11006} 11007class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 11008 string asm, dag oops, dag iops> 11009 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 11010 "$Rn = $wback", oops, iops, []> { 11011 // idx encoded in Q field. 11012 bits<1> idx; 11013 bits<5> Xm; 11014 let Inst{30} = idx; 11015 let Inst{23} = 1; 11016 let Inst{20-16} = Xm; 11017 let Inst{12} = 0; 11018 let Inst{11-10} = size; 11019} 11020 11021let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11022multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 11023 RegisterOperand listtype, 11024 RegisterOperand GPR64pi> { 11025 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 11026 (outs listtype:$dst), 11027 (ins listtype:$Vt, VectorIndexB:$idx, 11028 GPR64sp:$Rn), []>; 11029 11030 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 11031 (outs GPR64sp:$wback, listtype:$dst), 11032 (ins listtype:$Vt, VectorIndexB:$idx, 11033 GPR64sp:$Rn, GPR64pi:$Xm)>; 11034} 11035let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11036multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 11037 RegisterOperand listtype, 11038 RegisterOperand GPR64pi> { 11039 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 11040 (outs listtype:$dst), 11041 (ins listtype:$Vt, VectorIndexH:$idx, 11042 GPR64sp:$Rn), []>; 11043 11044 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 11045 (outs GPR64sp:$wback, listtype:$dst), 11046 (ins listtype:$Vt, VectorIndexH:$idx, 11047 GPR64sp:$Rn, GPR64pi:$Xm)>; 11048} 11049let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11050multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 11051 RegisterOperand listtype, 11052 RegisterOperand GPR64pi> { 11053 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 11054 (outs listtype:$dst), 11055 (ins listtype:$Vt, VectorIndexS:$idx, 11056 GPR64sp:$Rn), []>; 11057 11058 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 11059 (outs GPR64sp:$wback, listtype:$dst), 11060 (ins listtype:$Vt, VectorIndexS:$idx, 11061 GPR64sp:$Rn, GPR64pi:$Xm)>; 11062} 11063let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 11064multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 11065 RegisterOperand listtype, RegisterOperand GPR64pi> { 11066 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 11067 (outs listtype:$dst), 11068 (ins listtype:$Vt, VectorIndexD:$idx, 11069 GPR64sp:$Rn), []>; 11070 11071 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 11072 (outs GPR64sp:$wback, listtype:$dst), 11073 (ins listtype:$Vt, VectorIndexD:$idx, 11074 GPR64sp:$Rn, GPR64pi:$Xm)>; 11075} 11076let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11077multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 11078 RegisterOperand listtype, RegisterOperand GPR64pi> { 11079 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 11080 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 11081 GPR64sp:$Rn), []>; 11082 11083 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 11084 (outs GPR64sp:$wback), 11085 (ins listtype:$Vt, VectorIndexB:$idx, 11086 GPR64sp:$Rn, GPR64pi:$Xm)>; 11087} 11088let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11089multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 11090 RegisterOperand listtype, RegisterOperand GPR64pi> { 11091 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 11092 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 11093 GPR64sp:$Rn), []>; 11094 11095 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 11096 (outs GPR64sp:$wback), 11097 (ins listtype:$Vt, VectorIndexH:$idx, 11098 GPR64sp:$Rn, GPR64pi:$Xm)>; 11099} 11100let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11101multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 11102 RegisterOperand listtype, RegisterOperand GPR64pi> { 11103 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 11104 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 11105 GPR64sp:$Rn), []>; 11106 11107 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 11108 (outs GPR64sp:$wback), 11109 (ins listtype:$Vt, VectorIndexS:$idx, 11110 GPR64sp:$Rn, GPR64pi:$Xm)>; 11111} 11112let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 11113multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 11114 RegisterOperand listtype, RegisterOperand GPR64pi> { 11115 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 11116 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 11117 GPR64sp:$Rn), []>; 11118 11119 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 11120 (outs GPR64sp:$wback), 11121 (ins listtype:$Vt, VectorIndexD:$idx, 11122 GPR64sp:$Rn, GPR64pi:$Xm)>; 11123} 11124 11125multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 11126 string Count, int Offset, Operand idxtype> { 11127 // E.g. "ld1 { v0.8b }[0], [x1], #1" 11128 // "ld1\t$Vt, [$Rn], #1" 11129 // may get mapped to 11130 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 11131 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 11132 (!cast<Instruction>(NAME # Type # "_POST") 11133 GPR64sp:$Rn, 11134 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 11135 idxtype:$idx, XZR), 1>; 11136 11137 // E.g. "ld1.8b { v0 }[0], [x1], #1" 11138 // "ld1.8b\t$Vt, [$Rn], #1" 11139 // may get mapped to 11140 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 11141 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 11142 (!cast<Instruction>(NAME # Type # "_POST") 11143 GPR64sp:$Rn, 11144 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11145 idxtype:$idx, XZR), 0>; 11146 11147 // E.g. "ld1.8b { v0 }[0], [x1]" 11148 // "ld1.8b\t$Vt, [$Rn]" 11149 // may get mapped to 11150 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 11151 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 11152 (!cast<Instruction>(NAME # Type) 11153 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11154 idxtype:$idx, GPR64sp:$Rn), 0>; 11155 11156 // E.g. "ld1.8b { v0 }[0], [x1], x2" 11157 // "ld1.8b\t$Vt, [$Rn], $Xm" 11158 // may get mapped to 11159 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 11160 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 11161 (!cast<Instruction>(NAME # Type # "_POST") 11162 GPR64sp:$Rn, 11163 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 11164 idxtype:$idx, 11165 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 11166} 11167 11168multiclass SIMDLdSt1SingleAliases<string asm> { 11169 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 11170 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 11171 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 11172 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 11173} 11174 11175multiclass SIMDLdSt2SingleAliases<string asm> { 11176 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 11177 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 11178 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 11179 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 11180} 11181 11182multiclass SIMDLdSt3SingleAliases<string asm> { 11183 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 11184 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 11185 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 11186 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 11187} 11188 11189multiclass SIMDLdSt4SingleAliases<string asm> { 11190 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 11191 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 11192 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 11193 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 11194} 11195} // end of 'let Predicates = [HasNEON]' 11196 11197//---------------------------------------------------------------------------- 11198// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 11199//---------------------------------------------------------------------------- 11200 11201let Predicates = [HasNEON, HasRDM] in { 11202 11203class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 11204 RegisterOperand regtype, string asm, 11205 string kind, list<dag> pattern> 11206 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 11207 pattern> { 11208} 11209multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 11210 SDPatternOperator op> { 11211 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 11212 [(set (v4i16 V64:$dst), 11213 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 11214 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 11215 [(set (v8i16 V128:$dst), 11216 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 11217 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 11218 [(set (v2i32 V64:$dst), 11219 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 11220 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 11221 [(set (v4i32 V128:$dst), 11222 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 11223} 11224 11225multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 11226 SDPatternOperator op> { 11227 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 11228 V64, V64, V128_lo, VectorIndexH, 11229 asm, ".4h", ".4h", ".4h", ".h", 11230 [(set (v4i16 V64:$dst), 11231 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), 11232 (dup_v8i16 (v8i16 V128_lo:$Rm), 11233 VectorIndexH:$idx))))]> { 11234 bits<3> idx; 11235 let Inst{11} = idx{2}; 11236 let Inst{21} = idx{1}; 11237 let Inst{20} = idx{0}; 11238 } 11239 11240 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 11241 V128, V128, V128_lo, VectorIndexH, 11242 asm, ".8h", ".8h", ".8h", ".h", 11243 [(set (v8i16 V128:$dst), 11244 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), 11245 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 11246 VectorIndexH:$idx)))))]> { 11247 bits<3> idx; 11248 let Inst{11} = idx{2}; 11249 let Inst{21} = idx{1}; 11250 let Inst{20} = idx{0}; 11251 } 11252 11253 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 11254 V64, V64, V128, VectorIndexS, 11255 asm, ".2s", ".2s", ".2s", ".s", 11256 [(set (v2i32 V64:$dst), 11257 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), 11258 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 11259 bits<2> idx; 11260 let Inst{11} = idx{1}; 11261 let Inst{21} = idx{0}; 11262 } 11263 11264 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 11265 V128, V128, V128, VectorIndexS, 11266 asm, ".4s", ".4s", ".4s", ".s", 11267 [(set (v4i32 V128:$dst), 11268 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11269 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 11270 VectorIndexS:$idx)))))]> { 11271 bits<2> idx; 11272 let Inst{11} = idx{1}; 11273 let Inst{21} = idx{0}; 11274 } 11275 11276 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 11277 FPR16Op, FPR16Op, V128_lo, 11278 VectorIndexH, asm, ".h", "", "", ".h", 11279 []> { 11280 bits<3> idx; 11281 let Inst{11} = idx{2}; 11282 let Inst{21} = idx{1}; 11283 let Inst{20} = idx{0}; 11284 } 11285 11286 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 11287 FPR32Op, FPR32Op, V128, VectorIndexS, 11288 asm, ".s", "", "", ".s", 11289 [(set (i32 FPR32Op:$dst), 11290 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn), 11291 (i32 (vector_extract (v4i32 V128:$Rm), 11292 VectorIndexS:$idx)))))]> { 11293 bits<2> idx; 11294 let Inst{11} = idx{1}; 11295 let Inst{21} = idx{0}; 11296 } 11297} 11298} // let Predicates = [HasNeon, HasRDM] 11299 11300//---------------------------------------------------------------------------- 11301// ARMv8.3 Complex ADD/MLA instructions 11302//---------------------------------------------------------------------------- 11303 11304class ComplexRotationOperand<int Angle, int Remainder, string Type> 11305 : AsmOperandClass { 11306 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 11307 let DiagnosticType = "InvalidComplexRotation" # Type; 11308 let Name = "ComplexRotation" # Type; 11309} 11310def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11311 SDNodeXForm<imm, [{ 11312 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32); 11313}]>> { 11314 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 11315 let PrintMethod = "printComplexRotationOp<90, 0>"; 11316} 11317def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }], 11318 SDNodeXForm<imm, [{ 11319 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32); 11320}]>> { 11321 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 11322 let PrintMethod = "printComplexRotationOp<180, 90>"; 11323} 11324let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11325class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 11326 RegisterOperand regtype, Operand rottype, 11327 string asm, string kind, list<dag> pattern> 11328 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11329 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11330 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 11331 Sched<[!if(Q, WriteVq, WriteVd)]> { 11332 bits<5> Rd; 11333 bits<5> Rn; 11334 bits<5> Rm; 11335 bits<1> rot; 11336 let Inst{31} = 0; 11337 let Inst{30} = Q; 11338 let Inst{29} = U; 11339 let Inst{28-24} = 0b01110; 11340 let Inst{23-22} = size; 11341 let Inst{21} = 0; 11342 let Inst{20-16} = Rm; 11343 let Inst{15-13} = opcode; 11344 // Non-tied version (FCADD) only has one rotation bit 11345 let Inst{12} = rot; 11346 let Inst{11} = 0; 11347 let Inst{10} = 1; 11348 let Inst{9-5} = Rn; 11349 let Inst{4-0} = Rd; 11350} 11351 11352//8.3 CompNum - Floating-point complex number support 11353multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 11354 string asm, SDPatternOperator OpNode>{ 11355 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11356 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 11357 asm, ".4h", 11358 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11359 (v4f16 V64:$Rn), 11360 (v4f16 V64:$Rm), 11361 (i32 rottype:$rot)))]>; 11362 11363 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 11364 asm, ".8h", 11365 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11366 (v8f16 V128:$Rn), 11367 (v8f16 V128:$Rm), 11368 (i32 rottype:$rot)))]>; 11369 } 11370 11371 let Predicates = [HasComplxNum, HasNEON] in { 11372 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 11373 asm, ".2s", 11374 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11375 (v2f32 V64:$Rn), 11376 (v2f32 V64:$Rm), 11377 (i32 rottype:$rot)))]>; 11378 11379 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 11380 asm, ".4s", 11381 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11382 (v4f32 V128:$Rn), 11383 (v4f32 V128:$Rm), 11384 (i32 rottype:$rot)))]>; 11385 11386 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 11387 asm, ".2d", 11388 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11389 (v2f64 V128:$Rn), 11390 (v2f64 V128:$Rm), 11391 (i32 rottype:$rot)))]>; 11392 } 11393} 11394 11395let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11396class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 11397 bits<3> opcode, 11398 RegisterOperand regtype, 11399 Operand rottype, string asm, 11400 string kind, list<dag> pattern> 11401 : I<(outs regtype:$dst), 11402 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 11403 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 11404 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 11405 Sched<[!if(Q, WriteVq, WriteVd)]> { 11406 bits<5> Rd; 11407 bits<5> Rn; 11408 bits<5> Rm; 11409 bits<2> rot; 11410 let Inst{31} = 0; 11411 let Inst{30} = Q; 11412 let Inst{29} = U; 11413 let Inst{28-24} = 0b01110; 11414 let Inst{23-22} = size; 11415 let Inst{21} = 0; 11416 let Inst{20-16} = Rm; 11417 let Inst{15-13} = opcode; 11418 let Inst{12-11} = rot; 11419 let Inst{10} = 1; 11420 let Inst{9-5} = Rn; 11421 let Inst{4-0} = Rd; 11422} 11423 11424multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 11425 Operand rottype, string asm, 11426 SDPatternOperator OpNode> { 11427 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11428 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 11429 rottype, asm, ".4h", 11430 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 11431 (v4f16 V64:$Rn), 11432 (v4f16 V64:$Rm), 11433 (i32 rottype:$rot)))]>; 11434 11435 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 11436 rottype, asm, ".8h", 11437 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 11438 (v8f16 V128:$Rn), 11439 (v8f16 V128:$Rm), 11440 (i32 rottype:$rot)))]>; 11441 } 11442 11443 let Predicates = [HasComplxNum, HasNEON] in { 11444 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 11445 rottype, asm, ".2s", 11446 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 11447 (v2f32 V64:$Rn), 11448 (v2f32 V64:$Rm), 11449 (i32 rottype:$rot)))]>; 11450 11451 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 11452 rottype, asm, ".4s", 11453 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 11454 (v4f32 V128:$Rn), 11455 (v4f32 V128:$Rm), 11456 (i32 rottype:$rot)))]>; 11457 11458 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 11459 rottype, asm, ".2d", 11460 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 11461 (v2f64 V128:$Rn), 11462 (v2f64 V128:$Rm), 11463 (i32 rottype:$rot)))]>; 11464 } 11465} 11466 11467let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in 11468class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 11469 bit opc1, bit opc2, RegisterOperand dst_reg, 11470 RegisterOperand lhs_reg, 11471 RegisterOperand rhs_reg, Operand vec_idx, 11472 Operand rottype, string asm, string apple_kind, 11473 string dst_kind, string lhs_kind, 11474 string rhs_kind, list<dag> pattern> 11475 : I<(outs dst_reg:$dst), 11476 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 11477 asm, 11478 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 11479 "$idx, $rot" # "|" # apple_kind # 11480 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 11481 Sched<[!if(Q, WriteVq, WriteVd)]> { 11482 bits<5> Rd; 11483 bits<5> Rn; 11484 bits<5> Rm; 11485 bits<2> rot; 11486 11487 let Inst{31} = 0; 11488 let Inst{30} = Q; 11489 let Inst{29} = U; 11490 let Inst{28} = Scalar; 11491 let Inst{27-24} = 0b1111; 11492 let Inst{23-22} = size; 11493 // Bit 21 must be set by the derived class. 11494 let Inst{20-16} = Rm; 11495 let Inst{15} = opc1; 11496 let Inst{14-13} = rot; 11497 let Inst{12} = opc2; 11498 // Bit 11 must be set by the derived class. 11499 let Inst{10} = 0; 11500 let Inst{9-5} = Rn; 11501 let Inst{4-0} = Rd; 11502} 11503 11504// The complex instructions index by pairs of elements, so the VectorIndexes 11505// don't match the lane types, and the index bits are different to the other 11506// classes. 11507multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype, 11508 string asm> { 11509 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 11510 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 11511 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 11512 ".4h", ".h", []> { 11513 bits<1> idx; 11514 let Inst{11} = 0; 11515 let Inst{21} = idx{0}; 11516 } 11517 11518 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 11519 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 11520 ".8h", ".8h", ".h", []> { 11521 bits<2> idx; 11522 let Inst{11} = idx{1}; 11523 let Inst{21} = idx{0}; 11524 } 11525 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 11526 11527 let Predicates = [HasComplxNum, HasNEON] in { 11528 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 11529 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 11530 ".4s", ".4s", ".s", []> { 11531 bits<1> idx; 11532 let Inst{11} = idx{0}; 11533 let Inst{21} = 0; 11534 } 11535 } // Predicates = [HasComplxNum, HasNEON] 11536} 11537 11538//---------------------------------------------------------------------------- 11539// Crypto extensions 11540//---------------------------------------------------------------------------- 11541 11542let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11543class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 11544 list<dag> pat> 11545 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 11546 Sched<[WriteVq]>{ 11547 bits<5> Rd; 11548 bits<5> Rn; 11549 let Inst{31-16} = 0b0100111000101000; 11550 let Inst{15-12} = opc; 11551 let Inst{11-10} = 0b10; 11552 let Inst{9-5} = Rn; 11553 let Inst{4-0} = Rd; 11554} 11555 11556class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 11557 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 11558 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 11559 11560class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 11561 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 11562 "$Rd = $dst", 11563 [(set (v16i8 V128:$dst), 11564 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 11565 11566let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11567class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 11568 dag oops, dag iops, list<dag> pat> 11569 : I<oops, iops, asm, 11570 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 11571 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 11572 Sched<[WriteVq]>{ 11573 bits<5> Rd; 11574 bits<5> Rn; 11575 bits<5> Rm; 11576 let Inst{31-21} = 0b01011110000; 11577 let Inst{20-16} = Rm; 11578 let Inst{15} = 0; 11579 let Inst{14-12} = opc; 11580 let Inst{11-10} = 0b00; 11581 let Inst{9-5} = Rn; 11582 let Inst{4-0} = Rd; 11583} 11584 11585class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 11586 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11587 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 11588 [(set (v4i32 FPR128:$dst), 11589 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 11590 (v4i32 V128:$Rm)))]>; 11591 11592class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 11593 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 11594 (ins V128:$Rd, V128:$Rn, V128:$Rm), 11595 [(set (v4i32 V128:$dst), 11596 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 11597 (v4i32 V128:$Rm)))]>; 11598 11599class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 11600 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 11601 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 11602 [(set (v4i32 FPR128:$dst), 11603 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 11604 (v4i32 V128:$Rm)))]>; 11605 11606let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 11607class SHA2OpInst<bits<4> opc, string asm, string kind, 11608 string cstr, dag oops, dag iops, 11609 list<dag> pat> 11610 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 11611 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 11612 Sched<[WriteVq]>{ 11613 bits<5> Rd; 11614 bits<5> Rn; 11615 let Inst{31-16} = 0b0101111000101000; 11616 let Inst{15-12} = opc; 11617 let Inst{11-10} = 0b10; 11618 let Inst{9-5} = Rn; 11619 let Inst{4-0} = Rd; 11620} 11621 11622class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 11623 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 11624 (ins V128:$Rd, V128:$Rn), 11625 [(set (v4i32 V128:$dst), 11626 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 11627 11628class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 11629 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 11630 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 11631 11632// Armv8.2-A Crypto extensions 11633class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 11634 list<dag> pattern> 11635 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> { 11636 bits<5> Vd; 11637 bits<5> Vn; 11638 let Inst{31-25} = 0b1100111; 11639 let Inst{9-5} = Vn; 11640 let Inst{4-0} = Vd; 11641} 11642 11643class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 11644 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops, 11645 "$Vd = $Vdst", []> { 11646 let Inst{31-25} = 0b1100111; 11647 let Inst{24-21} = 0b0110; 11648 let Inst{20-15} = 0b000001; 11649 let Inst{14} = op0; 11650 let Inst{13-12} = 0b00; 11651 let Inst{11-10} = op1; 11652} 11653class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 11654 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">; 11655class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 11656 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">; 11657 11658class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 11659 string asmops, string cst> 11660 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 11661 bits<5> Vm; 11662 let Inst{24-21} = 0b0011; 11663 let Inst{20-16} = Vm; 11664 let Inst{15} = 0b1; 11665 let Inst{14} = op0; 11666 let Inst{13-12} = 0b00; 11667 let Inst{11-10} = op1; 11668} 11669class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 11670 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11671 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">; 11672class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 11673 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11674 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11675class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 11676 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 11677 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">; 11678class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 11679 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 11680 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11681class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 11682 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 11683 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">; 11684 11685class CryptoRRRR<bits<2>op0, string asm, string asmops> 11686 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 11687 asmops, "", []> { 11688 bits<5> Vm; 11689 bits<5> Va; 11690 let Inst{24-23} = 0b00; 11691 let Inst{22-21} = op0; 11692 let Inst{20-16} = Vm; 11693 let Inst{15} = 0b0; 11694 let Inst{14-10} = Va; 11695} 11696class CryptoRRRR_16B<bits<2>op0, string asm> 11697 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" # 11698 "|.16b\t$Vd, $Vn, $Vm, $Va}"> { 11699} 11700class CryptoRRRR_4S<bits<2>op0, string asm> 11701 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" # 11702 "|.4s\t$Vd, $Vn, $Vm, $Va}"> { 11703} 11704 11705class CryptoRRRi6<string asm> 11706 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 11707 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" # 11708 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> { 11709 bits<6> imm; 11710 bits<5> Vm; 11711 let Inst{24-21} = 0b0100; 11712 let Inst{20-16} = Vm; 11713 let Inst{15-10} = imm; 11714 let Inst{9-5} = Vn; 11715 let Inst{4-0} = Vd; 11716} 11717 11718class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 11719 : BaseCryptoV82<(outs V128:$Vdst), 11720 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 11721 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" # 11722 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> { 11723 bits<2> imm; 11724 bits<5> Vm; 11725 let Inst{24-21} = 0b0010; 11726 let Inst{20-16} = Vm; 11727 let Inst{15} = 0b1; 11728 let Inst{14} = op0; 11729 let Inst{13-12} = imm; 11730 let Inst{11-10} = op1; 11731} 11732 11733//---------------------------------------------------------------------------- 11734// v8.1 atomic instructions extension: 11735// * CAS 11736// * CASP 11737// * SWP 11738// * LDOPregister<OP>, and aliases STOPregister<OP> 11739 11740// Instruction encodings: 11741// 11742// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 11743// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 11744// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 11745// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 11746// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 11747// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 11748 11749// Instruction syntax: 11750// 11751// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11752// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 11753// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 11754// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 11755// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11756// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 11757// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 11758// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 11759// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 11760// ST<OP>{<order>} <Xs>, [<Xn|SP>] 11761 11762let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11763class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 11764 string cstr, list<dag> pattern> 11765 : I<oops, iops, asm, operands, cstr, pattern> { 11766 bits<2> Sz; 11767 bit NP; 11768 bit Acq; 11769 bit Rel; 11770 bits<5> Rs; 11771 bits<5> Rn; 11772 bits<5> Rt; 11773 let Inst{31-30} = Sz; 11774 let Inst{29-24} = 0b001000; 11775 let Inst{23} = NP; 11776 let Inst{22} = Acq; 11777 let Inst{21} = 0b1; 11778 let Inst{20-16} = Rs; 11779 let Inst{15} = Rel; 11780 let Inst{14-10} = 0b11111; 11781 let Inst{9-5} = Rn; 11782 let Inst{4-0} = Rt; 11783 let Predicates = [HasLSE]; 11784} 11785 11786class BaseCAS<string order, string size, RegisterClass RC> 11787 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11788 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 11789 "$out = $Rs",[]>, 11790 Sched<[WriteAtomic]> { 11791 let NP = 1; 11792} 11793 11794multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 11795 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 11796 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 11797 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 11798 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 11799} 11800 11801class BaseCASP<string order, string size, RegisterOperand RC> 11802 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 11803 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 11804 "$out = $Rs",[]>, 11805 Sched<[WriteAtomic]> { 11806 let NP = 0; 11807} 11808 11809multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 11810 let Sz = 0b00, Acq = Acq, Rel = Rel in 11811 def W : BaseCASP<order, "", WSeqPairClassOperand>; 11812 let Sz = 0b01, Acq = Acq, Rel = Rel in 11813 def X : BaseCASP<order, "", XSeqPairClassOperand>; 11814} 11815 11816let Predicates = [HasLSE] in 11817class BaseSWP<string order, string size, RegisterClass RC> 11818 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 11819 "\t$Rs, $Rt, [$Rn]","",[]>, 11820 Sched<[WriteAtomic]> { 11821 bits<2> Sz; 11822 bit Acq; 11823 bit Rel; 11824 bits<5> Rs; 11825 bits<3> opc = 0b000; 11826 bits<5> Rn; 11827 bits<5> Rt; 11828 let Inst{31-30} = Sz; 11829 let Inst{29-24} = 0b111000; 11830 let Inst{23} = Acq; 11831 let Inst{22} = Rel; 11832 let Inst{21} = 0b1; 11833 let Inst{20-16} = Rs; 11834 let Inst{15} = 0b1; 11835 let Inst{14-12} = opc; 11836 let Inst{11-10} = 0b00; 11837 let Inst{9-5} = Rn; 11838 let Inst{4-0} = Rt; 11839 let Predicates = [HasLSE]; 11840} 11841 11842multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 11843 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 11844 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 11845 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 11846 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 11847} 11848 11849let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 11850class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 11851 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 11852 "\t$Rs, $Rt, [$Rn]","",[]>, 11853 Sched<[WriteAtomic]> { 11854 bits<2> Sz; 11855 bit Acq; 11856 bit Rel; 11857 bits<5> Rs; 11858 bits<3> opc; 11859 bits<5> Rn; 11860 bits<5> Rt; 11861 let Inst{31-30} = Sz; 11862 let Inst{29-24} = 0b111000; 11863 let Inst{23} = Acq; 11864 let Inst{22} = Rel; 11865 let Inst{21} = 0b1; 11866 let Inst{20-16} = Rs; 11867 let Inst{15} = 0b0; 11868 let Inst{14-12} = opc; 11869 let Inst{11-10} = 0b00; 11870 let Inst{9-5} = Rn; 11871 let Inst{4-0} = Rt; 11872 let Predicates = [HasLSE]; 11873} 11874 11875multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 11876 string order> { 11877 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 11878 def B : BaseLDOPregister<op, order, "b", GPR32>; 11879 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 11880 def H : BaseLDOPregister<op, order, "h", GPR32>; 11881 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 11882 def W : BaseLDOPregister<op, order, "", GPR32>; 11883 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 11884 def X : BaseLDOPregister<op, order, "", GPR64>; 11885} 11886 11887// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 11888// complex DAG for DstRHS. 11889let Predicates = [HasLSE] in 11890multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 11891 ValueType vt, dag SrcRHS, dag DstRHS> { 11892 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, SrcRHS), 11893 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 11894 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, SrcRHS), 11895 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 11896 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, SrcRHS), 11897 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 11898 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, SrcRHS), 11899 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11900 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, SrcRHS), 11901 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 11902} 11903 11904multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 11905 ValueType vt, dag RHS> { 11906 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS, RHS>; 11907} 11908 11909multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 11910 ValueType vt, dag LHS, dag RHS> { 11911 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, LHS, RHS>; 11912} 11913 11914multiclass LDOPregister_patterns<string inst, string op> { 11915 defm : LDOPregister_patterns_ord<inst, "X", op, i64, (i64 GPR64:$Rm)>; 11916 defm : LDOPregister_patterns_ord<inst, "W", op, i32, (i32 GPR32:$Rm)>; 11917 defm : LDOPregister_patterns_ord<inst, "H", op, i16, (i32 GPR32:$Rm)>; 11918 defm : LDOPregister_patterns_ord<inst, "B", op, i8, (i32 GPR32:$Rm)>; 11919} 11920 11921multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 11922 defm : LDOPregister_patterns_ord_mod<inst, "X", op, i64, 11923 (i64 GPR64:$Rm), 11924 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 11925 defm : LDOPregister_patterns_ord_mod<inst, "W", op, i32, 11926 (i32 GPR32:$Rm), 11927 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11928 defm : LDOPregister_patterns_ord_mod<inst, "H", op, i16, 11929 (i32 GPR32:$Rm), 11930 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11931 defm : LDOPregister_patterns_ord_mod<inst, "B", op, i8, 11932 (i32 GPR32:$Rm), 11933 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 11934} 11935 11936let Predicates = [HasLSE] in 11937multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 11938 ValueType vt, dag OLD, dag NEW> { 11939 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, OLD, NEW), 11940 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 11941 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, OLD, NEW), 11942 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11943 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, OLD, NEW), 11944 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11945 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 11946 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11947 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 11948 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 11949} 11950 11951multiclass CASregister_patterns_ord<string inst, string suffix, string op, 11952 ValueType vt, dag OLD, dag NEW> { 11953 defm : CASregister_patterns_ord_dag<inst, suffix, op, vt, OLD, NEW>; 11954} 11955 11956multiclass CASregister_patterns<string inst, string op> { 11957 defm : CASregister_patterns_ord<inst, "X", op, i64, 11958 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 11959 defm : CASregister_patterns_ord<inst, "W", op, i32, 11960 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11961 defm : CASregister_patterns_ord<inst, "H", op, i16, 11962 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11963 defm : CASregister_patterns_ord<inst, "B", op, i8, 11964 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 11965} 11966 11967let Predicates = [HasLSE] in 11968class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 11969 Instruction inst> : 11970 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 11971 11972multiclass STOPregister<string asm, string instr> { 11973 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 11974 !cast<Instruction>(instr # "LB")>; 11975 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 11976 !cast<Instruction>(instr # "LH")>; 11977 def : BaseSTOPregister<asm # "l", GPR32, WZR, 11978 !cast<Instruction>(instr # "LW")>; 11979 def : BaseSTOPregister<asm # "l", GPR64, XZR, 11980 !cast<Instruction>(instr # "LX")>; 11981 def : BaseSTOPregister<asm # "b", GPR32, WZR, 11982 !cast<Instruction>(instr # "B")>; 11983 def : BaseSTOPregister<asm # "h", GPR32, WZR, 11984 !cast<Instruction>(instr # "H")>; 11985 def : BaseSTOPregister<asm, GPR32, WZR, 11986 !cast<Instruction>(instr # "W")>; 11987 def : BaseSTOPregister<asm, GPR64, XZR, 11988 !cast<Instruction>(instr # "X")>; 11989} 11990 11991class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops, 11992 dag iops, dag oops, list<dag> pat> 11993 : I<oops, iops, asm_inst, asm_ops, "", pat>, 11994 Sched<[]> /* FIXME: fill in scheduling details once known */ { 11995 bits<5> Rt; 11996 bits<5> Rn; 11997 let Inst{31-21} = 0b11111000001; 11998 let Inst{15} = 1; 11999 let Inst{14-12} = opc; 12000 let Inst{11-10} = 0b00; 12001 let Inst{9-5} = Rn; 12002 let Inst{4-0} = Rt; 12003 12004 let Predicates = [HasV8_7a]; 12005} 12006 12007class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops, 12008 list<dag> pat = []> 12009 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> { 12010 let Inst{20-16} = 0b11111; 12011} 12012 12013class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []> 12014 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]", 12015 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> { 12016 bits<5> Rs; 12017 let Inst{20-16} = Rs; 12018} 12019 12020class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1, 12021 bits<2> op2, string asm> 12022 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb), 12023 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn), 12024 asm, "\t[$Rd]!, [$Rs]!, $Rn!", 12025 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>, 12026 Sched<[]> { 12027 bits<5> Rd; 12028 bits<5> Rs; 12029 bits<5> Rn; 12030 let Inst{31-27} = 0b00011; 12031 let Inst{26} = isMove; 12032 let Inst{25-24} = 0b01; 12033 let Inst{23-22} = opcode; 12034 let Inst{21} = 0b0; 12035 let Inst{20-16} = Rs; 12036 let Inst{15-14} = op2; 12037 let Inst{13-12} = op1; 12038 let Inst{11-10} = 0b01; 12039 let Inst{9-5} = Rn; 12040 let Inst{4-0} = Rd; 12041 12042 let DecoderMethod = "DecodeCPYMemOpInstruction"; 12043 let mayLoad = 1; 12044 let mayStore = 1; 12045} 12046 12047class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 12048 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>; 12049 12050class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm> 12051 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>; 12052 12053class MOPSMemorySetBase<bit isTagging, bits<2> opcode, bit op1, bit op2, 12054 string asm> 12055 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), 12056 (ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm), 12057 asm, "\t[$Rd]!, $Rn!, $Rm", 12058 "$Rd = $Rd_wb,$Rn = $Rn_wb", []>, 12059 Sched<[]> { 12060 bits<5> Rd; 12061 bits<5> Rn; 12062 bits<5> Rm; 12063 let Inst{31-27} = 0b00011; 12064 let Inst{26} = isTagging; 12065 let Inst{25-21} = 0b01110; 12066 let Inst{20-16} = Rm; 12067 let Inst{15-14} = opcode; 12068 let Inst{13} = op2; 12069 let Inst{12} = op1; 12070 let Inst{11-10} = 0b01; 12071 let Inst{9-5} = Rn; 12072 let Inst{4-0} = Rd; 12073 12074 let DecoderMethod = "DecodeSETMemOpInstruction"; 12075 let mayLoad = 0; 12076 let mayStore = 1; 12077} 12078 12079class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, string asm> 12080 : MOPSMemorySetBase<0, opcode, op1, op2, asm>; 12081 12082class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, string asm> 12083 : MOPSMemorySetBase<1, opcode, op1, op2, asm>; 12084 12085multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> { 12086 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>; 12087 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">; 12088 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">; 12089 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">; 12090 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">; 12091 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">; 12092 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">; 12093 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">; 12094 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">; 12095 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">; 12096 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">; 12097 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">; 12098 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">; 12099 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">; 12100 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">; 12101 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">; 12102} 12103 12104multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> { 12105 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>; 12106 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">; 12107 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">; 12108 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">; 12109 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">; 12110 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">; 12111 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">; 12112 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">; 12113 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">; 12114 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">; 12115 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">; 12116 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">; 12117 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">; 12118 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">; 12119 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">; 12120 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">; 12121} 12122 12123multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> { 12124 def "" : MOPSMemorySet<opcode, 0, 0, asm>; 12125 def T : MOPSMemorySet<opcode, 1, 0, asm # "t">; 12126 def N : MOPSMemorySet<opcode, 0, 1, asm # "n">; 12127 def TN : MOPSMemorySet<opcode, 1, 1, asm # "tn">; 12128} 12129 12130multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> { 12131 def "" : MOPSMemorySetTagging<opcode, 0, 0, asm>; 12132 def T : MOPSMemorySetTagging<opcode, 1, 0, asm # "t">; 12133 def N : MOPSMemorySetTagging<opcode, 0, 1, asm # "n">; 12134 def TN : MOPSMemorySetTagging<opcode, 1, 1, asm # "tn">; 12135} 12136 12137//---------------------------------------------------------------------------- 12138// 2022 Armv8.9/Armv9.4 Extensions 12139//---------------------------------------------------------------------------- 12140 12141//--- 12142// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC) 12143//--- 12144 12145class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc, 12146 RegisterClass regtype, ImmLeaf immtype, string asm, 12147 SDPatternOperator OpNode> 12148 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm), 12149 asm, "\t$Rd, $Rn, $imm", "", 12150 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> { 12151 bits<5> Rd; 12152 bits<5> Rn; 12153 bits<8> imm; 12154 12155 let Inst{31} = sf; 12156 let Inst{30} = Op; 12157 let Inst{29} = S; 12158 let Inst{28-22} = 0b1000111; 12159 let Inst{21-18} = opc; 12160 let Inst{17-10} = imm; 12161 let Inst{9-5} = Rn; 12162 let Inst{4-0} = Rd; 12163} 12164 12165class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin, 12166 RegisterClass regtype, string asm, 12167 SDPatternOperator OpNode> 12168 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>, 12169 Sched<[WriteI]> { 12170 let Inst{11} = isMin; 12171 let Inst{10} = isUnsigned; 12172 let mayLoad = 0; 12173 let mayStore = 0; 12174 let hasSideEffects = 0; 12175} 12176 12177class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin, 12178 RegisterClass regtype, ImmLeaf immtype, string asm, 12179 SDPatternOperator OpNode> 12180 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm, 12181 OpNode>, 12182 Sched<[]> { 12183 let Inst{19} = isMin; 12184 let Inst{18} = isUnsigned; 12185 let mayLoad = 0; 12186 let mayStore = 0; 12187 let hasSideEffects = 0; 12188} 12189 12190multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm, 12191 SDPatternOperator OpNode = null_frag> { 12192 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>; 12193 12194 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32, 12195 !cond(isUnsigned : uimm8_32b, 12196 !not(isUnsigned) : simm8_32b), asm, OpNode>; 12197 12198 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>; 12199 12200 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64, 12201 !cond(isUnsigned : uimm8_64b, 12202 !not(isUnsigned) : simm8_64b), asm, OpNode>; 12203} 12204 12205//--- 12206// RCPC instructions (FEAT_LRCPC3) 12207//--- 12208 12209class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops, 12210 string asm, string operands, string cstr = ""> 12211 : I<oops, iops, asm, operands, cstr, []>, 12212 Sched<[WriteAtomic]> { 12213 bits<5> Rt; 12214 bits<5> Rn; 12215 let Inst{31-30} = size; 12216 let Inst{29-24} = {0,1,1,V,0,1}; 12217 let Inst{23-22} = opc; 12218 let Inst{21} = 0b0; 12219 // Inst{20-12} 12220 let Inst{11-10} = 0b10; 12221 let Inst{9-5} = Rn; 12222 let Inst{4-0} = Rt; 12223 12224 let mayLoad = Inst{22}; 12225 let mayStore = !not(Inst{22}); 12226 let hasSideEffects = 0; 12227} 12228 12229class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2, 12230 dag oops, dag iops, string asm, 12231 string operands, string cstr> 12232 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12233 bits<5> Rt2; 12234 let Inst{20-16} = Rt2; 12235 let Inst{15-12} = opc2; 12236} 12237 12238class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops, 12239 string asm, string operands, string cstr> 12240 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> { 12241 let Inst{20-12} = 0b000000000; // imm9 12242} 12243 12244multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype, 12245 dag oops, dag iops, string asm> { 12246 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> { 12247 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm4 12248 let Inst{20-12} = simm; 12249 } 12250 12251 def a : InstAlias<asm # "\t$Rt, [$Rn]", 12252 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 12253} 12254 12255class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst> 12256 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm, 12257 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>, 12258 Sched<[]> { 12259 bit Q; 12260 let Inst{31} = 0; 12261 let Inst{30} = Q; 12262 let Inst{23} = 0; 12263 let Inst{20-16} = 0b00001; 12264 let Inst{12} = 0; // S 12265 let Inst{11-10} = 0b01; // size 12266 12267 let mayLoad = L; 12268 let mayStore = !not(L); 12269 let hasSideEffects = 1; 12270} 12271 12272//--- 12273// Instrumentation Extension (FEAT_ITE) 12274//--- 12275 12276let Predicates = [HasITE] in 12277def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> { 12278 let Inst{20-19} = 0b01; 12279 let Inst{18-16} = 0b011; 12280 let Inst{15-12} = 0b0111; 12281 let Inst{11-8} = 0b0010; 12282 let Inst{7-5} = 0b111; 12283} 12284 12285// * RCWCAS family 12286// * RCW<OP> family 12287 12288//-------------------------------------------------------------------- 12289// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?) 12290 12291// Instruction encoding: 12292// 12293// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 0 12294// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12295// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt 12296// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12297// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt 12298 12299// Instruction syntax: 12300// 12301// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 12302// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>] 12303 12304class BaseRCWCASEncoding<dag oops, dag iops, string asm> 12305 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>, 12306 Sched<[]> { 12307 bit Acq; 12308 bit Rel; 12309 bit SC; 12310 bit Pair; 12311 bits<5> Rs; 12312 bits<5> Rn; 12313 bits<5> Rt; 12314 let Inst{31} = 0b0; 12315 let Inst{30} = SC; 12316 let Inst{29-24} = 0b011001; 12317 let Inst{23} = Acq; 12318 let Inst{22} = Rel; 12319 let Inst{21} = 0b1; 12320 let Inst{20-16} = Rs; 12321 let Inst{15-13} = 0b000; 12322 let Inst{12-11} = 0b01; 12323 let Inst{10} = Pair; 12324 let Inst{9-5} = Rn; 12325 let Inst{4-0} = Rt; 12326 let mayLoad = 1; 12327 let mayStore = 1; 12328 let hasSideEffects = 1; 12329 let Defs = [NZCV]; 12330} 12331 12332multiclass BaseRCWCAS<dag oops, dag iops, string prefix> { 12333 let Acq = 0b0, Rel = 0b0 in 12334 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">; 12335 let Acq = 0b1, Rel = 0b0 in 12336 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">; 12337 let Acq = 0b0, Rel = 0b1 in 12338 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">; 12339 let Acq = 0b1, Rel = 0b1 in 12340 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">; 12341} 12342 12343multiclass ReadCheckWriteCompareAndSwap { 12344 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in 12345 defm CAS : BaseRCWCAS<(outs GPR64:$out), 12346 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >; 12347 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in 12348 defm SCAS : BaseRCWCAS<(outs GPR64:$out), 12349 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">; 12350 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12351 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12352 (ins XSeqPairClassOperand:$Rs, 12353 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12354 "rcwcasp">; 12355 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in 12356 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out), 12357 (ins XSeqPairClassOperand:$Rs, 12358 XSeqPairClassOperand:$Rt, GPR64sp:$Rn), 12359 "rcwscasp">; 12360} 12361 12362//------------------------------------------------------------------ 12363// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?) 12364 12365// Instruction encoding: 12366// 12367// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12368// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12369// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt 12370// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12371// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt 12372// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12373// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt 12374 12375// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 0 12376// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12377// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt 12378// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12379// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt 12380// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12381// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt 12382 12383// Instruction syntax: 12384// 12385// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 12386// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>] 12387 12388class BaseRCWOPEncoding<string asm> 12389 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm, 12390 "\t$Rs, $Rt, [$Rn]", "", []>, 12391 Sched<[]> { 12392 bit Acq; 12393 bit Rel; 12394 bit SC; 12395 bits<3> opc; 12396 bits<5> Rs; 12397 bits<5> Rn; 12398 bits<5> Rt; 12399 let Inst{31} = 0b0; 12400 let Inst{30} = SC; 12401 let Inst{29-24} = 0b111000; 12402 let Inst{23} = Acq; 12403 let Inst{22} = Rel; 12404 let Inst{21} = 0b1; 12405 let Inst{20-16} = Rs; 12406 let Inst{15} = 0b1; 12407 let Inst{14-12} = opc; 12408 let Inst{11-10} = 0b00; 12409 let Inst{9-5} = Rn; 12410 let Inst{4-0} = Rt; 12411 let mayLoad = 1; 12412 let mayStore = 1; 12413 let hasSideEffects = 1; 12414 let Defs = [NZCV]; 12415 let Predicates = [HasTHE]; 12416} 12417 12418class BaseRCWOPPEncoding<string asm> 12419 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12420 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm, 12421 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12422 Sched<[]> { 12423 bit Acq; 12424 bit Rel; 12425 bit SC; 12426 bits<3> opc; 12427 bits<5> Rt2; 12428 bits<5> Rn; 12429 bits<5> Rt; 12430 let Inst{31} = 0b0; 12431 let Inst{30} = SC; 12432 let Inst{29-24} = 0b011001; 12433 let Inst{23} = Acq; 12434 let Inst{22} = Rel; 12435 let Inst{21} = 0b1; 12436 let Inst{20-16} = Rt2; 12437 let Inst{15} = 0b1; 12438 let Inst{14-12} = opc; 12439 let Inst{11-10} = 0b00; 12440 let Inst{9-5} = Rn; 12441 let Inst{4-0} = Rt; 12442 let mayLoad = 1; 12443 let mayStore = 1; 12444 let hasSideEffects = 1; 12445 let Defs = [NZCV]; 12446 let Predicates = [HasTHE, HasD128]; 12447} 12448 12449multiclass BaseRCWOP<string prefix> { 12450 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">; 12451 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">; 12452 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">; 12453 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">; 12454 12455 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">; 12456 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">; 12457 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">; 12458 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">; 12459} 12460 12461multiclass ReadCheckWriteOperation<bits<3> opc, string op> { 12462 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>; 12463 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >; 12464} 12465 12466//--- 12467// 128-bit atomic instructions (FEAT_LSE128) 12468//--- 12469 12470let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in 12471class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm> 12472: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb), 12473 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), 12474 asm, "\t$Rt, $Rt2, [$Rn]", 12475 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>, 12476 Sched<[]> { 12477 bits<5> Rt; 12478 bits<5> Rt2; 12479 bits<5> Rn; 12480 let Inst{31-24} = 0b00011001; 12481 let Inst{23-22} = AR; 12482 let Inst{21} = 0b1; 12483 let Inst{20-16} = Rt2; 12484 let Inst{15} = o3; 12485 let Inst{14-12} = op0; 12486 let Inst{11-10} = 0b00; 12487 let Inst{9-5} = Rn; 12488 let Inst{4-0} = Rt; 12489} 12490 12491//--- 12492// 128-bit System Instructions (FEAT_SYSINSTR128) 12493//--- 12494 12495// Instruction encoding: 12496// 12497// 31 19|18 16|15 12|11 8|7 5|4 0 12498// SYSP 1101010101001| op1| Cn| Cm|op2| Rt 12499 12500// Instruction syntax: 12501// 12502// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>} 12503 12504class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> : 12505 RtSystemI<L, oops, iops, asm, operands, pattern> { 12506 let Inst{22} = 0b1; // override BaseSystemI 12507} 12508 12509class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs> 12510 : RtSystemI128<L, outputs, inputs, asm, operands> { 12511 bits<3> op1; 12512 bits<4> Cn; 12513 bits<4> Cm; 12514 bits<3> op2; 12515 let Inst{20-19} = 0b01; 12516 let Inst{18-16} = op1; 12517 let Inst{15-12} = Cn; 12518 let Inst{11-8} = Cm; 12519 let Inst{7-5} = op2; 12520} 12521class SystemPXtI<bit L, string asm> : 12522 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs), 12523 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>; 12524 12525//---------------------------------------------------------------------------- 12526// 2023 Armv9.5 Extensions 12527//---------------------------------------------------------------------------- 12528 12529//--- 12530// Checked Pointer Arithmetic (FEAT_CPA) 12531//--- 12532 12533def LSLImm3ShiftOperand : AsmOperandClass { 12534 let SuperClasses = [ExtendOperandLSL64]; 12535 let Name = "LSLImm3Shift"; 12536 let RenderMethod = "addLSLImm3ShifterOperands"; 12537 let DiagnosticType = "AddSubLSLImm3ShiftLarge"; 12538} 12539 12540def lsl_imm3_shift_operand : Operand<i32> { 12541 let PrintMethod = "printShifter"; 12542 let ParserMatchClass = LSLImm3ShiftOperand; 12543} 12544 12545// Base CPA scalar add/subtract with lsl #imm3 shift 12546class BaseAddSubCPA<bit isSub, string asm> : I<(outs GPR64sp:$Rd), 12547 (ins GPR64sp:$Rn, GPR64:$Rm, lsl_imm3_shift_operand:$shift_imm), 12548 asm, "\t$Rd, $Rn, $Rm$shift_imm", "", []>, Sched<[]> { 12549 bits<5> Rd; 12550 bits<5> Rn; 12551 bits<5> Rm; 12552 bits<3> shift_imm; 12553 let Inst{31} = 0b1; 12554 let Inst{30} = isSub; 12555 let Inst{29-21} = 0b011010000; 12556 let Inst{20-16} = Rm; 12557 let Inst{15-13} = 0b001; 12558 let Inst{12-10} = shift_imm; 12559 let Inst{9-5} = Rn; 12560 let Inst{4-0} = Rd; 12561} 12562 12563// Alias for CPA scalar add/subtract with no shift 12564class AddSubCPAAlias<string asm, Instruction inst> 12565 : InstAlias<asm#"\t$Rd, $Rn, $Rm", 12566 (inst GPR64sp:$Rd, GPR64sp:$Rn, GPR64:$Rm, 0)>; 12567 12568multiclass AddSubCPA<bit isSub, string asm> { 12569 def _shift : BaseAddSubCPA<isSub, asm>; 12570 def _noshift : AddSubCPAAlias<asm, !cast<Instruction>(NAME#"_shift")>; 12571} 12572 12573class MulAccumCPA<bit isSub, string asm> 12574 : BaseMulAccum<isSub, 0b011, GPR64, GPR64, asm, []>, Sched<[]> { 12575 let Inst{31} = 0b1; 12576} 12577 12578//---------------------------------------------------------------------------- 12579// Allow the size specifier tokens to be upper case, not just lower. 12580def : TokenAlias<".4B", ".4b">; // Add dot product 12581def : TokenAlias<".8B", ".8b">; 12582def : TokenAlias<".4H", ".4h">; 12583def : TokenAlias<".2S", ".2s">; 12584def : TokenAlias<".1D", ".1d">; 12585def : TokenAlias<".16B", ".16b">; 12586def : TokenAlias<".8H", ".8h">; 12587def : TokenAlias<".4S", ".4s">; 12588def : TokenAlias<".2D", ".2d">; 12589def : TokenAlias<".1Q", ".1q">; 12590def : TokenAlias<".2H", ".2h">; 12591def : TokenAlias<".2B", ".2b">; 12592def : TokenAlias<".B", ".b">; 12593def : TokenAlias<".H", ".h">; 12594def : TokenAlias<".S", ".s">; 12595def : TokenAlias<".D", ".d">; 12596def : TokenAlias<".Q", ".q">; 12597