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// AArch64 Instruction Format 24class AArch64Inst<Format f, string cstr> : Instruction { 25 field bits<32> Inst; // Instruction encoding. 26 // Mask of bits that cause an encoding to be UNPREDICTABLE. 27 // If a bit is set, then if the corresponding bit in the 28 // target encoding differs from its value in the "Inst" field, 29 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 30 field bits<32> Unpredictable = 0; 31 // SoftFail is the generic name for this field, but we alias it so 32 // as to make it more obvious what it means in ARM-land. 33 field bits<32> SoftFail = Unpredictable; 34 let Namespace = "AArch64"; 35 Format F = f; 36 bits<2> Form = F.Value; 37 let Pattern = []; 38 let Constraints = cstr; 39} 40 41class InstSubst<string Asm, dag Result, bit EmitPriority = 0> 42 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>; 43 44// Pseudo instructions (don't have encoding information) 45class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 46 : AArch64Inst<PseudoFrm, cstr> { 47 dag OutOperandList = oops; 48 dag InOperandList = iops; 49 let Pattern = pattern; 50 let isCodeGenOnly = 1; 51} 52 53// Real instructions (have encoding information) 54class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 55 let Pattern = pattern; 56 let Size = 4; 57} 58 59// Enum describing whether an instruction is 60// destructive in its first source operand. 61class DestructiveInstTypeEnum<bits<1> val> { 62 bits<1> Value = val; 63} 64def NotDestructive : DestructiveInstTypeEnum<0>; 65def Destructive : DestructiveInstTypeEnum<1>; 66 67// Normal instructions 68class I<dag oops, dag iops, string asm, string operands, string cstr, 69 list<dag> pattern> 70 : EncodedI<cstr, pattern> { 71 dag OutOperandList = oops; 72 dag InOperandList = iops; 73 let AsmString = !strconcat(asm, operands); 74 75 // Destructive operations (SVE) 76 DestructiveInstTypeEnum DestructiveInstType = NotDestructive; 77 ElementSizeEnum ElementSize = ElementSizeB; 78 79 let TSFlags{3} = DestructiveInstType.Value; 80 let TSFlags{2-0} = ElementSize.Value; 81} 82 83class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 84class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 85class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 86 87// Helper fragment for an extract of the high portion of a 128-bit vector. 88def extract_high_v16i8 : 89 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>; 90def extract_high_v8i16 : 91 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>; 92def extract_high_v4i32 : 93 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>; 94def extract_high_v2i64 : 95 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>; 96 97//===----------------------------------------------------------------------===// 98// Asm Operand Classes. 99// 100 101// Shifter operand for arithmetic shifted encodings. 102def ShifterOperand : AsmOperandClass { 103 let Name = "Shifter"; 104} 105 106// Shifter operand for mov immediate encodings. 107def MovImm32ShifterOperand : AsmOperandClass { 108 let SuperClasses = [ShifterOperand]; 109 let Name = "MovImm32Shifter"; 110 let RenderMethod = "addShifterOperands"; 111 let DiagnosticType = "InvalidMovImm32Shift"; 112} 113def MovImm64ShifterOperand : AsmOperandClass { 114 let SuperClasses = [ShifterOperand]; 115 let Name = "MovImm64Shifter"; 116 let RenderMethod = "addShifterOperands"; 117 let DiagnosticType = "InvalidMovImm64Shift"; 118} 119 120// Shifter operand for arithmetic register shifted encodings. 121class ArithmeticShifterOperand<int width> : AsmOperandClass { 122 let SuperClasses = [ShifterOperand]; 123 let Name = "ArithmeticShifter" # width; 124 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 125 let RenderMethod = "addShifterOperands"; 126 let DiagnosticType = "AddSubRegShift" # width; 127} 128 129def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 130def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 131 132// Shifter operand for logical register shifted encodings. 133class LogicalShifterOperand<int width> : AsmOperandClass { 134 let SuperClasses = [ShifterOperand]; 135 let Name = "LogicalShifter" # width; 136 let PredicateMethod = "isLogicalShifter<" # width # ">"; 137 let RenderMethod = "addShifterOperands"; 138 let DiagnosticType = "AddSubRegShift" # width; 139} 140 141def LogicalShifterOperand32 : LogicalShifterOperand<32>; 142def LogicalShifterOperand64 : LogicalShifterOperand<64>; 143 144// Shifter operand for logical vector 128/64-bit shifted encodings. 145def LogicalVecShifterOperand : AsmOperandClass { 146 let SuperClasses = [ShifterOperand]; 147 let Name = "LogicalVecShifter"; 148 let RenderMethod = "addShifterOperands"; 149} 150def LogicalVecHalfWordShifterOperand : AsmOperandClass { 151 let SuperClasses = [LogicalVecShifterOperand]; 152 let Name = "LogicalVecHalfWordShifter"; 153 let RenderMethod = "addShifterOperands"; 154} 155 156// The "MSL" shifter on the vector MOVI instruction. 157def MoveVecShifterOperand : AsmOperandClass { 158 let SuperClasses = [ShifterOperand]; 159 let Name = "MoveVecShifter"; 160 let RenderMethod = "addShifterOperands"; 161} 162 163// Extend operand for arithmetic encodings. 164def ExtendOperand : AsmOperandClass { 165 let Name = "Extend"; 166 let DiagnosticType = "AddSubRegExtendLarge"; 167} 168def ExtendOperand64 : AsmOperandClass { 169 let SuperClasses = [ExtendOperand]; 170 let Name = "Extend64"; 171 let DiagnosticType = "AddSubRegExtendSmall"; 172} 173// 'extend' that's a lsl of a 64-bit register. 174def ExtendOperandLSL64 : AsmOperandClass { 175 let SuperClasses = [ExtendOperand]; 176 let Name = "ExtendLSL64"; 177 let RenderMethod = "addExtend64Operands"; 178 let DiagnosticType = "AddSubRegExtendLarge"; 179} 180 181// 8-bit floating-point immediate encodings. 182def FPImmOperand : AsmOperandClass { 183 let Name = "FPImm"; 184 let ParserMethod = "tryParseFPImm<true>"; 185 let DiagnosticType = "InvalidFPImm"; 186} 187 188def CondCode : AsmOperandClass { 189 let Name = "CondCode"; 190 let DiagnosticType = "InvalidCondCode"; 191} 192 193// A 32-bit register pasrsed as 64-bit 194def GPR32as64Operand : AsmOperandClass { 195 let Name = "GPR32as64"; 196 let ParserMethod = 197 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>"; 198} 199def GPR32as64 : RegisterOperand<GPR32> { 200 let ParserMatchClass = GPR32as64Operand; 201} 202 203// A 64-bit register pasrsed as 32-bit 204def GPR64as32Operand : AsmOperandClass { 205 let Name = "GPR64as32"; 206 let ParserMethod = 207 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>"; 208} 209def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> { 210 let ParserMatchClass = GPR64as32Operand; 211} 212 213// 8-bit immediate for AdvSIMD where 64-bit values of the form: 214// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 215// are encoded as the eight bit value 'abcdefgh'. 216def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 217 218class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 219 let Name = "UImm" # Width # "s" # Scale; 220 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width; 221 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 222 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">"; 223} 224 225class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass { 226 let Name = "SImm" # Width # "s" # Scale; 227 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width; 228 let RenderMethod = "addImmScaledOperands<" # Scale # ">"; 229 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">"; 230} 231 232//===----------------------------------------------------------------------===// 233// Operand Definitions. 234// 235 236// ADR[P] instruction labels. 237def AdrpOperand : AsmOperandClass { 238 let Name = "AdrpLabel"; 239 let ParserMethod = "tryParseAdrpLabel"; 240 let DiagnosticType = "InvalidLabel"; 241} 242def adrplabel : Operand<i64> { 243 let EncoderMethod = "getAdrLabelOpValue"; 244 let PrintMethod = "printAdrpLabel"; 245 let ParserMatchClass = AdrpOperand; 246} 247 248def AdrOperand : AsmOperandClass { 249 let Name = "AdrLabel"; 250 let ParserMethod = "tryParseAdrLabel"; 251 let DiagnosticType = "InvalidLabel"; 252} 253def adrlabel : Operand<i64> { 254 let EncoderMethod = "getAdrLabelOpValue"; 255 let ParserMatchClass = AdrOperand; 256} 257 258class SImmOperand<int width> : AsmOperandClass { 259 let Name = "SImm" # width; 260 let DiagnosticType = "InvalidMemoryIndexedSImm" # width; 261 let RenderMethod = "addImmOperands"; 262 let PredicateMethod = "isSImm<" # width # ">"; 263} 264 265 266class AsmImmRange<int Low, int High> : AsmOperandClass { 267 let Name = "Imm" # Low # "_" # High; 268 let DiagnosticType = "InvalidImm" # Low # "_" # High; 269 let RenderMethod = "addImmOperands"; 270 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; 271} 272 273// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets. 274def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>; 275def simm10Scaled : Operand<i64> { 276 let ParserMatchClass = SImm10s8Operand; 277 let DecoderMethod = "DecodeSImm<10>"; 278 let PrintMethod = "printImmScale<8>"; 279} 280 281def simm9s16 : Operand<i64> { 282 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>; 283 let DecoderMethod = "DecodeSImm<9>"; 284 let PrintMethod = "printImmScale<16>"; 285} 286 287// uimm6 predicate - True if the immediate is in the range [0, 63]. 288def UImm6Operand : AsmOperandClass { 289 let Name = "UImm6"; 290 let DiagnosticType = "InvalidImm0_63"; 291} 292 293def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 294 let ParserMatchClass = UImm6Operand; 295} 296 297def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{ 298 let ParserMatchClass = AsmImmRange<0, 65535>; 299} 300 301def SImm9Operand : SImmOperand<9>; 302def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 303 let ParserMatchClass = SImm9Operand; 304 let DecoderMethod = "DecodeSImm<9>"; 305} 306 307def SImm8Operand : SImmOperand<8>; 308def simm8 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 127; }]> { 309 let ParserMatchClass = SImm8Operand; 310 let DecoderMethod = "DecodeSImm<8>"; 311} 312 313def SImm6Operand : SImmOperand<6>; 314def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> { 315 let ParserMatchClass = SImm6Operand; 316 let DecoderMethod = "DecodeSImm<6>"; 317} 318 319def SImm5Operand : SImmOperand<5>; 320def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> { 321 let ParserMatchClass = SImm5Operand; 322 let DecoderMethod = "DecodeSImm<5>"; 323} 324 325def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> { 326 let ParserMatchClass = SImm5Operand; 327 let DecoderMethod = "DecodeSImm<5>"; 328} 329 330// simm7sN predicate - True if the immediate is a multiple of N in the range 331// [-64 * N, 63 * N]. 332 333def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>; 334def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>; 335def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>; 336 337def simm7s4 : Operand<i32> { 338 let ParserMatchClass = SImm7s4Operand; 339 let PrintMethod = "printImmScale<4>"; 340} 341 342def simm7s8 : Operand<i32> { 343 let ParserMatchClass = SImm7s8Operand; 344 let PrintMethod = "printImmScale<8>"; 345} 346 347def simm7s16 : Operand<i32> { 348 let ParserMatchClass = SImm7s16Operand; 349 let PrintMethod = "printImmScale<16>"; 350} 351 352def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>; 353def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>; 354def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>; 355def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>; 356def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>; 357 358def am_indexedu6s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedU6S128", []>; 359def am_indexeds9s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexedS9S128", []>; 360 361// uimm5sN predicate - True if the immediate is a multiple of N in the range 362// [0 * N, 32 * N]. 363def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>; 364def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>; 365def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>; 366 367def uimm5s2 : Operand<i64>, ImmLeaf<i64, 368 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }]> { 369 let ParserMatchClass = UImm5s2Operand; 370 let PrintMethod = "printImmScale<2>"; 371} 372def uimm5s4 : Operand<i64>, ImmLeaf<i64, 373 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }]> { 374 let ParserMatchClass = UImm5s4Operand; 375 let PrintMethod = "printImmScale<4>"; 376} 377def uimm5s8 : Operand<i64>, ImmLeaf<i64, 378 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }]> { 379 let ParserMatchClass = UImm5s8Operand; 380 let PrintMethod = "printImmScale<8>"; 381} 382 383// uimm6sN predicate - True if the immediate is a multiple of N in the range 384// [0 * N, 64 * N]. 385def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>; 386def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>; 387def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>; 388def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>; 389def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>; 390 391def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> { 392 let ParserMatchClass = UImm6s1Operand; 393} 394def uimm6s2 : Operand<i64>, ImmLeaf<i64, 395[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> { 396 let PrintMethod = "printImmScale<2>"; 397 let ParserMatchClass = UImm6s2Operand; 398} 399def uimm6s4 : Operand<i64>, ImmLeaf<i64, 400[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> { 401 let PrintMethod = "printImmScale<4>"; 402 let ParserMatchClass = UImm6s4Operand; 403} 404def uimm6s8 : Operand<i64>, ImmLeaf<i64, 405[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> { 406 let PrintMethod = "printImmScale<8>"; 407 let ParserMatchClass = UImm6s8Operand; 408} 409def uimm6s16 : Operand<i64>, ImmLeaf<i64, 410[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> { 411 let PrintMethod = "printImmScale<16>"; 412 let ParserMatchClass = UImm6s16Operand; 413} 414 415// simm6sN predicate - True if the immediate is a multiple of N in the range 416// [-32 * N, 31 * N]. 417def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>; 418def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> { 419 let ParserMatchClass = SImm6s1Operand; 420 let DecoderMethod = "DecodeSImm<6>"; 421} 422 423// simm4sN predicate - True if the immediate is a multiple of N in the range 424// [ -8* N, 7 * N]. 425def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>; 426def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; 427def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; 428def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; 429def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; 430 431def simm4s1 : Operand<i64>, ImmLeaf<i64, 432[{ return Imm >=-8 && Imm <= 7; }]> { 433 let ParserMatchClass = SImm4s1Operand; 434 let DecoderMethod = "DecodeSImm<4>"; 435} 436 437def simm4s2 : Operand<i64>, ImmLeaf<i64, 438[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }]> { 439 let PrintMethod = "printImmScale<2>"; 440 let ParserMatchClass = SImm4s2Operand; 441 let DecoderMethod = "DecodeSImm<4>"; 442} 443 444def simm4s3 : Operand<i64>, ImmLeaf<i64, 445[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }]> { 446 let PrintMethod = "printImmScale<3>"; 447 let ParserMatchClass = SImm4s3Operand; 448 let DecoderMethod = "DecodeSImm<4>"; 449} 450 451def simm4s4 : Operand<i64>, ImmLeaf<i64, 452[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }]> { 453 let PrintMethod = "printImmScale<4>"; 454 let ParserMatchClass = SImm4s4Operand; 455 let DecoderMethod = "DecodeSImm<4>"; 456} 457def simm4s16 : Operand<i64>, ImmLeaf<i64, 458[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }]> { 459 let PrintMethod = "printImmScale<16>"; 460 let ParserMatchClass = SImm4s16Operand; 461 let DecoderMethod = "DecodeSImm<4>"; 462} 463 464def Imm1_8Operand : AsmImmRange<1, 8>; 465def Imm1_16Operand : AsmImmRange<1, 16>; 466def Imm1_32Operand : AsmImmRange<1, 32>; 467def Imm1_64Operand : AsmImmRange<1, 64>; 468 469class BranchTarget<int N> : AsmOperandClass { 470 let Name = "BranchTarget" # N; 471 let DiagnosticType = "InvalidLabel"; 472 let PredicateMethod = "isBranchTarget<" # N # ">"; 473} 474 475class PCRelLabel<int N> : BranchTarget<N> { 476 let Name = "PCRelLabel" # N; 477} 478 479def BranchTarget14Operand : BranchTarget<14>; 480def BranchTarget26Operand : BranchTarget<26>; 481def PCRelLabel19Operand : PCRelLabel<19>; 482 483def MovWSymbolG3AsmOperand : AsmOperandClass { 484 let Name = "MovWSymbolG3"; 485 let RenderMethod = "addImmOperands"; 486} 487 488def movw_symbol_g3 : Operand<i32> { 489 let ParserMatchClass = MovWSymbolG3AsmOperand; 490} 491 492def MovWSymbolG2AsmOperand : AsmOperandClass { 493 let Name = "MovWSymbolG2"; 494 let RenderMethod = "addImmOperands"; 495} 496 497def movw_symbol_g2 : Operand<i32> { 498 let ParserMatchClass = MovWSymbolG2AsmOperand; 499} 500 501def MovWSymbolG1AsmOperand : AsmOperandClass { 502 let Name = "MovWSymbolG1"; 503 let RenderMethod = "addImmOperands"; 504} 505 506def movw_symbol_g1 : Operand<i32> { 507 let ParserMatchClass = MovWSymbolG1AsmOperand; 508} 509 510def MovWSymbolG0AsmOperand : AsmOperandClass { 511 let Name = "MovWSymbolG0"; 512 let RenderMethod = "addImmOperands"; 513} 514 515def movw_symbol_g0 : Operand<i32> { 516 let ParserMatchClass = MovWSymbolG0AsmOperand; 517} 518 519class fixedpoint_i32<ValueType FloatVT> 520 : Operand<FloatVT>, 521 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 522 let EncoderMethod = "getFixedPointScaleOpValue"; 523 let DecoderMethod = "DecodeFixedPointScaleImm32"; 524 let ParserMatchClass = Imm1_32Operand; 525} 526 527class fixedpoint_i64<ValueType FloatVT> 528 : Operand<FloatVT>, 529 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 530 let EncoderMethod = "getFixedPointScaleOpValue"; 531 let DecoderMethod = "DecodeFixedPointScaleImm64"; 532 let ParserMatchClass = Imm1_64Operand; 533} 534 535def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 536def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 537def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 538 539def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 540def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 541def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 542 543def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 544 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 545}]> { 546 let EncoderMethod = "getVecShiftR8OpValue"; 547 let DecoderMethod = "DecodeVecShiftR8Imm"; 548 let ParserMatchClass = Imm1_8Operand; 549} 550def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 551 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 552}]> { 553 let EncoderMethod = "getVecShiftR16OpValue"; 554 let DecoderMethod = "DecodeVecShiftR16Imm"; 555 let ParserMatchClass = Imm1_16Operand; 556} 557def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 558 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 559}]> { 560 let EncoderMethod = "getVecShiftR16OpValue"; 561 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 562 let ParserMatchClass = Imm1_8Operand; 563} 564def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 565 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 566}]> { 567 let EncoderMethod = "getVecShiftR32OpValue"; 568 let DecoderMethod = "DecodeVecShiftR32Imm"; 569 let ParserMatchClass = Imm1_32Operand; 570} 571def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 572 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 573}]> { 574 let EncoderMethod = "getVecShiftR32OpValue"; 575 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 576 let ParserMatchClass = Imm1_16Operand; 577} 578def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 579 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 580}]> { 581 let EncoderMethod = "getVecShiftR64OpValue"; 582 let DecoderMethod = "DecodeVecShiftR64Imm"; 583 let ParserMatchClass = Imm1_64Operand; 584} 585def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 586 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 587}]> { 588 let EncoderMethod = "getVecShiftR64OpValue"; 589 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 590 let ParserMatchClass = Imm1_32Operand; 591} 592 593def Imm0_1Operand : AsmImmRange<0, 1>; 594def Imm0_7Operand : AsmImmRange<0, 7>; 595def Imm0_15Operand : AsmImmRange<0, 15>; 596def Imm0_31Operand : AsmImmRange<0, 31>; 597def Imm0_63Operand : AsmImmRange<0, 63>; 598 599def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 600 return (((uint32_t)Imm) < 8); 601}]> { 602 let EncoderMethod = "getVecShiftL8OpValue"; 603 let DecoderMethod = "DecodeVecShiftL8Imm"; 604 let ParserMatchClass = Imm0_7Operand; 605} 606def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 607 return (((uint32_t)Imm) < 16); 608}]> { 609 let EncoderMethod = "getVecShiftL16OpValue"; 610 let DecoderMethod = "DecodeVecShiftL16Imm"; 611 let ParserMatchClass = Imm0_15Operand; 612} 613def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 614 return (((uint32_t)Imm) < 32); 615}]> { 616 let EncoderMethod = "getVecShiftL32OpValue"; 617 let DecoderMethod = "DecodeVecShiftL32Imm"; 618 let ParserMatchClass = Imm0_31Operand; 619} 620def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 621 return (((uint32_t)Imm) < 64); 622}]> { 623 let EncoderMethod = "getVecShiftL64OpValue"; 624 let DecoderMethod = "DecodeVecShiftL64Imm"; 625 let ParserMatchClass = Imm0_63Operand; 626} 627 628 629// Crazy immediate formats used by 32-bit and 64-bit logical immediate 630// instructions for splatting repeating bit patterns across the immediate. 631def logical_imm32_XFORM : SDNodeXForm<imm, [{ 632 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 633 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 634}]>; 635def logical_imm64_XFORM : SDNodeXForm<imm, [{ 636 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 637 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 638}]>; 639 640def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">, 641 GISDNodeXFormEquiv<logical_imm32_XFORM>; 642def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">, 643 GISDNodeXFormEquiv<logical_imm64_XFORM>; 644 645let DiagnosticType = "LogicalSecondSource" in { 646 def LogicalImm32Operand : AsmOperandClass { 647 let Name = "LogicalImm32"; 648 let PredicateMethod = "isLogicalImm<int32_t>"; 649 let RenderMethod = "addLogicalImmOperands<int32_t>"; 650 } 651 def LogicalImm64Operand : AsmOperandClass { 652 let Name = "LogicalImm64"; 653 let PredicateMethod = "isLogicalImm<int64_t>"; 654 let RenderMethod = "addLogicalImmOperands<int64_t>"; 655 } 656 def LogicalImm32NotOperand : AsmOperandClass { 657 let Name = "LogicalImm32Not"; 658 let PredicateMethod = "isLogicalImm<int32_t>"; 659 let RenderMethod = "addLogicalImmNotOperands<int32_t>"; 660 } 661 def LogicalImm64NotOperand : AsmOperandClass { 662 let Name = "LogicalImm64Not"; 663 let PredicateMethod = "isLogicalImm<int64_t>"; 664 let RenderMethod = "addLogicalImmNotOperands<int64_t>"; 665 } 666} 667def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{ 668 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32); 669}], logical_imm32_XFORM> { 670 let PrintMethod = "printLogicalImm<int32_t>"; 671 let ParserMatchClass = LogicalImm32Operand; 672} 673def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{ 674 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64); 675}], logical_imm64_XFORM> { 676 let PrintMethod = "printLogicalImm<int64_t>"; 677 let ParserMatchClass = LogicalImm64Operand; 678} 679def logical_imm32_not : Operand<i32> { 680 let ParserMatchClass = LogicalImm32NotOperand; 681} 682def logical_imm64_not : Operand<i64> { 683 let ParserMatchClass = LogicalImm64NotOperand; 684} 685 686// iXX_imm0_65535 predicates - True if the immediate is in the range [0,65535]. 687let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in { 688def i32_imm0_65535 : Operand<i32>, TImmLeaf<i32, [{ 689 return ((uint32_t)Imm) < 65536; 690}]>; 691 692def i64_imm0_65535 : Operand<i64>, TImmLeaf<i64, [{ 693 return ((uint64_t)Imm) < 65536; 694}]>; 695} 696 697// imm0_255 predicate - True if the immediate is in the range [0,255]. 698def Imm0_255Operand : AsmImmRange<0,255>; 699 700def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 701 return ((uint32_t)Imm) < 256; 702}]> { 703 let ParserMatchClass = Imm0_255Operand; 704 let PrintMethod = "printImm"; 705} 706 707// imm0_127 predicate - True if the immediate is in the range [0,127] 708def Imm0_127Operand : AsmImmRange<0, 127>; 709def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 710 return ((uint32_t)Imm) < 128; 711}]> { 712 let ParserMatchClass = Imm0_127Operand; 713 let PrintMethod = "printImm"; 714} 715 716// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 717// for all shift-amounts. 718 719// imm0_63 predicate - True if the immediate is in the range [0,63] 720def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 721 return ((uint64_t)Imm) < 64; 722}]> { 723 let ParserMatchClass = Imm0_63Operand; 724} 725 726// imm0_31 predicate - True if the immediate is in the range [0,31] 727def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 728 return ((uint64_t)Imm) < 32; 729}]> { 730 let ParserMatchClass = Imm0_31Operand; 731} 732 733// True if the 32-bit immediate is in the range [0,31] 734def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 735 return ((uint64_t)Imm) < 32; 736}]> { 737 let ParserMatchClass = Imm0_31Operand; 738} 739 740// imm0_1 predicate - True if the immediate is in the range [0,1] 741def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 742 return ((uint64_t)Imm) < 2; 743}]> { 744 let ParserMatchClass = Imm0_1Operand; 745} 746 747// imm0_15 predicate - True if the immediate is in the range [0,15] 748def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 749 return ((uint64_t)Imm) < 16; 750}]> { 751 let ParserMatchClass = Imm0_15Operand; 752} 753 754// imm0_7 predicate - True if the immediate is in the range [0,7] 755def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 756 return ((uint64_t)Imm) < 8; 757}]> { 758 let ParserMatchClass = Imm0_7Operand; 759} 760 761// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 762def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 763 return ((uint32_t)Imm) < 16; 764}]> { 765 let ParserMatchClass = Imm0_15Operand; 766} 767 768// An arithmetic shifter operand: 769// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 770// {5-0} - imm6 771class arith_shift<ValueType Ty, int width> : Operand<Ty> { 772 let PrintMethod = "printShifter"; 773 let ParserMatchClass = !cast<AsmOperandClass>( 774 "ArithmeticShifterOperand" # width); 775} 776 777def arith_shift32 : arith_shift<i32, 32>; 778def arith_shift64 : arith_shift<i64, 64>; 779 780class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 781 : Operand<Ty>, 782 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 783 let PrintMethod = "printShiftedRegister"; 784 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 785} 786 787def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 788def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 789 790def gi_arith_shifted_reg32 : 791 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">, 792 GIComplexPatternEquiv<arith_shifted_reg32>; 793 794def gi_arith_shifted_reg64 : 795 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">, 796 GIComplexPatternEquiv<arith_shifted_reg64>; 797 798// An arithmetic shifter operand: 799// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 800// {5-0} - imm6 801class logical_shift<int width> : Operand<i32> { 802 let PrintMethod = "printShifter"; 803 let ParserMatchClass = !cast<AsmOperandClass>( 804 "LogicalShifterOperand" # width); 805} 806 807def logical_shift32 : logical_shift<32>; 808def logical_shift64 : logical_shift<64>; 809 810class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 811 : Operand<Ty>, 812 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 813 let PrintMethod = "printShiftedRegister"; 814 let MIOperandInfo = (ops regclass, shiftop); 815} 816 817def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 818def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 819 820def gi_logical_shifted_reg32 : 821 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">, 822 GIComplexPatternEquiv<logical_shifted_reg32>; 823 824def gi_logical_shifted_reg64 : 825 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">, 826 GIComplexPatternEquiv<logical_shifted_reg64>; 827 828// A logical vector shifter operand: 829// {7-6} - shift type: 00 = lsl 830// {5-0} - imm6: #0, #8, #16, or #24 831def logical_vec_shift : Operand<i32> { 832 let PrintMethod = "printShifter"; 833 let EncoderMethod = "getVecShifterOpValue"; 834 let ParserMatchClass = LogicalVecShifterOperand; 835} 836 837// A logical vector half-word shifter operand: 838// {7-6} - shift type: 00 = lsl 839// {5-0} - imm6: #0 or #8 840def logical_vec_hw_shift : Operand<i32> { 841 let PrintMethod = "printShifter"; 842 let EncoderMethod = "getVecShifterOpValue"; 843 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 844} 845 846// A vector move shifter operand: 847// {0} - imm1: #8 or #16 848def move_vec_shift : Operand<i32> { 849 let PrintMethod = "printShifter"; 850 let EncoderMethod = "getMoveVecShifterOpValue"; 851 let ParserMatchClass = MoveVecShifterOperand; 852} 853 854let DiagnosticType = "AddSubSecondSource" in { 855 def AddSubImmOperand : AsmOperandClass { 856 let Name = "AddSubImm"; 857 let ParserMethod = "tryParseImmWithOptionalShift"; 858 let RenderMethod = "addImmWithOptionalShiftOperands<12>"; 859 } 860 def AddSubImmNegOperand : AsmOperandClass { 861 let Name = "AddSubImmNeg"; 862 let ParserMethod = "tryParseImmWithOptionalShift"; 863 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>"; 864 } 865} 866// An ADD/SUB immediate shifter operand: 867// second operand: 868// {7-6} - shift type: 00 = lsl 869// {5-0} - imm6: #0 or #12 870class addsub_shifted_imm<ValueType Ty> 871 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 872 let PrintMethod = "printAddSubImm"; 873 let EncoderMethod = "getAddSubImmOpValue"; 874 let ParserMatchClass = AddSubImmOperand; 875 let MIOperandInfo = (ops i32imm, i32imm); 876} 877 878class addsub_shifted_imm_neg<ValueType Ty> 879 : Operand<Ty> { 880 let EncoderMethod = "getAddSubImmOpValue"; 881 let ParserMatchClass = AddSubImmNegOperand; 882 let MIOperandInfo = (ops i32imm, i32imm); 883} 884 885def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 886def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 887def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 888def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 889 890def gi_addsub_shifted_imm32 : 891 GIComplexOperandMatcher<s32, "selectArithImmed">, 892 GIComplexPatternEquiv<addsub_shifted_imm32>; 893 894def gi_addsub_shifted_imm64 : 895 GIComplexOperandMatcher<s64, "selectArithImmed">, 896 GIComplexPatternEquiv<addsub_shifted_imm64>; 897 898class neg_addsub_shifted_imm<ValueType Ty> 899 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 900 let PrintMethod = "printAddSubImm"; 901 let EncoderMethod = "getAddSubImmOpValue"; 902 let ParserMatchClass = AddSubImmOperand; 903 let MIOperandInfo = (ops i32imm, i32imm); 904} 905 906def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 907def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 908 909def gi_neg_addsub_shifted_imm32 : 910 GIComplexOperandMatcher<s32, "selectNegArithImmed">, 911 GIComplexPatternEquiv<neg_addsub_shifted_imm32>; 912 913def gi_neg_addsub_shifted_imm64 : 914 GIComplexOperandMatcher<s64, "selectNegArithImmed">, 915 GIComplexPatternEquiv<neg_addsub_shifted_imm64>; 916 917// An extend operand: 918// {5-3} - extend type 919// {2-0} - imm3 920def arith_extend : Operand<i32> { 921 let PrintMethod = "printArithExtend"; 922 let ParserMatchClass = ExtendOperand; 923} 924def arith_extend64 : Operand<i32> { 925 let PrintMethod = "printArithExtend"; 926 let ParserMatchClass = ExtendOperand64; 927} 928 929// 'extend' that's a lsl of a 64-bit register. 930def arith_extendlsl64 : Operand<i32> { 931 let PrintMethod = "printArithExtend"; 932 let ParserMatchClass = ExtendOperandLSL64; 933} 934 935class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 936 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 937 let PrintMethod = "printExtendedRegister"; 938 let MIOperandInfo = (ops GPR32, arith_extend); 939} 940 941class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 942 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 943 let PrintMethod = "printExtendedRegister"; 944 let MIOperandInfo = (ops GPR32, arith_extend64); 945} 946 947def arith_extended_reg32_i32 : arith_extended_reg32<i32>; 948def gi_arith_extended_reg32_i32 : 949 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">, 950 GIComplexPatternEquiv<arith_extended_reg32_i32>; 951 952def arith_extended_reg32_i64 : arith_extended_reg32<i64>; 953def gi_arith_extended_reg32_i64 : 954 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 955 GIComplexPatternEquiv<arith_extended_reg32_i64>; 956 957def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>; 958def gi_arith_extended_reg32to64_i64 : 959 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">, 960 GIComplexPatternEquiv<arith_extended_reg32to64_i64>; 961 962// Floating-point immediate. 963def fpimm16 : Operand<f16>, 964 FPImmLeaf<f16, [{ 965 return AArch64_AM::getFP16Imm(Imm) != -1; 966 }], SDNodeXForm<fpimm, [{ 967 APFloat InVal = N->getValueAPF(); 968 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 969 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 970 }]>> { 971 let ParserMatchClass = FPImmOperand; 972 let PrintMethod = "printFPImmOperand"; 973} 974def fpimm32 : Operand<f32>, 975 FPImmLeaf<f32, [{ 976 return AArch64_AM::getFP32Imm(Imm) != -1; 977 }], SDNodeXForm<fpimm, [{ 978 APFloat InVal = N->getValueAPF(); 979 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 980 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 981 }]>> { 982 let ParserMatchClass = FPImmOperand; 983 let PrintMethod = "printFPImmOperand"; 984} 985def fpimm64 : Operand<f64>, 986 FPImmLeaf<f64, [{ 987 return AArch64_AM::getFP64Imm(Imm) != -1; 988 }], SDNodeXForm<fpimm, [{ 989 APFloat InVal = N->getValueAPF(); 990 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 991 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 992 }]>> { 993 let ParserMatchClass = FPImmOperand; 994 let PrintMethod = "printFPImmOperand"; 995} 996 997def fpimm8 : Operand<i32> { 998 let ParserMatchClass = FPImmOperand; 999 let PrintMethod = "printFPImmOperand"; 1000} 1001 1002def fpimm0 : FPImmLeaf<fAny, [{ 1003 return Imm.isExactlyValue(+0.0); 1004}]>; 1005 1006// Vector lane operands 1007class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass { 1008 let Name = NamePrefix # "IndexRange" # Min # "_" # Max; 1009 let DiagnosticType = "Invalid" # Name; 1010 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">"; 1011 let RenderMethod = "addVectorIndexOperands"; 1012} 1013 1014class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc, code pred> 1015 : Operand<ty>, ImmLeaf<ty, pred> { 1016 let ParserMatchClass = mc; 1017 let PrintMethod = "printVectorIndex"; 1018} 1019 1020def VectorIndex1Operand : AsmVectorIndex<1, 1>; 1021def VectorIndexBOperand : AsmVectorIndex<0, 15>; 1022def VectorIndexHOperand : AsmVectorIndex<0, 7>; 1023def VectorIndexSOperand : AsmVectorIndex<0, 3>; 1024def VectorIndexDOperand : AsmVectorIndex<0, 1>; 1025 1026def VectorIndex1 : AsmVectorIndexOpnd<i64, VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>; 1027def VectorIndexB : AsmVectorIndexOpnd<i64, VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>; 1028def VectorIndexH : AsmVectorIndexOpnd<i64, VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>; 1029def VectorIndexS : AsmVectorIndexOpnd<i64, VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>; 1030def VectorIndexD : AsmVectorIndexOpnd<i64, VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>; 1031 1032def VectorIndex132b : AsmVectorIndexOpnd<i32, VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>; 1033def VectorIndexB32b : AsmVectorIndexOpnd<i32, VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>; 1034def VectorIndexH32b : AsmVectorIndexOpnd<i32, VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>; 1035def VectorIndexS32b : AsmVectorIndexOpnd<i32, VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>; 1036def VectorIndexD32b : AsmVectorIndexOpnd<i32, VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>; 1037 1038def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">; 1039def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">; 1040def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">; 1041def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">; 1042def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">; 1043 1044def sve_elm_idx_extdup_b 1045 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupBOperand, [{ return ((uint64_t)Imm) < 64; }]>; 1046def sve_elm_idx_extdup_h 1047 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupHOperand, [{ return ((uint64_t)Imm) < 32; }]>; 1048def sve_elm_idx_extdup_s 1049 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupSOperand, [{ return ((uint64_t)Imm) < 16; }]>; 1050def sve_elm_idx_extdup_d 1051 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupDOperand, [{ return ((uint64_t)Imm) < 8; }]>; 1052def sve_elm_idx_extdup_q 1053 : AsmVectorIndexOpnd<i64, SVEVectorIndexExtDupQOperand, [{ return ((uint64_t)Imm) < 4; }]>; 1054 1055// 8-bit immediate for AdvSIMD where 64-bit values of the form: 1056// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 1057// are encoded as the eight bit value 'abcdefgh'. 1058def simdimmtype10 : Operand<i32>, 1059 FPImmLeaf<f64, [{ 1060 return AArch64_AM::isAdvSIMDModImmType10( 1061 Imm.bitcastToAPInt().getZExtValue()); 1062 }], SDNodeXForm<fpimm, [{ 1063 APFloat InVal = N->getValueAPF(); 1064 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 1065 .bitcastToAPInt() 1066 .getZExtValue()); 1067 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 1068 }]>> { 1069 let ParserMatchClass = SIMDImmType10Operand; 1070 let PrintMethod = "printSIMDType10Operand"; 1071} 1072 1073 1074//--- 1075// System management 1076//--- 1077 1078// Base encoding for system instruction operands. 1079let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 1080class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 1081 list<dag> pattern = []> 1082 : I<oops, iops, asm, operands, "", pattern> { 1083 let Inst{31-22} = 0b1101010100; 1084 let Inst{21} = L; 1085} 1086 1087// System instructions which do not have an Rt register. 1088class SimpleSystemI<bit L, dag iops, string asm, string operands, 1089 list<dag> pattern = []> 1090 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 1091 let Inst{4-0} = 0b11111; 1092} 1093 1094// System instructions which have an Rt register. 1095class RtSystemI<bit L, dag oops, dag iops, string asm, string operands> 1096 : BaseSystemI<L, oops, iops, asm, operands>, 1097 Sched<[WriteSys]> { 1098 bits<5> Rt; 1099 let Inst{4-0} = Rt; 1100} 1101 1102// System instructions for transactional memory extension 1103class TMBaseSystemI<bit L, bits<4> CRm, bits<3> op2, dag oops, dag iops, 1104 string asm, string operands, list<dag> pattern> 1105 : BaseSystemI<L, oops, iops, asm, operands, pattern>, 1106 Sched<[WriteSys]> { 1107 let Inst{20-12} = 0b000110011; 1108 let Inst{11-8} = CRm; 1109 let Inst{7-5} = op2; 1110 let DecoderMethod = ""; 1111 1112 let mayLoad = 1; 1113 let mayStore = 1; 1114} 1115 1116// System instructions for transactional memory - single input operand 1117class TMSystemI<bits<4> CRm, string asm, list<dag> pattern> 1118 : TMBaseSystemI<0b1, CRm, 0b011, 1119 (outs GPR64:$Rt), (ins), asm, "\t$Rt", pattern> { 1120 bits<5> Rt; 1121 let Inst{4-0} = Rt; 1122} 1123 1124// System instructions for transactional memory - no operand 1125class TMSystemINoOperand<bits<4> CRm, string asm, list<dag> pattern> 1126 : TMBaseSystemI<0b0, CRm, 0b011, (outs), (ins), asm, "", pattern> { 1127 let Inst{4-0} = 0b11111; 1128} 1129 1130// System instructions for exit from transactions 1131class TMSystemException<bits<3> op1, string asm, list<dag> pattern> 1132 : I<(outs), (ins i64_imm0_65535:$imm), asm, "\t$imm", "", pattern>, 1133 Sched<[WriteSys]> { 1134 bits<16> imm; 1135 let Inst{31-24} = 0b11010100; 1136 let Inst{23-21} = op1; 1137 let Inst{20-5} = imm; 1138 let Inst{4-0} = 0b00000; 1139} 1140 1141// Hint instructions that take both a CRm and a 3-bit immediate. 1142// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 1143// model patterns with sufficiently fine granularity 1144let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 1145 class HintI<string mnemonic> 1146 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 1147 [(int_aarch64_hint imm0_127:$imm)]>, 1148 Sched<[WriteHint]> { 1149 bits <7> imm; 1150 let Inst{20-12} = 0b000110010; 1151 let Inst{11-5} = imm; 1152 } 1153 1154// System instructions taking a single literal operand which encodes into 1155// CRm. op2 differentiates the opcodes. 1156def BarrierAsmOperand : AsmOperandClass { 1157 let Name = "Barrier"; 1158 let ParserMethod = "tryParseBarrierOperand"; 1159} 1160def barrier_op : Operand<i32> { 1161 let PrintMethod = "printBarrierOption"; 1162 let ParserMatchClass = BarrierAsmOperand; 1163} 1164class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 1165 list<dag> pattern = []> 1166 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 1167 Sched<[WriteBarrier]> { 1168 bits<4> CRm; 1169 let Inst{20-12} = 0b000110011; 1170 let Inst{11-8} = CRm; 1171 let Inst{7-5} = opc; 1172} 1173 1174class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []> 1175 : SimpleSystemI<0, (ins), asm, "", pattern>, 1176 Sched<[]> { 1177 bits<4> CRm; 1178 let CRm = 0b0011; 1179 let Inst{31-12} = 0b11010101000000110010; 1180 let Inst{11-8} = CRm; 1181 let Inst{7-5} = op2; 1182 let Inst{4-0} = 0b11111; 1183} 1184 1185// MRS/MSR system instructions. These have different operand classes because 1186// a different subset of registers can be accessed through each instruction. 1187def MRSSystemRegisterOperand : AsmOperandClass { 1188 let Name = "MRSSystemRegister"; 1189 let ParserMethod = "tryParseSysReg"; 1190 let DiagnosticType = "MRS"; 1191} 1192// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 1193def mrs_sysreg_op : Operand<i32> { 1194 let ParserMatchClass = MRSSystemRegisterOperand; 1195 let DecoderMethod = "DecodeMRSSystemRegister"; 1196 let PrintMethod = "printMRSSystemRegister"; 1197} 1198 1199def MSRSystemRegisterOperand : AsmOperandClass { 1200 let Name = "MSRSystemRegister"; 1201 let ParserMethod = "tryParseSysReg"; 1202 let DiagnosticType = "MSR"; 1203} 1204def msr_sysreg_op : Operand<i32> { 1205 let ParserMatchClass = MSRSystemRegisterOperand; 1206 let DecoderMethod = "DecodeMSRSystemRegister"; 1207 let PrintMethod = "printMSRSystemRegister"; 1208} 1209 1210def PSBHintOperand : AsmOperandClass { 1211 let Name = "PSBHint"; 1212 let ParserMethod = "tryParsePSBHint"; 1213} 1214def psbhint_op : Operand<i32> { 1215 let ParserMatchClass = PSBHintOperand; 1216 let PrintMethod = "printPSBHintOp"; 1217 let MCOperandPredicate = [{ 1218 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 1219 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 1220 if (!MCOp.isImm()) 1221 return false; 1222 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 1223 }]; 1224} 1225 1226def BTIHintOperand : AsmOperandClass { 1227 let Name = "BTIHint"; 1228 let ParserMethod = "tryParseBTIHint"; 1229} 1230def btihint_op : Operand<i32> { 1231 let ParserMatchClass = BTIHintOperand; 1232 let PrintMethod = "printBTIHintOp"; 1233 let MCOperandPredicate = [{ 1234 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields. 1235 if (!MCOp.isImm()) 1236 return false; 1237 return AArch64BTIHint::lookupBTIByEncoding((MCOp.getImm() ^ 32) >> 1) != nullptr; 1238 }]; 1239} 1240 1241class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 1242 "mrs", "\t$Rt, $systemreg"> { 1243 bits<16> systemreg; 1244 let Inst{20-5} = systemreg; 1245} 1246 1247// FIXME: Some of these def NZCV, others don't. Best way to model that? 1248// Explicitly modeling each of the system register as a register class 1249// would do it, but feels like overkill at this point. 1250class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 1251 "msr", "\t$systemreg, $Rt"> { 1252 bits<16> systemreg; 1253 let Inst{20-5} = systemreg; 1254} 1255 1256def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 1257 let Name = "SystemPStateFieldWithImm0_15"; 1258 let ParserMethod = "tryParseSysReg"; 1259} 1260def pstatefield4_op : Operand<i32> { 1261 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 1262 let PrintMethod = "printSystemPStateField"; 1263} 1264 1265// Instructions to modify PSTATE, no input reg 1266let Defs = [NZCV] in 1267class PstateWriteSimple<dag iops, string asm, string operands> 1268 : SimpleSystemI<0, iops, asm, operands> { 1269 1270 let Inst{20-19} = 0b00; 1271 let Inst{15-12} = 0b0100; 1272} 1273 1274class MSRpstateImm0_15 1275 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr", 1276 "\t$pstatefield, $imm">, 1277 Sched<[WriteSys]> { 1278 1279 bits<6> pstatefield; 1280 bits<4> imm; 1281 let Inst{18-16} = pstatefield{5-3}; 1282 let Inst{11-8} = imm; 1283 let Inst{7-5} = pstatefield{2-0}; 1284 1285 let DecoderMethod = "DecodeSystemPStateInstruction"; 1286 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1287 // Fail the decoder should attempt to decode the instruction as MSRI. 1288 let hasCompleteDecoder = 0; 1289} 1290 1291def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 1292 let Name = "SystemPStateFieldWithImm0_1"; 1293 let ParserMethod = "tryParseSysReg"; 1294} 1295def pstatefield1_op : Operand<i32> { 1296 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 1297 let PrintMethod = "printSystemPStateField"; 1298} 1299 1300class MSRpstateImm0_1 1301 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr", 1302 "\t$pstatefield, $imm">, 1303 Sched<[WriteSys]> { 1304 1305 bits<6> pstatefield; 1306 bit imm; 1307 let Inst{18-16} = pstatefield{5-3}; 1308 let Inst{11-9} = 0b000; 1309 let Inst{8} = imm; 1310 let Inst{7-5} = pstatefield{2-0}; 1311 1312 let DecoderMethod = "DecodeSystemPStateInstruction"; 1313 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1314 // Fail the decoder should attempt to decode the instruction as MSRI. 1315 let hasCompleteDecoder = 0; 1316} 1317 1318// SYS and SYSL generic system instructions. 1319def SysCRAsmOperand : AsmOperandClass { 1320 let Name = "SysCR"; 1321 let ParserMethod = "tryParseSysCROperand"; 1322} 1323 1324def sys_cr_op : Operand<i32> { 1325 let PrintMethod = "printSysCROperand"; 1326 let ParserMatchClass = SysCRAsmOperand; 1327} 1328 1329class SystemXtI<bit L, string asm> 1330 : RtSystemI<L, (outs), 1331 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1332 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1333 bits<3> op1; 1334 bits<4> Cn; 1335 bits<4> Cm; 1336 bits<3> op2; 1337 let Inst{20-19} = 0b01; 1338 let Inst{18-16} = op1; 1339 let Inst{15-12} = Cn; 1340 let Inst{11-8} = Cm; 1341 let Inst{7-5} = op2; 1342} 1343 1344class SystemLXtI<bit L, string asm> 1345 : RtSystemI<L, (outs), 1346 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1347 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1348 bits<3> op1; 1349 bits<4> Cn; 1350 bits<4> Cm; 1351 bits<3> op2; 1352 let Inst{20-19} = 0b01; 1353 let Inst{18-16} = op1; 1354 let Inst{15-12} = Cn; 1355 let Inst{11-8} = Cm; 1356 let Inst{7-5} = op2; 1357} 1358 1359 1360// Branch (register) instructions: 1361// 1362// case opc of 1363// 0001 blr 1364// 0000 br 1365// 0101 dret 1366// 0100 eret 1367// 0010 ret 1368// otherwise UNDEFINED 1369class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1370 string operands, list<dag> pattern> 1371 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1372 let Inst{31-25} = 0b1101011; 1373 let Inst{24-21} = opc; 1374 let Inst{20-16} = 0b11111; 1375 let Inst{15-10} = 0b000000; 1376 let Inst{4-0} = 0b00000; 1377} 1378 1379class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1380 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1381 bits<5> Rn; 1382 let Inst{9-5} = Rn; 1383} 1384 1385let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1386class SpecialReturn<bits<4> opc, string asm> 1387 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1388 let Inst{9-5} = 0b11111; 1389} 1390 1391let mayLoad = 1 in 1392class RCPCLoad<bits<2> sz, string asm, RegisterClass RC> 1393 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>, 1394 Sched<[]> { 1395 bits<5> Rn; 1396 bits<5> Rt; 1397 let Inst{31-30} = sz; 1398 let Inst{29-10} = 0b11100010111111110000; 1399 let Inst{9-5} = Rn; 1400 let Inst{4-0} = Rt; 1401} 1402 1403class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands, 1404 list<dag> pattern> 1405 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> { 1406 let Inst{31-25} = 0b1101011; 1407 let Inst{20-11} = 0b1111100001; 1408 let Inst{10} = M; 1409 let Inst{4-0} = 0b11111; 1410} 1411 1412class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm> 1413 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> { 1414 bits<5> Rn; 1415 bits<5> Rm; 1416 let Inst{24-22} = 0b100; 1417 let Inst{21} = op; 1418 let Inst{9-5} = Rn; 1419 let Inst{4-0} = Rm; 1420} 1421 1422class AuthOneOperand<bits<3> opc, bits<1> M, string asm> 1423 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> { 1424 bits<5> Rn; 1425 let Inst{24} = 0; 1426 let Inst{23-21} = opc; 1427 let Inst{9-5} = Rn; 1428} 1429 1430class AuthReturn<bits<3> op, bits<1> M, string asm> 1431 : AuthBase<M, (outs), (ins), asm, "", []> { 1432 let Inst{24} = 0; 1433 let Inst{23-21} = op; 1434 let Inst{9-0} = 0b1111111111; 1435} 1436 1437let mayLoad = 1 in 1438class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm, 1439 string operands, string cstr, Operand opr> 1440 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> { 1441 bits<10> offset; 1442 bits<5> Rn; 1443 bits<5> Rt; 1444 let Inst{31-24} = 0b11111000; 1445 let Inst{23} = M; 1446 let Inst{22} = offset{9}; 1447 let Inst{21} = 1; 1448 let Inst{20-12} = offset{8-0}; 1449 let Inst{11} = W; 1450 let Inst{10} = 1; 1451 let Inst{9-5} = Rn; 1452 let Inst{4-0} = Rt; 1453} 1454 1455multiclass AuthLoad<bit M, string asm, Operand opr> { 1456 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt), 1457 (ins GPR64sp:$Rn, opr:$offset), 1458 asm, "\t$Rt, [$Rn, $offset]", "", opr>; 1459 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt), 1460 (ins GPR64sp:$Rn, opr:$offset), 1461 asm, "\t$Rt, [$Rn, $offset]!", 1462 "$Rn = $wback,@earlyclobber $wback", opr>; 1463 1464 def : InstAlias<asm # "\t$Rt, [$Rn]", 1465 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>; 1466} 1467 1468//--- 1469// Conditional branch instruction. 1470//--- 1471 1472// Condition code. 1473// 4-bit immediate. Pretty-printed as <cc> 1474def ccode : Operand<i32> { 1475 let PrintMethod = "printCondCode"; 1476 let ParserMatchClass = CondCode; 1477} 1478def inv_ccode : Operand<i32> { 1479 // AL and NV are invalid in the aliases which use inv_ccode 1480 let PrintMethod = "printInverseCondCode"; 1481 let ParserMatchClass = CondCode; 1482 let MCOperandPredicate = [{ 1483 return MCOp.isImm() && 1484 MCOp.getImm() != AArch64CC::AL && 1485 MCOp.getImm() != AArch64CC::NV; 1486 }]; 1487} 1488 1489// Conditional branch target. 19-bit immediate. The low two bits of the target 1490// offset are implied zero and so are not part of the immediate. 1491def am_brcond : Operand<OtherVT> { 1492 let EncoderMethod = "getCondBranchTargetOpValue"; 1493 let DecoderMethod = "DecodePCRelLabel19"; 1494 let PrintMethod = "printAlignedLabel"; 1495 let ParserMatchClass = PCRelLabel19Operand; 1496 let OperandType = "OPERAND_PCREL"; 1497} 1498 1499class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1500 "b", ".$cond\t$target", "", 1501 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1502 Sched<[WriteBr]> { 1503 let isBranch = 1; 1504 let isTerminator = 1; 1505 let Uses = [NZCV]; 1506 1507 bits<4> cond; 1508 bits<19> target; 1509 let Inst{31-24} = 0b01010100; 1510 let Inst{23-5} = target; 1511 let Inst{4} = 0; 1512 let Inst{3-0} = cond; 1513} 1514 1515//--- 1516// Compare-and-branch instructions. 1517//--- 1518class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1519 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1520 asm, "\t$Rt, $target", "", 1521 [(node regtype:$Rt, bb:$target)]>, 1522 Sched<[WriteBr]> { 1523 let isBranch = 1; 1524 let isTerminator = 1; 1525 1526 bits<5> Rt; 1527 bits<19> target; 1528 let Inst{30-25} = 0b011010; 1529 let Inst{24} = op; 1530 let Inst{23-5} = target; 1531 let Inst{4-0} = Rt; 1532} 1533 1534multiclass CmpBranch<bit op, string asm, SDNode node> { 1535 def W : BaseCmpBranch<GPR32, op, asm, node> { 1536 let Inst{31} = 0; 1537 } 1538 def X : BaseCmpBranch<GPR64, op, asm, node> { 1539 let Inst{31} = 1; 1540 } 1541} 1542 1543//--- 1544// Test-bit-and-branch instructions. 1545//--- 1546// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1547// the target offset are implied zero and so are not part of the immediate. 1548def am_tbrcond : Operand<OtherVT> { 1549 let EncoderMethod = "getTestBranchTargetOpValue"; 1550 let PrintMethod = "printAlignedLabel"; 1551 let ParserMatchClass = BranchTarget14Operand; 1552 let OperandType = "OPERAND_PCREL"; 1553} 1554 1555// AsmOperand classes to emit (or not) special diagnostics 1556def TBZImm0_31Operand : AsmOperandClass { 1557 let Name = "TBZImm0_31"; 1558 let PredicateMethod = "isImmInRange<0,31>"; 1559 let RenderMethod = "addImmOperands"; 1560} 1561def TBZImm32_63Operand : AsmOperandClass { 1562 let Name = "Imm32_63"; 1563 let PredicateMethod = "isImmInRange<32,63>"; 1564 let DiagnosticType = "InvalidImm0_63"; 1565 let RenderMethod = "addImmOperands"; 1566} 1567 1568class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1569 return (((uint32_t)Imm) < 32); 1570}]> { 1571 let ParserMatchClass = matcher; 1572} 1573 1574def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1575def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1576 1577def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1578 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1579}]> { 1580 let ParserMatchClass = TBZImm32_63Operand; 1581} 1582 1583class BaseTestBranch<RegisterClass regtype, Operand immtype, 1584 bit op, string asm, SDNode node> 1585 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1586 asm, "\t$Rt, $bit_off, $target", "", 1587 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1588 Sched<[WriteBr]> { 1589 let isBranch = 1; 1590 let isTerminator = 1; 1591 1592 bits<5> Rt; 1593 bits<6> bit_off; 1594 bits<14> target; 1595 1596 let Inst{30-25} = 0b011011; 1597 let Inst{24} = op; 1598 let Inst{23-19} = bit_off{4-0}; 1599 let Inst{18-5} = target; 1600 let Inst{4-0} = Rt; 1601 1602 let DecoderMethod = "DecodeTestAndBranch"; 1603} 1604 1605multiclass TestBranch<bit op, string asm, SDNode node> { 1606 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1607 let Inst{31} = 0; 1608 } 1609 1610 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1611 let Inst{31} = 1; 1612 } 1613 1614 // Alias X-reg with 0-31 imm to W-Reg. 1615 def : InstAlias<asm # "\t$Rd, $imm, $target", 1616 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1617 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1618 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1619 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1620 tbz_imm0_31_diag:$imm, bb:$target)>; 1621} 1622 1623//--- 1624// Unconditional branch (immediate) instructions. 1625//--- 1626def am_b_target : Operand<OtherVT> { 1627 let EncoderMethod = "getBranchTargetOpValue"; 1628 let PrintMethod = "printAlignedLabel"; 1629 let ParserMatchClass = BranchTarget26Operand; 1630 let OperandType = "OPERAND_PCREL"; 1631} 1632def am_bl_target : Operand<i64> { 1633 let EncoderMethod = "getBranchTargetOpValue"; 1634 let PrintMethod = "printAlignedLabel"; 1635 let ParserMatchClass = BranchTarget26Operand; 1636 let OperandType = "OPERAND_PCREL"; 1637} 1638 1639class BImm<bit op, dag iops, string asm, list<dag> pattern> 1640 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1641 bits<26> addr; 1642 let Inst{31} = op; 1643 let Inst{30-26} = 0b00101; 1644 let Inst{25-0} = addr; 1645 1646 let DecoderMethod = "DecodeUnconditionalBranch"; 1647} 1648 1649class BranchImm<bit op, string asm, list<dag> pattern> 1650 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1651class CallImm<bit op, string asm, list<dag> pattern> 1652 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1653 1654//--- 1655// Basic one-operand data processing instructions. 1656//--- 1657 1658let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1659class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1660 SDPatternOperator node> 1661 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1662 [(set regtype:$Rd, (node regtype:$Rn))]>, 1663 Sched<[WriteI, ReadI]> { 1664 bits<5> Rd; 1665 bits<5> Rn; 1666 1667 let Inst{30-13} = 0b101101011000000000; 1668 let Inst{12-10} = opc; 1669 let Inst{9-5} = Rn; 1670 let Inst{4-0} = Rd; 1671} 1672 1673let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1674multiclass OneOperandData<bits<3> opc, string asm, 1675 SDPatternOperator node = null_frag> { 1676 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1677 let Inst{31} = 0; 1678 } 1679 1680 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1681 let Inst{31} = 1; 1682 } 1683} 1684 1685class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1686 : BaseOneOperandData<opc, GPR32, asm, node> { 1687 let Inst{31} = 0; 1688} 1689 1690class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1691 : BaseOneOperandData<opc, GPR64, asm, node> { 1692 let Inst{31} = 1; 1693} 1694 1695class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm> 1696 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "", 1697 []>, 1698 Sched<[WriteI, ReadI]> { 1699 bits<5> Rd; 1700 bits<5> Rn; 1701 let Inst{31-15} = 0b11011010110000010; 1702 let Inst{14-12} = opcode_prefix; 1703 let Inst{11-10} = opcode; 1704 let Inst{9-5} = Rn; 1705 let Inst{4-0} = Rd; 1706} 1707 1708class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm> 1709 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> { 1710 bits<5> Rd; 1711 let Inst{31-15} = 0b11011010110000010; 1712 let Inst{14-12} = opcode_prefix; 1713 let Inst{11-10} = opcode; 1714 let Inst{9-5} = 0b11111; 1715 let Inst{4-0} = Rd; 1716} 1717 1718class SignAuthTwoOperand<bits<4> opc, string asm, 1719 SDPatternOperator OpNode> 1720 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm), 1721 asm, "\t$Rd, $Rn, $Rm", "", 1722 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>, 1723 Sched<[WriteI, ReadI, ReadI]> { 1724 bits<5> Rd; 1725 bits<5> Rn; 1726 bits<5> Rm; 1727 let Inst{31-21} = 0b10011010110; 1728 let Inst{20-16} = Rm; 1729 let Inst{15-14} = 0b00; 1730 let Inst{13-10} = opc; 1731 let Inst{9-5} = Rn; 1732 let Inst{4-0} = Rd; 1733} 1734 1735// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions 1736class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops> 1737 : I<(outs), iops, asm, ops, "", []>, 1738 Sched<[WriteI, ReadI, ReadI]> { 1739 let Uses = [NZCV]; 1740 bits<5> Rn; 1741 let Inst{31} = sf; 1742 let Inst{30-15} = 0b0111010000000000; 1743 let Inst{14} = sz; 1744 let Inst{13-10} = 0b0010; 1745 let Inst{9-5} = Rn; 1746 let Inst{4-0} = 0b01101; 1747} 1748 1749class FlagRotate<dag iops, string asm, string ops> 1750 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> { 1751 bits<6> imm; 1752 bits<4> mask; 1753 let Inst{20-15} = imm; 1754 let Inst{13-10} = 0b0001; 1755 let Inst{4} = 0b0; 1756 let Inst{3-0} = mask; 1757} 1758 1759//--- 1760// Basic two-operand data processing instructions. 1761//--- 1762class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1763 list<dag> pattern> 1764 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1765 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1766 Sched<[WriteI, ReadI, ReadI]> { 1767 let Uses = [NZCV]; 1768 bits<5> Rd; 1769 bits<5> Rn; 1770 bits<5> Rm; 1771 let Inst{30} = isSub; 1772 let Inst{28-21} = 0b11010000; 1773 let Inst{20-16} = Rm; 1774 let Inst{15-10} = 0; 1775 let Inst{9-5} = Rn; 1776 let Inst{4-0} = Rd; 1777} 1778 1779class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1780 SDNode OpNode> 1781 : BaseBaseAddSubCarry<isSub, regtype, asm, 1782 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 1783 1784class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 1785 SDNode OpNode> 1786 : BaseBaseAddSubCarry<isSub, regtype, asm, 1787 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 1788 (implicit NZCV)]> { 1789 let Defs = [NZCV]; 1790} 1791 1792multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 1793 SDNode OpNode, SDNode OpNode_setflags> { 1794 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 1795 let Inst{31} = 0; 1796 let Inst{29} = 0; 1797 } 1798 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 1799 let Inst{31} = 1; 1800 let Inst{29} = 0; 1801 } 1802 1803 // Sets flags. 1804 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 1805 OpNode_setflags> { 1806 let Inst{31} = 0; 1807 let Inst{29} = 1; 1808 } 1809 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 1810 OpNode_setflags> { 1811 let Inst{31} = 1; 1812 let Inst{29} = 1; 1813 } 1814} 1815 1816class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 1817 SDPatternOperator OpNode, 1818 RegisterClass in1regtype = regtype, 1819 RegisterClass in2regtype = regtype> 1820 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm), 1821 asm, "\t$Rd, $Rn, $Rm", "", 1822 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> { 1823 bits<5> Rd; 1824 bits<5> Rn; 1825 bits<5> Rm; 1826 let Inst{30-21} = 0b0011010110; 1827 let Inst{20-16} = Rm; 1828 let Inst{15-14} = 0b00; 1829 let Inst{13-10} = opc; 1830 let Inst{9-5} = Rn; 1831 let Inst{4-0} = Rd; 1832} 1833 1834class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 1835 SDPatternOperator OpNode> 1836 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 1837 let Inst{10} = isSigned; 1838} 1839 1840multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 1841 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 1842 Sched<[WriteID32, ReadID, ReadID]> { 1843 let Inst{31} = 0; 1844 } 1845 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 1846 Sched<[WriteID64, ReadID, ReadID]> { 1847 let Inst{31} = 1; 1848 } 1849} 1850 1851class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 1852 SDPatternOperator OpNode = null_frag> 1853 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 1854 Sched<[WriteIS, ReadI]> { 1855 let Inst{11-10} = shift_type; 1856} 1857 1858multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 1859 def Wr : BaseShift<shift_type, GPR32, asm> { 1860 let Inst{31} = 0; 1861 } 1862 1863 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 1864 let Inst{31} = 1; 1865 } 1866 1867 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 1868 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 1869 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 1870 1871 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 1872 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1873 1874 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 1875 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1876 1877 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 1878 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1879 1880 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))), 1881 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 1882 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 1883 1884 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))), 1885 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn, 1886 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>; 1887} 1888 1889class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 1890 : InstAlias<asm#"\t$dst, $src1, $src2", 1891 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 1892 1893class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 1894 RegisterClass addtype, string asm, 1895 list<dag> pattern> 1896 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 1897 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 1898 bits<5> Rd; 1899 bits<5> Rn; 1900 bits<5> Rm; 1901 bits<5> Ra; 1902 let Inst{30-24} = 0b0011011; 1903 let Inst{23-21} = opc; 1904 let Inst{20-16} = Rm; 1905 let Inst{15} = isSub; 1906 let Inst{14-10} = Ra; 1907 let Inst{9-5} = Rn; 1908 let Inst{4-0} = Rd; 1909} 1910 1911multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 1912 // MADD/MSUB generation is decided by MachineCombiner.cpp 1913 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 1914 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 1915 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1916 let Inst{31} = 0; 1917 } 1918 1919 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 1920 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 1921 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 1922 let Inst{31} = 1; 1923 } 1924} 1925 1926class WideMulAccum<bit isSub, bits<3> opc, string asm, 1927 SDNode AccNode, SDNode ExtNode> 1928 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 1929 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 1930 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 1931 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1932 let Inst{31} = 1; 1933} 1934 1935class MulHi<bits<3> opc, string asm, SDNode OpNode> 1936 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 1937 asm, "\t$Rd, $Rn, $Rm", "", 1938 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 1939 Sched<[WriteIM64, ReadIM, ReadIM]> { 1940 bits<5> Rd; 1941 bits<5> Rn; 1942 bits<5> Rm; 1943 let Inst{31-24} = 0b10011011; 1944 let Inst{23-21} = opc; 1945 let Inst{20-16} = Rm; 1946 let Inst{15} = 0; 1947 let Inst{9-5} = Rn; 1948 let Inst{4-0} = Rd; 1949 1950 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 1951 // (i.e. all bits 1) but is ignored by the processor. 1952 let PostEncoderMethod = "fixMulHigh"; 1953} 1954 1955class MulAccumWAlias<string asm, Instruction inst> 1956 : InstAlias<asm#"\t$dst, $src1, $src2", 1957 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 1958class MulAccumXAlias<string asm, Instruction inst> 1959 : InstAlias<asm#"\t$dst, $src1, $src2", 1960 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 1961class WideMulAccumAlias<string asm, Instruction inst> 1962 : InstAlias<asm#"\t$dst, $src1, $src2", 1963 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 1964 1965class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 1966 SDPatternOperator OpNode, string asm> 1967 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 1968 asm, "\t$Rd, $Rn, $Rm", "", 1969 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 1970 Sched<[WriteISReg, ReadI, ReadISReg]> { 1971 bits<5> Rd; 1972 bits<5> Rn; 1973 bits<5> Rm; 1974 1975 let Inst{31} = sf; 1976 let Inst{30-21} = 0b0011010110; 1977 let Inst{20-16} = Rm; 1978 let Inst{15-13} = 0b010; 1979 let Inst{12} = C; 1980 let Inst{11-10} = sz; 1981 let Inst{9-5} = Rn; 1982 let Inst{4-0} = Rd; 1983 let Predicates = [HasCRC]; 1984} 1985 1986//--- 1987// Address generation. 1988//--- 1989 1990class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 1991 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 1992 pattern>, 1993 Sched<[WriteI]> { 1994 bits<5> Xd; 1995 bits<21> label; 1996 let Inst{31} = page; 1997 let Inst{30-29} = label{1-0}; 1998 let Inst{28-24} = 0b10000; 1999 let Inst{23-5} = label{20-2}; 2000 let Inst{4-0} = Xd; 2001 2002 let DecoderMethod = "DecodeAdrInstruction"; 2003} 2004 2005//--- 2006// Move immediate. 2007//--- 2008 2009def movimm32_imm : Operand<i32> { 2010 let ParserMatchClass = AsmImmRange<0, 65535>; 2011 let EncoderMethod = "getMoveWideImmOpValue"; 2012 let PrintMethod = "printImm"; 2013} 2014def movimm32_shift : Operand<i32> { 2015 let PrintMethod = "printShifter"; 2016 let ParserMatchClass = MovImm32ShifterOperand; 2017} 2018def movimm64_shift : Operand<i32> { 2019 let PrintMethod = "printShifter"; 2020 let ParserMatchClass = MovImm64ShifterOperand; 2021} 2022 2023let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2024class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2025 string asm> 2026 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 2027 asm, "\t$Rd, $imm$shift", "", []>, 2028 Sched<[WriteImm]> { 2029 bits<5> Rd; 2030 bits<16> imm; 2031 bits<6> shift; 2032 let Inst{30-29} = opc; 2033 let Inst{28-23} = 0b100101; 2034 let Inst{22-21} = shift{5-4}; 2035 let Inst{20-5} = imm; 2036 let Inst{4-0} = Rd; 2037 2038 let DecoderMethod = "DecodeMoveImmInstruction"; 2039} 2040 2041multiclass MoveImmediate<bits<2> opc, string asm> { 2042 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 2043 let Inst{31} = 0; 2044 } 2045 2046 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 2047 let Inst{31} = 1; 2048 } 2049} 2050 2051let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2052class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 2053 string asm> 2054 : I<(outs regtype:$Rd), 2055 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 2056 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 2057 Sched<[WriteI, ReadI]> { 2058 bits<5> Rd; 2059 bits<16> imm; 2060 bits<6> shift; 2061 let Inst{30-29} = opc; 2062 let Inst{28-23} = 0b100101; 2063 let Inst{22-21} = shift{5-4}; 2064 let Inst{20-5} = imm; 2065 let Inst{4-0} = Rd; 2066 2067 let DecoderMethod = "DecodeMoveImmInstruction"; 2068} 2069 2070multiclass InsertImmediate<bits<2> opc, string asm> { 2071 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 2072 let Inst{31} = 0; 2073 } 2074 2075 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 2076 let Inst{31} = 1; 2077 } 2078} 2079 2080//--- 2081// Add/Subtract 2082//--- 2083 2084class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 2085 string asm_inst, string asm_ops, 2086 dag inputs, dag pattern> 2087 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>, 2088 Sched<[WriteI, ReadI]> { 2089 bits<5> Rd; 2090 bits<5> Rn; 2091 let Inst{30} = isSub; 2092 let Inst{29} = setFlags; 2093 let Inst{28-24} = 0b10001; 2094 let Inst{9-5} = Rn; 2095 let Inst{4-0} = Rd; 2096} 2097 2098class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype, 2099 RegisterClass srcRegtype, addsub_shifted_imm immtype, 2100 string asm_inst, SDPatternOperator OpNode> 2101 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm", 2102 (ins srcRegtype:$Rn, immtype:$imm), 2103 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> { 2104 bits<14> imm; 2105 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 2106 let Inst{21-10} = imm{11-0}; 2107 let DecoderMethod = "DecodeAddSubImmShift"; 2108} 2109 2110class BaseAddSubRegPseudo<RegisterClass regtype, 2111 SDPatternOperator OpNode> 2112 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2113 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2114 Sched<[WriteI, ReadI, ReadI]>; 2115 2116class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 2117 arith_shifted_reg shifted_regtype, string asm, 2118 SDPatternOperator OpNode> 2119 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2120 asm, "\t$Rd, $Rn, $Rm", "", 2121 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 2122 Sched<[WriteISReg, ReadI, ReadISReg]> { 2123 // The operands are in order to match the 'addr' MI operands, so we 2124 // don't need an encoder method and by-name matching. Just use the default 2125 // in-order handling. Since we're using by-order, make sure the names 2126 // do not match. 2127 bits<5> dst; 2128 bits<5> src1; 2129 bits<5> src2; 2130 bits<8> shift; 2131 let Inst{30} = isSub; 2132 let Inst{29} = setFlags; 2133 let Inst{28-24} = 0b01011; 2134 let Inst{23-22} = shift{7-6}; 2135 let Inst{21} = 0; 2136 let Inst{20-16} = src2; 2137 let Inst{15-10} = shift{5-0}; 2138 let Inst{9-5} = src1; 2139 let Inst{4-0} = dst; 2140 2141 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2142} 2143 2144class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 2145 RegisterClass src1Regtype, Operand src2Regtype, 2146 string asm, SDPatternOperator OpNode> 2147 : I<(outs dstRegtype:$R1), 2148 (ins src1Regtype:$R2, src2Regtype:$R3), 2149 asm, "\t$R1, $R2, $R3", "", 2150 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 2151 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2152 bits<5> Rd; 2153 bits<5> Rn; 2154 bits<5> Rm; 2155 bits<6> ext; 2156 let Inst{30} = isSub; 2157 let Inst{29} = setFlags; 2158 let Inst{28-24} = 0b01011; 2159 let Inst{23-21} = 0b001; 2160 let Inst{20-16} = Rm; 2161 let Inst{15-13} = ext{5-3}; 2162 let Inst{12-10} = ext{2-0}; 2163 let Inst{9-5} = Rn; 2164 let Inst{4-0} = Rd; 2165 2166 let DecoderMethod = "DecodeAddSubERegInstruction"; 2167} 2168 2169let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2170class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 2171 RegisterClass src1Regtype, RegisterClass src2Regtype, 2172 Operand ext_op, string asm> 2173 : I<(outs dstRegtype:$Rd), 2174 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 2175 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 2176 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 2177 bits<5> Rd; 2178 bits<5> Rn; 2179 bits<5> Rm; 2180 bits<6> ext; 2181 let Inst{30} = isSub; 2182 let Inst{29} = setFlags; 2183 let Inst{28-24} = 0b01011; 2184 let Inst{23-21} = 0b001; 2185 let Inst{20-16} = Rm; 2186 let Inst{15} = ext{5}; 2187 let Inst{12-10} = ext{2-0}; 2188 let Inst{9-5} = Rn; 2189 let Inst{4-0} = Rd; 2190 2191 let DecoderMethod = "DecodeAddSubERegInstruction"; 2192} 2193 2194// Aliases for register+register add/subtract. 2195class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 2196 RegisterClass src1Regtype, RegisterClass src2Regtype, 2197 int shiftExt> 2198 : InstAlias<asm#"\t$dst, $src1, $src2", 2199 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 2200 shiftExt)>; 2201 2202multiclass AddSub<bit isSub, string mnemonic, string alias, 2203 SDPatternOperator OpNode = null_frag> { 2204 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2205 // Add/Subtract immediate 2206 // Increase the weight of the immediate variant to try to match it before 2207 // the extended register variant. 2208 // We used to match the register variant before the immediate when the 2209 // register argument could be implicitly zero-extended. 2210 let AddedComplexity = 6 in 2211 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 2212 mnemonic, OpNode> { 2213 let Inst{31} = 0; 2214 } 2215 let AddedComplexity = 6 in 2216 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 2217 mnemonic, OpNode> { 2218 let Inst{31} = 1; 2219 } 2220 2221 // Add/Subtract register - Only used for CodeGen 2222 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2223 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2224 2225 // Add/Subtract shifted register 2226 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 2227 OpNode> { 2228 let Inst{31} = 0; 2229 } 2230 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 2231 OpNode> { 2232 let Inst{31} = 1; 2233 } 2234 } 2235 2236 // Add/Subtract extended register 2237 let AddedComplexity = 1, hasSideEffects = 0 in { 2238 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 2239 arith_extended_reg32_i32, mnemonic, OpNode> { 2240 let Inst{31} = 0; 2241 } 2242 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 2243 arith_extended_reg32to64_i64, mnemonic, OpNode> { 2244 let Inst{31} = 1; 2245 } 2246 } 2247 2248 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 2249 arith_extendlsl64, mnemonic> { 2250 // UXTX and SXTX only. 2251 let Inst{14-13} = 0b11; 2252 let Inst{31} = 1; 2253 } 2254 2255 // add Rd, Rb, -imm -> sub Rd, Rn, imm 2256 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2257 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 2258 addsub_shifted_imm32_neg:$imm), 0>; 2259 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2260 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 2261 addsub_shifted_imm64_neg:$imm), 0>; 2262 2263 // Register/register aliases with no shift when SP is not used. 2264 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2265 GPR32, GPR32, GPR32, 0>; 2266 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2267 GPR64, GPR64, GPR64, 0>; 2268 2269 // Register/register aliases with no shift when either the destination or 2270 // first source register is SP. 2271 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2272 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 2273 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2274 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 2275 def : AddSubRegAlias<mnemonic, 2276 !cast<Instruction>(NAME#"Xrx64"), 2277 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 2278 def : AddSubRegAlias<mnemonic, 2279 !cast<Instruction>(NAME#"Xrx64"), 2280 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 2281} 2282 2283multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 2284 string alias, string cmpAlias> { 2285 let isCompare = 1, Defs = [NZCV] in { 2286 // Add/Subtract immediate 2287 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 2288 mnemonic, OpNode> { 2289 let Inst{31} = 0; 2290 } 2291 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 2292 mnemonic, OpNode> { 2293 let Inst{31} = 1; 2294 } 2295 2296 // Add/Subtract register 2297 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 2298 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 2299 2300 // Add/Subtract shifted register 2301 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 2302 OpNode> { 2303 let Inst{31} = 0; 2304 } 2305 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 2306 OpNode> { 2307 let Inst{31} = 1; 2308 } 2309 2310 // Add/Subtract extended register 2311 let AddedComplexity = 1 in { 2312 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 2313 arith_extended_reg32_i32, mnemonic, OpNode> { 2314 let Inst{31} = 0; 2315 } 2316 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 2317 arith_extended_reg32_i64, mnemonic, OpNode> { 2318 let Inst{31} = 1; 2319 } 2320 } 2321 2322 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 2323 arith_extendlsl64, mnemonic> { 2324 // UXTX and SXTX only. 2325 let Inst{14-13} = 0b11; 2326 let Inst{31} = 1; 2327 } 2328 } // Defs = [NZCV] 2329 2330 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 2331 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2332 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 2333 addsub_shifted_imm32_neg:$imm), 0>; 2334 def : InstSubst<alias#"\t$Rd, $Rn, $imm", 2335 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 2336 addsub_shifted_imm64_neg:$imm), 0>; 2337 2338 // Compare aliases 2339 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2340 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 2341 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2342 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 2343 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 2344 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2345 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 2346 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 2347 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 2348 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 2349 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 2350 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 2351 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 2352 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 2353 2354 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 2355 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 2356 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 2357 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 2358 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 2359 2360 // Compare shorthands 2361 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 2362 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 2363 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 2364 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 2365 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 2366 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 2367 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 2368 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 2369 2370 // Register/register aliases with no shift when SP is not used. 2371 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 2372 GPR32, GPR32, GPR32, 0>; 2373 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 2374 GPR64, GPR64, GPR64, 0>; 2375 2376 // Register/register aliases with no shift when the first source register 2377 // is SP. 2378 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 2379 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 2380 def : AddSubRegAlias<mnemonic, 2381 !cast<Instruction>(NAME#"Xrx64"), 2382 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 2383} 2384 2385class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode> 2386 : BaseAddSubImm< 2387 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4", 2388 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4), 2389 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> { 2390 bits<6> imm6; 2391 bits<4> imm4; 2392 let Inst{31} = 1; 2393 let Inst{23-22} = 0b10; 2394 let Inst{21-16} = imm6; 2395 let Inst{15-14} = 0b00; 2396 let Inst{13-10} = imm4; 2397 let Unpredictable{15-14} = 0b11; 2398} 2399 2400class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode> 2401 : BaseTwoOperand<0b0000, GPR64, asm_instr, OpNode, GPR64sp, GPR64sp> { 2402 let Inst{31} = 1; 2403 let Inst{29} = setsFlags; 2404} 2405 2406//--- 2407// Extract 2408//--- 2409def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2410 SDTCisPtrTy<3>]>; 2411def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 2412 2413class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 2414 list<dag> patterns> 2415 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 2416 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 2417 Sched<[WriteExtr, ReadExtrHi]> { 2418 bits<5> Rd; 2419 bits<5> Rn; 2420 bits<5> Rm; 2421 bits<6> imm; 2422 2423 let Inst{30-23} = 0b00100111; 2424 let Inst{21} = 0; 2425 let Inst{20-16} = Rm; 2426 let Inst{15-10} = imm; 2427 let Inst{9-5} = Rn; 2428 let Inst{4-0} = Rd; 2429} 2430 2431multiclass ExtractImm<string asm> { 2432 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 2433 [(set GPR32:$Rd, 2434 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 2435 let Inst{31} = 0; 2436 let Inst{22} = 0; 2437 // imm<5> must be zero. 2438 let imm{5} = 0; 2439 } 2440 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 2441 [(set GPR64:$Rd, 2442 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 2443 2444 let Inst{31} = 1; 2445 let Inst{22} = 1; 2446 } 2447} 2448 2449//--- 2450// Bitfield 2451//--- 2452 2453let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2454class BaseBitfieldImm<bits<2> opc, 2455 RegisterClass regtype, Operand imm_type, string asm> 2456 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 2457 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 2458 Sched<[WriteIS, ReadI]> { 2459 bits<5> Rd; 2460 bits<5> Rn; 2461 bits<6> immr; 2462 bits<6> imms; 2463 2464 let Inst{30-29} = opc; 2465 let Inst{28-23} = 0b100110; 2466 let Inst{21-16} = immr; 2467 let Inst{15-10} = imms; 2468 let Inst{9-5} = Rn; 2469 let Inst{4-0} = Rd; 2470} 2471 2472multiclass BitfieldImm<bits<2> opc, string asm> { 2473 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 2474 let Inst{31} = 0; 2475 let Inst{22} = 0; 2476 // imms<5> and immr<5> must be zero, else ReservedValue(). 2477 let Inst{21} = 0; 2478 let Inst{15} = 0; 2479 } 2480 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 2481 let Inst{31} = 1; 2482 let Inst{22} = 1; 2483 } 2484} 2485 2486let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2487class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2488 RegisterClass regtype, Operand imm_type, string asm> 2489 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2490 imm_type:$imms), 2491 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2492 Sched<[WriteIS, ReadI]> { 2493 bits<5> Rd; 2494 bits<5> Rn; 2495 bits<6> immr; 2496 bits<6> imms; 2497 2498 let Inst{30-29} = opc; 2499 let Inst{28-23} = 0b100110; 2500 let Inst{21-16} = immr; 2501 let Inst{15-10} = imms; 2502 let Inst{9-5} = Rn; 2503 let Inst{4-0} = Rd; 2504} 2505 2506multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2507 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2508 let Inst{31} = 0; 2509 let Inst{22} = 0; 2510 // imms<5> and immr<5> must be zero, else ReservedValue(). 2511 let Inst{21} = 0; 2512 let Inst{15} = 0; 2513 } 2514 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2515 let Inst{31} = 1; 2516 let Inst{22} = 1; 2517 } 2518} 2519 2520//--- 2521// Logical 2522//--- 2523 2524// Logical (immediate) 2525class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2526 RegisterClass sregtype, Operand imm_type, string asm, 2527 list<dag> pattern> 2528 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2529 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2530 Sched<[WriteI, ReadI]> { 2531 bits<5> Rd; 2532 bits<5> Rn; 2533 bits<13> imm; 2534 let Inst{30-29} = opc; 2535 let Inst{28-23} = 0b100100; 2536 let Inst{22} = imm{12}; 2537 let Inst{21-16} = imm{11-6}; 2538 let Inst{15-10} = imm{5-0}; 2539 let Inst{9-5} = Rn; 2540 let Inst{4-0} = Rd; 2541 2542 let DecoderMethod = "DecodeLogicalImmInstruction"; 2543} 2544 2545// Logical (shifted register) 2546class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2547 logical_shifted_reg shifted_regtype, string asm, 2548 list<dag> pattern> 2549 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2550 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2551 Sched<[WriteISReg, ReadI, ReadISReg]> { 2552 // The operands are in order to match the 'addr' MI operands, so we 2553 // don't need an encoder method and by-name matching. Just use the default 2554 // in-order handling. Since we're using by-order, make sure the names 2555 // do not match. 2556 bits<5> dst; 2557 bits<5> src1; 2558 bits<5> src2; 2559 bits<8> shift; 2560 let Inst{30-29} = opc; 2561 let Inst{28-24} = 0b01010; 2562 let Inst{23-22} = shift{7-6}; 2563 let Inst{21} = N; 2564 let Inst{20-16} = src2; 2565 let Inst{15-10} = shift{5-0}; 2566 let Inst{9-5} = src1; 2567 let Inst{4-0} = dst; 2568 2569 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2570} 2571 2572// Aliases for register+register logical instructions. 2573class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2574 : InstAlias<asm#"\t$dst, $src1, $src2", 2575 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2576 2577multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2578 string Alias> { 2579 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2580 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2581 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2582 logical_imm32:$imm))]> { 2583 let Inst{31} = 0; 2584 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2585 } 2586 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2587 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2588 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2589 logical_imm64:$imm))]> { 2590 let Inst{31} = 1; 2591 } 2592 2593 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2594 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2595 logical_imm32_not:$imm), 0>; 2596 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2597 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2598 logical_imm64_not:$imm), 0>; 2599} 2600 2601multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2602 string Alias> { 2603 let isCompare = 1, Defs = [NZCV] in { 2604 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2605 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2606 let Inst{31} = 0; 2607 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2608 } 2609 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2610 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2611 let Inst{31} = 1; 2612 } 2613 } // end Defs = [NZCV] 2614 2615 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2616 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2617 logical_imm32_not:$imm), 0>; 2618 def : InstSubst<Alias # "\t$Rd, $Rn, $imm", 2619 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2620 logical_imm64_not:$imm), 0>; 2621} 2622 2623class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2624 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2625 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2626 Sched<[WriteI, ReadI, ReadI]>; 2627 2628// Split from LogicalImm as not all instructions have both. 2629multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2630 SDPatternOperator OpNode> { 2631 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2632 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2633 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2634 } 2635 2636 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2637 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2638 logical_shifted_reg32:$Rm))]> { 2639 let Inst{31} = 0; 2640 } 2641 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2642 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2643 logical_shifted_reg64:$Rm))]> { 2644 let Inst{31} = 1; 2645 } 2646 2647 def : LogicalRegAlias<mnemonic, 2648 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2649 def : LogicalRegAlias<mnemonic, 2650 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2651} 2652 2653// Split from LogicalReg to allow setting NZCV Defs 2654multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2655 SDPatternOperator OpNode = null_frag> { 2656 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2657 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2658 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2659 2660 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2661 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2662 let Inst{31} = 0; 2663 } 2664 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2665 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2666 let Inst{31} = 1; 2667 } 2668 } // Defs = [NZCV] 2669 2670 def : LogicalRegAlias<mnemonic, 2671 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2672 def : LogicalRegAlias<mnemonic, 2673 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2674} 2675 2676//--- 2677// Conditionally set flags 2678//--- 2679 2680let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2681class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2682 string mnemonic, SDNode OpNode> 2683 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2684 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2685 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2686 (i32 imm:$cond), NZCV))]>, 2687 Sched<[WriteI, ReadI]> { 2688 let Uses = [NZCV]; 2689 let Defs = [NZCV]; 2690 2691 bits<5> Rn; 2692 bits<5> imm; 2693 bits<4> nzcv; 2694 bits<4> cond; 2695 2696 let Inst{30} = op; 2697 let Inst{29-21} = 0b111010010; 2698 let Inst{20-16} = imm; 2699 let Inst{15-12} = cond; 2700 let Inst{11-10} = 0b10; 2701 let Inst{9-5} = Rn; 2702 let Inst{4} = 0b0; 2703 let Inst{3-0} = nzcv; 2704} 2705 2706let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2707class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2708 SDNode OpNode> 2709 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2710 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2711 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2712 (i32 imm:$cond), NZCV))]>, 2713 Sched<[WriteI, ReadI, ReadI]> { 2714 let Uses = [NZCV]; 2715 let Defs = [NZCV]; 2716 2717 bits<5> Rn; 2718 bits<5> Rm; 2719 bits<4> nzcv; 2720 bits<4> cond; 2721 2722 let Inst{30} = op; 2723 let Inst{29-21} = 0b111010010; 2724 let Inst{20-16} = Rm; 2725 let Inst{15-12} = cond; 2726 let Inst{11-10} = 0b00; 2727 let Inst{9-5} = Rn; 2728 let Inst{4} = 0b0; 2729 let Inst{3-0} = nzcv; 2730} 2731 2732multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2733 // immediate operand variants 2734 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2735 let Inst{31} = 0; 2736 } 2737 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2738 let Inst{31} = 1; 2739 } 2740 // register operand variants 2741 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2742 let Inst{31} = 0; 2743 } 2744 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2745 let Inst{31} = 1; 2746 } 2747} 2748 2749//--- 2750// Conditional select 2751//--- 2752 2753class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2754 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2755 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2756 [(set regtype:$Rd, 2757 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2758 Sched<[WriteI, ReadI, ReadI]> { 2759 let Uses = [NZCV]; 2760 2761 bits<5> Rd; 2762 bits<5> Rn; 2763 bits<5> Rm; 2764 bits<4> cond; 2765 2766 let Inst{30} = op; 2767 let Inst{29-21} = 0b011010100; 2768 let Inst{20-16} = Rm; 2769 let Inst{15-12} = cond; 2770 let Inst{11-10} = op2; 2771 let Inst{9-5} = Rn; 2772 let Inst{4-0} = Rd; 2773} 2774 2775multiclass CondSelect<bit op, bits<2> op2, string asm> { 2776 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2777 let Inst{31} = 0; 2778 } 2779 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 2780 let Inst{31} = 1; 2781 } 2782} 2783 2784class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 2785 PatFrag frag> 2786 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2787 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2788 [(set regtype:$Rd, 2789 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 2790 (i32 imm:$cond), NZCV))]>, 2791 Sched<[WriteI, ReadI, ReadI]> { 2792 let Uses = [NZCV]; 2793 2794 bits<5> Rd; 2795 bits<5> Rn; 2796 bits<5> Rm; 2797 bits<4> cond; 2798 2799 let Inst{30} = op; 2800 let Inst{29-21} = 0b011010100; 2801 let Inst{20-16} = Rm; 2802 let Inst{15-12} = cond; 2803 let Inst{11-10} = op2; 2804 let Inst{9-5} = Rn; 2805 let Inst{4-0} = Rd; 2806} 2807 2808def inv_cond_XFORM : SDNodeXForm<imm, [{ 2809 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 2810 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 2811 MVT::i32); 2812}]>; 2813 2814multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 2815 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 2816 let Inst{31} = 0; 2817 } 2818 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 2819 let Inst{31} = 1; 2820 } 2821 2822 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 2823 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 2824 (inv_cond_XFORM imm:$cond))>; 2825 2826 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 2827 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 2828 (inv_cond_XFORM imm:$cond))>; 2829} 2830 2831//--- 2832// Special Mask Value 2833//--- 2834def maski8_or_more : Operand<i32>, 2835 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 2836} 2837def maski16_or_more : Operand<i32>, 2838 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 2839} 2840 2841 2842//--- 2843// Load/store 2844//--- 2845 2846// (unsigned immediate) 2847// Indexed for 8-bit registers. offset is in range [0,4095]. 2848def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 2849def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 2850def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 2851def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 2852def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 2853 2854def gi_am_indexed8 : 2855 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">, 2856 GIComplexPatternEquiv<am_indexed8>; 2857def gi_am_indexed16 : 2858 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">, 2859 GIComplexPatternEquiv<am_indexed16>; 2860def gi_am_indexed32 : 2861 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">, 2862 GIComplexPatternEquiv<am_indexed32>; 2863def gi_am_indexed64 : 2864 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">, 2865 GIComplexPatternEquiv<am_indexed64>; 2866def gi_am_indexed128 : 2867 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">, 2868 GIComplexPatternEquiv<am_indexed128>; 2869 2870class UImm12OffsetOperand<int Scale> : AsmOperandClass { 2871 let Name = "UImm12Offset" # Scale; 2872 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 2873 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 2874 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 2875} 2876 2877def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 2878def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 2879def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 2880def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 2881def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 2882 2883class uimm12_scaled<int Scale> : Operand<i64> { 2884 let ParserMatchClass 2885 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 2886 let EncoderMethod 2887 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 2888 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 2889} 2890 2891def uimm12s1 : uimm12_scaled<1>; 2892def uimm12s2 : uimm12_scaled<2>; 2893def uimm12s4 : uimm12_scaled<4>; 2894def uimm12s8 : uimm12_scaled<8>; 2895def uimm12s16 : uimm12_scaled<16>; 2896 2897class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2898 string asm, list<dag> pattern> 2899 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 2900 bits<5> Rt; 2901 2902 bits<5> Rn; 2903 bits<12> offset; 2904 2905 let Inst{31-30} = sz; 2906 let Inst{29-27} = 0b111; 2907 let Inst{26} = V; 2908 let Inst{25-24} = 0b01; 2909 let Inst{23-22} = opc; 2910 let Inst{21-10} = offset; 2911 let Inst{9-5} = Rn; 2912 let Inst{4-0} = Rt; 2913 2914 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 2915} 2916 2917multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 2918 Operand indextype, string asm, list<dag> pattern> { 2919 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2920 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 2921 (ins GPR64sp:$Rn, indextype:$offset), 2922 asm, pattern>, 2923 Sched<[WriteLD]>; 2924 2925 def : InstAlias<asm # "\t$Rt, [$Rn]", 2926 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2927} 2928 2929multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 2930 Operand indextype, string asm, list<dag> pattern> { 2931 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2932 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 2933 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 2934 asm, pattern>, 2935 Sched<[WriteST]>; 2936 2937 def : InstAlias<asm # "\t$Rt, [$Rn]", 2938 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2939} 2940 2941// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to 2942// substitute zero-registers automatically. 2943// 2944// TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back 2945// into StoreUI. 2946multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 2947 Operand indextype, string asm, list<dag> pattern> { 2948 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2949 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 2950 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 2951 asm, pattern>, 2952 Sched<[WriteST]>; 2953 2954 def : InstAlias<asm # "\t$Rt, [$Rn]", 2955 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2956} 2957 2958def PrefetchOperand : AsmOperandClass { 2959 let Name = "Prefetch"; 2960 let ParserMethod = "tryParsePrefetch"; 2961} 2962def prfop : Operand<i32> { 2963 let PrintMethod = "printPrefetchOp"; 2964 let ParserMatchClass = PrefetchOperand; 2965} 2966 2967let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2968class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 2969 : BaseLoadStoreUI<sz, V, opc, 2970 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 2971 asm, pat>, 2972 Sched<[WriteLD]>; 2973 2974//--- 2975// Load literal 2976//--- 2977 2978// Load literal address: 19-bit immediate. The low two bits of the target 2979// offset are implied zero and so are not part of the immediate. 2980def am_ldrlit : Operand<iPTR> { 2981 let EncoderMethod = "getLoadLiteralOpValue"; 2982 let DecoderMethod = "DecodePCRelLabel19"; 2983 let PrintMethod = "printAlignedLabel"; 2984 let ParserMatchClass = PCRelLabel19Operand; 2985 let OperandType = "OPERAND_PCREL"; 2986} 2987 2988let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in 2989class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat> 2990 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 2991 asm, "\t$Rt, $label", "", pat>, 2992 Sched<[WriteLD]> { 2993 bits<5> Rt; 2994 bits<19> label; 2995 let Inst{31-30} = opc; 2996 let Inst{29-27} = 0b011; 2997 let Inst{26} = V; 2998 let Inst{25-24} = 0b00; 2999 let Inst{23-5} = label; 3000 let Inst{4-0} = Rt; 3001} 3002 3003let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3004class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 3005 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 3006 asm, "\t$Rt, $label", "", pat>, 3007 Sched<[WriteLD]> { 3008 bits<5> Rt; 3009 bits<19> label; 3010 let Inst{31-30} = opc; 3011 let Inst{29-27} = 0b011; 3012 let Inst{26} = V; 3013 let Inst{25-24} = 0b00; 3014 let Inst{23-5} = label; 3015 let Inst{4-0} = Rt; 3016} 3017 3018//--- 3019// Load/store register offset 3020//--- 3021 3022def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 3023def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 3024def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 3025def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 3026def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 3027 3028def gi_ro_Xindexed8 : 3029 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">, 3030 GIComplexPatternEquiv<ro_Xindexed8>; 3031def gi_ro_Xindexed16 : 3032 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">, 3033 GIComplexPatternEquiv<ro_Xindexed16>; 3034def gi_ro_Xindexed32 : 3035 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">, 3036 GIComplexPatternEquiv<ro_Xindexed32>; 3037def gi_ro_Xindexed64 : 3038 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">, 3039 GIComplexPatternEquiv<ro_Xindexed64>; 3040def gi_ro_Xindexed128 : 3041 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">, 3042 GIComplexPatternEquiv<ro_Xindexed128>; 3043 3044def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 3045def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 3046def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 3047def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 3048def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 3049 3050class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 3051 let Name = "Mem" # Reg # "Extend" # Width; 3052 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 3053 let RenderMethod = "addMemExtendOperands"; 3054 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 3055} 3056 3057def MemWExtend8Operand : MemExtendOperand<"W", 8> { 3058 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3059 // the trivial shift. 3060 let RenderMethod = "addMemExtend8Operands"; 3061} 3062def MemWExtend16Operand : MemExtendOperand<"W", 16>; 3063def MemWExtend32Operand : MemExtendOperand<"W", 32>; 3064def MemWExtend64Operand : MemExtendOperand<"W", 64>; 3065def MemWExtend128Operand : MemExtendOperand<"W", 128>; 3066 3067def MemXExtend8Operand : MemExtendOperand<"X", 8> { 3068 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 3069 // the trivial shift. 3070 let RenderMethod = "addMemExtend8Operands"; 3071} 3072def MemXExtend16Operand : MemExtendOperand<"X", 16>; 3073def MemXExtend32Operand : MemExtendOperand<"X", 32>; 3074def MemXExtend64Operand : MemExtendOperand<"X", 64>; 3075def MemXExtend128Operand : MemExtendOperand<"X", 128>; 3076 3077class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 3078 : Operand<i32> { 3079 let ParserMatchClass = ParserClass; 3080 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 3081 let DecoderMethod = "DecodeMemExtend"; 3082 let EncoderMethod = "getMemExtendOpValue"; 3083 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 3084} 3085 3086def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 3087def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 3088def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 3089def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 3090def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 3091 3092def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 3093def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 3094def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 3095def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 3096def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 3097 3098class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 3099 Operand wextend, Operand xextend> { 3100 // CodeGen-level pattern covering the entire addressing mode. 3101 ComplexPattern Wpat = windex; 3102 ComplexPattern Xpat = xindex; 3103 3104 // Asm-level Operand covering the valid "uxtw #3" style syntax. 3105 Operand Wext = wextend; 3106 Operand Xext = xextend; 3107} 3108 3109def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 3110def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 3111def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 3112def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 3113def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 3114 ro_Xextend128>; 3115 3116class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3117 string asm, dag ins, dag outs, list<dag> pat> 3118 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3119 bits<5> Rt; 3120 bits<5> Rn; 3121 bits<5> Rm; 3122 bits<2> extend; 3123 let Inst{31-30} = sz; 3124 let Inst{29-27} = 0b111; 3125 let Inst{26} = V; 3126 let Inst{25-24} = 0b00; 3127 let Inst{23-22} = opc; 3128 let Inst{21} = 1; 3129 let Inst{20-16} = Rm; 3130 let Inst{15} = extend{1}; // sign extend Rm? 3131 let Inst{14} = 1; 3132 let Inst{12} = extend{0}; // do shift? 3133 let Inst{11-10} = 0b10; 3134 let Inst{9-5} = Rn; 3135 let Inst{4-0} = Rt; 3136} 3137 3138class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST> 3139 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 3140 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3141 3142multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3143 string asm, ValueType Ty, SDPatternOperator loadop> { 3144 let AddedComplexity = 10 in 3145 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 3146 (outs regtype:$Rt), 3147 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3148 [(set (Ty regtype:$Rt), 3149 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3150 ro_Wextend8:$extend)))]>, 3151 Sched<[WriteLDIdx, ReadAdrBase]> { 3152 let Inst{13} = 0b0; 3153 } 3154 3155 let AddedComplexity = 10 in 3156 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 3157 (outs regtype:$Rt), 3158 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3159 [(set (Ty regtype:$Rt), 3160 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3161 ro_Xextend8:$extend)))]>, 3162 Sched<[WriteLDIdx, ReadAdrBase]> { 3163 let Inst{13} = 0b1; 3164 } 3165 3166 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3167} 3168 3169multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3170 string asm, ValueType Ty, SDPatternOperator storeop> { 3171 let AddedComplexity = 10 in 3172 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3173 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 3174 [(storeop (Ty regtype:$Rt), 3175 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 3176 ro_Wextend8:$extend))]>, 3177 Sched<[WriteSTIdx, ReadAdrBase]> { 3178 let Inst{13} = 0b0; 3179 } 3180 3181 let AddedComplexity = 10 in 3182 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 3183 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 3184 [(storeop (Ty regtype:$Rt), 3185 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 3186 ro_Xextend8:$extend))]>, 3187 Sched<[WriteSTIdx, ReadAdrBase]> { 3188 let Inst{13} = 0b1; 3189 } 3190 3191 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3192} 3193 3194class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3195 string asm, dag ins, dag outs, list<dag> pat> 3196 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3197 bits<5> Rt; 3198 bits<5> Rn; 3199 bits<5> Rm; 3200 bits<2> extend; 3201 let Inst{31-30} = sz; 3202 let Inst{29-27} = 0b111; 3203 let Inst{26} = V; 3204 let Inst{25-24} = 0b00; 3205 let Inst{23-22} = opc; 3206 let Inst{21} = 1; 3207 let Inst{20-16} = Rm; 3208 let Inst{15} = extend{1}; // sign extend Rm? 3209 let Inst{14} = 1; 3210 let Inst{12} = extend{0}; // do shift? 3211 let Inst{11-10} = 0b10; 3212 let Inst{9-5} = Rn; 3213 let Inst{4-0} = Rt; 3214} 3215 3216multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3217 string asm, ValueType Ty, SDPatternOperator loadop> { 3218 let AddedComplexity = 10 in 3219 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3220 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3221 [(set (Ty regtype:$Rt), 3222 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3223 ro_Wextend16:$extend)))]>, 3224 Sched<[WriteLDIdx, ReadAdrBase]> { 3225 let Inst{13} = 0b0; 3226 } 3227 3228 let AddedComplexity = 10 in 3229 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3230 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3231 [(set (Ty regtype:$Rt), 3232 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3233 ro_Xextend16:$extend)))]>, 3234 Sched<[WriteLDIdx, ReadAdrBase]> { 3235 let Inst{13} = 0b1; 3236 } 3237 3238 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3239} 3240 3241multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3242 string asm, ValueType Ty, SDPatternOperator storeop> { 3243 let AddedComplexity = 10 in 3244 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3245 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 3246 [(storeop (Ty regtype:$Rt), 3247 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 3248 ro_Wextend16:$extend))]>, 3249 Sched<[WriteSTIdx, ReadAdrBase]> { 3250 let Inst{13} = 0b0; 3251 } 3252 3253 let AddedComplexity = 10 in 3254 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 3255 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 3256 [(storeop (Ty regtype:$Rt), 3257 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 3258 ro_Xextend16:$extend))]>, 3259 Sched<[WriteSTIdx, ReadAdrBase]> { 3260 let Inst{13} = 0b1; 3261 } 3262 3263 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3264} 3265 3266class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3267 string asm, dag ins, dag outs, list<dag> pat> 3268 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3269 bits<5> Rt; 3270 bits<5> Rn; 3271 bits<5> Rm; 3272 bits<2> extend; 3273 let Inst{31-30} = sz; 3274 let Inst{29-27} = 0b111; 3275 let Inst{26} = V; 3276 let Inst{25-24} = 0b00; 3277 let Inst{23-22} = opc; 3278 let Inst{21} = 1; 3279 let Inst{20-16} = Rm; 3280 let Inst{15} = extend{1}; // sign extend Rm? 3281 let Inst{14} = 1; 3282 let Inst{12} = extend{0}; // do shift? 3283 let Inst{11-10} = 0b10; 3284 let Inst{9-5} = Rn; 3285 let Inst{4-0} = Rt; 3286} 3287 3288multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3289 string asm, ValueType Ty, SDPatternOperator loadop> { 3290 let AddedComplexity = 10 in 3291 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3292 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3293 [(set (Ty regtype:$Rt), 3294 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3295 ro_Wextend32:$extend)))]>, 3296 Sched<[WriteLDIdx, ReadAdrBase]> { 3297 let Inst{13} = 0b0; 3298 } 3299 3300 let AddedComplexity = 10 in 3301 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3302 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3303 [(set (Ty regtype:$Rt), 3304 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3305 ro_Xextend32:$extend)))]>, 3306 Sched<[WriteLDIdx, ReadAdrBase]> { 3307 let Inst{13} = 0b1; 3308 } 3309 3310 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3311} 3312 3313multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3314 string asm, ValueType Ty, SDPatternOperator storeop> { 3315 let AddedComplexity = 10 in 3316 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3317 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 3318 [(storeop (Ty regtype:$Rt), 3319 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 3320 ro_Wextend32:$extend))]>, 3321 Sched<[WriteSTIdx, ReadAdrBase]> { 3322 let Inst{13} = 0b0; 3323 } 3324 3325 let AddedComplexity = 10 in 3326 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 3327 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 3328 [(storeop (Ty regtype:$Rt), 3329 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 3330 ro_Xextend32:$extend))]>, 3331 Sched<[WriteSTIdx, ReadAdrBase]> { 3332 let Inst{13} = 0b1; 3333 } 3334 3335 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3336} 3337 3338class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3339 string asm, dag ins, dag outs, list<dag> pat> 3340 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3341 bits<5> Rt; 3342 bits<5> Rn; 3343 bits<5> Rm; 3344 bits<2> extend; 3345 let Inst{31-30} = sz; 3346 let Inst{29-27} = 0b111; 3347 let Inst{26} = V; 3348 let Inst{25-24} = 0b00; 3349 let Inst{23-22} = opc; 3350 let Inst{21} = 1; 3351 let Inst{20-16} = Rm; 3352 let Inst{15} = extend{1}; // sign extend Rm? 3353 let Inst{14} = 1; 3354 let Inst{12} = extend{0}; // do shift? 3355 let Inst{11-10} = 0b10; 3356 let Inst{9-5} = Rn; 3357 let Inst{4-0} = Rt; 3358} 3359 3360multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3361 string asm, ValueType Ty, SDPatternOperator loadop> { 3362 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3363 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3364 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3365 [(set (Ty regtype:$Rt), 3366 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3367 ro_Wextend64:$extend)))]>, 3368 Sched<[WriteLDIdx, ReadAdrBase]> { 3369 let Inst{13} = 0b0; 3370 } 3371 3372 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3373 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3374 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3375 [(set (Ty regtype:$Rt), 3376 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3377 ro_Xextend64:$extend)))]>, 3378 Sched<[WriteLDIdx, ReadAdrBase]> { 3379 let Inst{13} = 0b1; 3380 } 3381 3382 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3383} 3384 3385multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3386 string asm, ValueType Ty, SDPatternOperator storeop> { 3387 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3388 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3389 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3390 [(storeop (Ty regtype:$Rt), 3391 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3392 ro_Wextend64:$extend))]>, 3393 Sched<[WriteSTIdx, ReadAdrBase]> { 3394 let Inst{13} = 0b0; 3395 } 3396 3397 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3398 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 3399 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3400 [(storeop (Ty regtype:$Rt), 3401 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3402 ro_Xextend64:$extend))]>, 3403 Sched<[WriteSTIdx, ReadAdrBase]> { 3404 let Inst{13} = 0b1; 3405 } 3406 3407 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3408} 3409 3410class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3411 string asm, dag ins, dag outs, list<dag> pat> 3412 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 3413 bits<5> Rt; 3414 bits<5> Rn; 3415 bits<5> Rm; 3416 bits<2> extend; 3417 let Inst{31-30} = sz; 3418 let Inst{29-27} = 0b111; 3419 let Inst{26} = V; 3420 let Inst{25-24} = 0b00; 3421 let Inst{23-22} = opc; 3422 let Inst{21} = 1; 3423 let Inst{20-16} = Rm; 3424 let Inst{15} = extend{1}; // sign extend Rm? 3425 let Inst{14} = 1; 3426 let Inst{12} = extend{0}; // do shift? 3427 let Inst{11-10} = 0b10; 3428 let Inst{9-5} = Rn; 3429 let Inst{4-0} = Rt; 3430} 3431 3432multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3433 string asm, ValueType Ty, SDPatternOperator loadop> { 3434 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3435 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3436 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3437 [(set (Ty regtype:$Rt), 3438 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 3439 ro_Wextend128:$extend)))]>, 3440 Sched<[WriteLDIdx, ReadAdrBase]> { 3441 let Inst{13} = 0b0; 3442 } 3443 3444 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 3445 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 3446 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3447 [(set (Ty regtype:$Rt), 3448 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 3449 ro_Xextend128:$extend)))]>, 3450 Sched<[WriteLDIdx, ReadAdrBase]> { 3451 let Inst{13} = 0b1; 3452 } 3453 3454 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3455} 3456 3457multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3458 string asm, ValueType Ty, SDPatternOperator storeop> { 3459 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3460 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3461 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 3462 []>, 3463 Sched<[WriteSTIdx, ReadAdrBase]> { 3464 let Inst{13} = 0b0; 3465 } 3466 3467 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 3468 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 3469 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 3470 []>, 3471 Sched<[WriteSTIdx, ReadAdrBase]> { 3472 let Inst{13} = 0b1; 3473 } 3474 3475 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 3476} 3477 3478let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3479class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 3480 string asm, list<dag> pat> 3481 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 3482 Sched<[WriteLD]> { 3483 bits<5> Rt; 3484 bits<5> Rn; 3485 bits<5> Rm; 3486 bits<2> extend; 3487 let Inst{31-30} = sz; 3488 let Inst{29-27} = 0b111; 3489 let Inst{26} = V; 3490 let Inst{25-24} = 0b00; 3491 let Inst{23-22} = opc; 3492 let Inst{21} = 1; 3493 let Inst{20-16} = Rm; 3494 let Inst{15} = extend{1}; // sign extend Rm? 3495 let Inst{14} = 1; 3496 let Inst{12} = extend{0}; // do shift? 3497 let Inst{11-10} = 0b10; 3498 let Inst{9-5} = Rn; 3499 let Inst{4-0} = Rt; 3500} 3501 3502multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 3503 def roW : BasePrefetchRO<sz, V, opc, (outs), 3504 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 3505 asm, [(AArch64Prefetch imm:$Rt, 3506 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 3507 ro_Wextend64:$extend))]> { 3508 let Inst{13} = 0b0; 3509 } 3510 3511 def roX : BasePrefetchRO<sz, V, opc, (outs), 3512 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 3513 asm, [(AArch64Prefetch imm:$Rt, 3514 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 3515 ro_Xextend64:$extend))]> { 3516 let Inst{13} = 0b1; 3517 } 3518 3519 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 3520 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 3521 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 3522} 3523 3524//--- 3525// Load/store unscaled immediate 3526//--- 3527 3528def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 3529def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 3530def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 3531def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 3532def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3533 3534def gi_am_unscaled8 : 3535 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">, 3536 GIComplexPatternEquiv<am_unscaled8>; 3537def gi_am_unscaled16 : 3538 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">, 3539 GIComplexPatternEquiv<am_unscaled16>; 3540def gi_am_unscaled32 : 3541 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">, 3542 GIComplexPatternEquiv<am_unscaled32>; 3543def gi_am_unscaled64 : 3544 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">, 3545 GIComplexPatternEquiv<am_unscaled64>; 3546def gi_am_unscaled128 : 3547 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">, 3548 GIComplexPatternEquiv<am_unscaled128>; 3549 3550 3551class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3552 string asm, list<dag> pattern> 3553 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3554 bits<5> Rt; 3555 bits<5> Rn; 3556 bits<9> offset; 3557 let Inst{31-30} = sz; 3558 let Inst{29-27} = 0b111; 3559 let Inst{26} = V; 3560 let Inst{25-24} = 0b00; 3561 let Inst{23-22} = opc; 3562 let Inst{21} = 0; 3563 let Inst{20-12} = offset; 3564 let Inst{11-10} = 0b00; 3565 let Inst{9-5} = Rn; 3566 let Inst{4-0} = Rt; 3567 3568 let DecoderMethod = "DecodeSignedLdStInstruction"; 3569} 3570 3571// Armv8.4 LDAPR & STLR with Immediate Offset instruction 3572multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3573 RegisterOperand regtype > { 3574 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt), 3575 (ins GPR64sp:$Rn, simm9:$offset), asm, []>, 3576 Sched<[WriteST]> { 3577 let Inst{29} = 0; 3578 let Inst{24} = 1; 3579 } 3580 def : InstAlias<asm # "\t$Rt, [$Rn]", 3581 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3582} 3583 3584multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc, 3585 RegisterOperand regtype > { 3586 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs), 3587 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3588 asm, []>, 3589 Sched<[WriteST]> { 3590 let Inst{29} = 0; 3591 let Inst{24} = 1; 3592 } 3593 def : InstAlias<asm # "\t$Rt, [$Rn]", 3594 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3595} 3596 3597multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3598 string asm, list<dag> pattern> { 3599 let AddedComplexity = 1 in // try this before LoadUI 3600 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3601 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3602 Sched<[WriteLD]>; 3603 3604 def : InstAlias<asm # "\t$Rt, [$Rn]", 3605 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3606} 3607 3608multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3609 string asm, list<dag> pattern> { 3610 let AddedComplexity = 1 in // try this before StoreUI 3611 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3612 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3613 asm, pattern>, 3614 Sched<[WriteST]>; 3615 3616 def : InstAlias<asm # "\t$Rt, [$Rn]", 3617 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3618} 3619 3620multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3621 list<dag> pat> { 3622 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3623 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3624 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3625 asm, pat>, 3626 Sched<[WriteLD]>; 3627 3628 def : InstAlias<asm # "\t$Rt, [$Rn]", 3629 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3630} 3631 3632//--- 3633// Load/store unscaled immediate, unprivileged 3634//--- 3635 3636class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3637 dag oops, dag iops, string asm> 3638 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3639 bits<5> Rt; 3640 bits<5> Rn; 3641 bits<9> offset; 3642 let Inst{31-30} = sz; 3643 let Inst{29-27} = 0b111; 3644 let Inst{26} = V; 3645 let Inst{25-24} = 0b00; 3646 let Inst{23-22} = opc; 3647 let Inst{21} = 0; 3648 let Inst{20-12} = offset; 3649 let Inst{11-10} = 0b10; 3650 let Inst{9-5} = Rn; 3651 let Inst{4-0} = Rt; 3652 3653 let DecoderMethod = "DecodeSignedLdStInstruction"; 3654} 3655 3656multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3657 RegisterClass regtype, string asm> { 3658 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3659 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3660 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3661 Sched<[WriteLD]>; 3662 3663 def : InstAlias<asm # "\t$Rt, [$Rn]", 3664 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3665} 3666 3667multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3668 RegisterClass regtype, string asm> { 3669 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3670 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3671 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3672 asm>, 3673 Sched<[WriteST]>; 3674 3675 def : InstAlias<asm # "\t$Rt, [$Rn]", 3676 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3677} 3678 3679//--- 3680// Load/store pre-indexed 3681//--- 3682 3683class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3684 string asm, string cstr, list<dag> pat> 3685 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3686 bits<5> Rt; 3687 bits<5> Rn; 3688 bits<9> offset; 3689 let Inst{31-30} = sz; 3690 let Inst{29-27} = 0b111; 3691 let Inst{26} = V; 3692 let Inst{25-24} = 0; 3693 let Inst{23-22} = opc; 3694 let Inst{21} = 0; 3695 let Inst{20-12} = offset; 3696 let Inst{11-10} = 0b11; 3697 let Inst{9-5} = Rn; 3698 let Inst{4-0} = Rt; 3699 3700 let DecoderMethod = "DecodeSignedLdStInstruction"; 3701} 3702 3703let hasSideEffects = 0 in { 3704let mayStore = 0, mayLoad = 1 in 3705class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3706 string asm> 3707 : BaseLoadStorePreIdx<sz, V, opc, 3708 (outs GPR64sp:$wback, regtype:$Rt), 3709 (ins GPR64sp:$Rn, simm9:$offset), asm, 3710 "$Rn = $wback,@earlyclobber $wback", []>, 3711 Sched<[WriteLD, WriteAdr]>; 3712 3713let mayStore = 1, mayLoad = 0 in 3714class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3715 string asm, SDPatternOperator storeop, ValueType Ty> 3716 : BaseLoadStorePreIdx<sz, V, opc, 3717 (outs GPR64sp:$wback), 3718 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3719 asm, "$Rn = $wback,@earlyclobber $wback", 3720 [(set GPR64sp:$wback, 3721 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3722 Sched<[WriteAdr, WriteST]>; 3723} // hasSideEffects = 0 3724 3725//--- 3726// Load/store post-indexed 3727//--- 3728 3729class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3730 string asm, string cstr, list<dag> pat> 3731 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3732 bits<5> Rt; 3733 bits<5> Rn; 3734 bits<9> offset; 3735 let Inst{31-30} = sz; 3736 let Inst{29-27} = 0b111; 3737 let Inst{26} = V; 3738 let Inst{25-24} = 0b00; 3739 let Inst{23-22} = opc; 3740 let Inst{21} = 0b0; 3741 let Inst{20-12} = offset; 3742 let Inst{11-10} = 0b01; 3743 let Inst{9-5} = Rn; 3744 let Inst{4-0} = Rt; 3745 3746 let DecoderMethod = "DecodeSignedLdStInstruction"; 3747} 3748 3749let hasSideEffects = 0 in { 3750let mayStore = 0, mayLoad = 1 in 3751class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3752 string asm> 3753 : BaseLoadStorePostIdx<sz, V, opc, 3754 (outs GPR64sp:$wback, regtype:$Rt), 3755 (ins GPR64sp:$Rn, simm9:$offset), 3756 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3757 Sched<[WriteLD, WriteAdr]>; 3758 3759let mayStore = 1, mayLoad = 0 in 3760class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype, 3761 string asm, SDPatternOperator storeop, ValueType Ty> 3762 : BaseLoadStorePostIdx<sz, V, opc, 3763 (outs GPR64sp:$wback), 3764 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3765 asm, "$Rn = $wback,@earlyclobber $wback", 3766 [(set GPR64sp:$wback, 3767 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3768 Sched<[WriteAdr, WriteST]>; 3769} // hasSideEffects = 0 3770 3771 3772//--- 3773// Load/store pair 3774//--- 3775 3776// (indexed, offset) 3777 3778class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 3779 string asm> 3780 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3781 bits<5> Rt; 3782 bits<5> Rt2; 3783 bits<5> Rn; 3784 bits<7> offset; 3785 let Inst{31-30} = opc; 3786 let Inst{29-27} = 0b101; 3787 let Inst{26} = V; 3788 let Inst{25-23} = 0b010; 3789 let Inst{22} = L; 3790 let Inst{21-15} = offset; 3791 let Inst{14-10} = Rt2; 3792 let Inst{9-5} = Rn; 3793 let Inst{4-0} = Rt; 3794 3795 let DecoderMethod = "DecodePairLdStInstruction"; 3796} 3797 3798multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype, 3799 Operand indextype, string asm> { 3800 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3801 def i : BaseLoadStorePairOffset<opc, V, 1, 3802 (outs regtype:$Rt, regtype:$Rt2), 3803 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3804 Sched<[WriteLD, WriteLDHi]>; 3805 3806 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3807 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3808 GPR64sp:$Rn, 0)>; 3809} 3810 3811 3812multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype, 3813 Operand indextype, string asm> { 3814 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 3815 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 3816 (ins regtype:$Rt, regtype:$Rt2, 3817 GPR64sp:$Rn, indextype:$offset), 3818 asm>, 3819 Sched<[WriteSTP]>; 3820 3821 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3822 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3823 GPR64sp:$Rn, 0)>; 3824} 3825 3826// (pre-indexed) 3827class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3828 string asm> 3829 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 3830 bits<5> Rt; 3831 bits<5> Rt2; 3832 bits<5> Rn; 3833 bits<7> offset; 3834 let Inst{31-30} = opc; 3835 let Inst{29-27} = 0b101; 3836 let Inst{26} = V; 3837 let Inst{25-23} = 0b011; 3838 let Inst{22} = L; 3839 let Inst{21-15} = offset; 3840 let Inst{14-10} = Rt2; 3841 let Inst{9-5} = Rn; 3842 let Inst{4-0} = Rt; 3843 3844 let DecoderMethod = "DecodePairLdStInstruction"; 3845} 3846 3847let hasSideEffects = 0 in { 3848let mayStore = 0, mayLoad = 1 in 3849class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 3850 Operand indextype, string asm> 3851 : BaseLoadStorePairPreIdx<opc, V, 1, 3852 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3853 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3854 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3855 3856let mayStore = 1, mayLoad = 0 in 3857class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype, 3858 Operand indextype, string asm> 3859 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 3860 (ins regtype:$Rt, regtype:$Rt2, 3861 GPR64sp:$Rn, indextype:$offset), 3862 asm>, 3863 Sched<[WriteAdr, WriteSTP]>; 3864} // hasSideEffects = 0 3865 3866// (post-indexed) 3867 3868class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3869 string asm> 3870 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 3871 bits<5> Rt; 3872 bits<5> Rt2; 3873 bits<5> Rn; 3874 bits<7> offset; 3875 let Inst{31-30} = opc; 3876 let Inst{29-27} = 0b101; 3877 let Inst{26} = V; 3878 let Inst{25-23} = 0b001; 3879 let Inst{22} = L; 3880 let Inst{21-15} = offset; 3881 let Inst{14-10} = Rt2; 3882 let Inst{9-5} = Rn; 3883 let Inst{4-0} = Rt; 3884 3885 let DecoderMethod = "DecodePairLdStInstruction"; 3886} 3887 3888let hasSideEffects = 0 in { 3889let mayStore = 0, mayLoad = 1 in 3890class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 3891 Operand idxtype, string asm> 3892 : BaseLoadStorePairPostIdx<opc, V, 1, 3893 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3894 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 3895 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3896 3897let mayStore = 1, mayLoad = 0 in 3898class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype, 3899 Operand idxtype, string asm> 3900 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 3901 (ins regtype:$Rt, regtype:$Rt2, 3902 GPR64sp:$Rn, idxtype:$offset), 3903 asm>, 3904 Sched<[WriteAdr, WriteSTP]>; 3905} // hasSideEffects = 0 3906 3907// (no-allocate) 3908 3909class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 3910 string asm> 3911 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3912 bits<5> Rt; 3913 bits<5> Rt2; 3914 bits<5> Rn; 3915 bits<7> offset; 3916 let Inst{31-30} = opc; 3917 let Inst{29-27} = 0b101; 3918 let Inst{26} = V; 3919 let Inst{25-23} = 0b000; 3920 let Inst{22} = L; 3921 let Inst{21-15} = offset; 3922 let Inst{14-10} = Rt2; 3923 let Inst{9-5} = Rn; 3924 let Inst{4-0} = Rt; 3925 3926 let DecoderMethod = "DecodePairLdStInstruction"; 3927} 3928 3929multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3930 Operand indextype, string asm> { 3931 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3932 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 3933 (outs regtype:$Rt, regtype:$Rt2), 3934 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3935 Sched<[WriteLD, WriteLDHi]>; 3936 3937 3938 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3939 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3940 GPR64sp:$Rn, 0)>; 3941} 3942 3943multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3944 Operand indextype, string asm> { 3945 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 3946 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 3947 (ins regtype:$Rt, regtype:$Rt2, 3948 GPR64sp:$Rn, indextype:$offset), 3949 asm>, 3950 Sched<[WriteSTP]>; 3951 3952 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3953 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3954 GPR64sp:$Rn, 0)>; 3955} 3956 3957//--- 3958// Load/store exclusive 3959//--- 3960 3961// True exclusive operations write to and/or read from the system's exclusive 3962// monitors, which as far as a compiler is concerned can be modelled as a 3963// random shared memory address. Hence LoadExclusive mayStore. 3964// 3965// Since these instructions have the undefined register bits set to 1 in 3966// their canonical form, we need a post encoder method to set those bits 3967// to 1 when encoding these instructions. We do this using the 3968// fixLoadStoreExclusive function. This function has template parameters: 3969// 3970// fixLoadStoreExclusive<int hasRs, int hasRt2> 3971// 3972// hasRs indicates that the instruction uses the Rs field, so we won't set 3973// it to 1 (and the same for Rt2). We don't need template parameters for 3974// the other register fields since Rt and Rn are always used. 3975// 3976let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 3977class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3978 dag oops, dag iops, string asm, string operands> 3979 : I<oops, iops, asm, operands, "", []> { 3980 let Inst{31-30} = sz; 3981 let Inst{29-24} = 0b001000; 3982 let Inst{23} = o2; 3983 let Inst{22} = L; 3984 let Inst{21} = o1; 3985 let Inst{15} = o0; 3986 3987 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 3988} 3989 3990// Neither Rs nor Rt2 operands. 3991class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3992 dag oops, dag iops, string asm, string operands> 3993 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 3994 bits<5> Rt; 3995 bits<5> Rn; 3996 let Inst{20-16} = 0b11111; 3997 let Unpredictable{20-16} = 0b11111; 3998 let Inst{14-10} = 0b11111; 3999 let Unpredictable{14-10} = 0b11111; 4000 let Inst{9-5} = Rn; 4001 let Inst{4-0} = Rt; 4002 4003 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 4004} 4005 4006// Simple load acquires don't set the exclusive monitor 4007let mayLoad = 1, mayStore = 0 in 4008class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4009 RegisterClass regtype, string asm> 4010 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4011 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4012 Sched<[WriteLD]>; 4013 4014class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4015 RegisterClass regtype, string asm> 4016 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 4017 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 4018 Sched<[WriteLD]>; 4019 4020class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4021 RegisterClass regtype, string asm> 4022 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4023 (outs regtype:$Rt, regtype:$Rt2), 4024 (ins GPR64sp0:$Rn), asm, 4025 "\t$Rt, $Rt2, [$Rn]">, 4026 Sched<[WriteLD, WriteLDHi]> { 4027 bits<5> Rt; 4028 bits<5> Rt2; 4029 bits<5> Rn; 4030 let Inst{14-10} = Rt2; 4031 let Inst{9-5} = Rn; 4032 let Inst{4-0} = Rt; 4033 4034 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 4035} 4036 4037// Simple store release operations do not check the exclusive monitor. 4038let mayLoad = 0, mayStore = 1 in 4039class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4040 RegisterClass regtype, string asm> 4041 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 4042 (ins regtype:$Rt, GPR64sp0:$Rn), 4043 asm, "\t$Rt, [$Rn]">, 4044 Sched<[WriteST]>; 4045 4046let mayLoad = 1, mayStore = 1 in 4047class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4048 RegisterClass regtype, string asm> 4049 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 4050 (ins regtype:$Rt, GPR64sp0:$Rn), 4051 asm, "\t$Ws, $Rt, [$Rn]">, 4052 Sched<[WriteSTX]> { 4053 bits<5> Ws; 4054 bits<5> Rt; 4055 bits<5> Rn; 4056 let Inst{20-16} = Ws; 4057 let Inst{9-5} = Rn; 4058 let Inst{4-0} = Rt; 4059 4060 let Constraints = "@earlyclobber $Ws"; 4061 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 4062} 4063 4064class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 4065 RegisterClass regtype, string asm> 4066 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 4067 (outs GPR32:$Ws), 4068 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 4069 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 4070 Sched<[WriteSTX]> { 4071 bits<5> Ws; 4072 bits<5> Rt; 4073 bits<5> Rt2; 4074 bits<5> Rn; 4075 let Inst{20-16} = Ws; 4076 let Inst{14-10} = Rt2; 4077 let Inst{9-5} = Rn; 4078 let Inst{4-0} = Rt; 4079 4080 let Constraints = "@earlyclobber $Ws"; 4081} 4082 4083// Armv8.5-A Memory Tagging Extension 4084class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn, 4085 string asm_opnds, string cstr, dag oops, dag iops> 4086 : I<oops, iops, asm_insn, asm_opnds, cstr, []>, 4087 Sched<[]> { 4088 bits<5> Rn; 4089 4090 let Inst{31-24} = 0b11011001; 4091 let Inst{23-22} = opc1; 4092 let Inst{21} = 1; 4093 // Inst{20-12} defined by subclass 4094 let Inst{11-10} = opc2; 4095 let Inst{9-5} = Rn; 4096 // Inst{4-0} defined by subclass 4097} 4098 4099class MemTagVector<bit Load, string asm_insn, string asm_opnds, 4100 dag oops, dag iops> 4101 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds, 4102 "", oops, iops> { 4103 bits<5> Rt; 4104 4105 let Inst{20-12} = 0b000000000; 4106 let Inst{4-0} = Rt; 4107 4108 let mayLoad = Load; 4109} 4110 4111class MemTagLoad<string asm_insn, string asm_opnds> 4112 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback", 4113 (outs GPR64:$wback), 4114 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> { 4115 bits<5> Rt; 4116 bits<9> offset; 4117 4118 let Inst{20-12} = offset; 4119 let Inst{4-0} = Rt; 4120 4121 let mayLoad = 1; 4122} 4123 4124class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn, 4125 string asm_opnds, string cstr, dag oops, dag iops> 4126 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> { 4127 bits<5> Rt; 4128 bits<9> offset; 4129 4130 let Inst{20-12} = offset; 4131 let Inst{4-0} = Rt; 4132 4133 let mayStore = 1; 4134} 4135 4136multiclass MemTagStore<bits<2> opc1, string insn> { 4137 def Offset : 4138 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "", 4139 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4140 def PreIndex : 4141 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!", 4142 "$Rn = $wback", 4143 (outs GPR64sp:$wback), 4144 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4145 def PostIndex : 4146 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset", 4147 "$Rn = $wback", 4148 (outs GPR64sp:$wback), 4149 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>; 4150 4151 def : InstAlias<insn # "\t$Rt, [$Rn]", 4152 (!cast<Instruction>(NAME # "Offset") GPR64sp:$Rt, GPR64sp:$Rn, 0)>; 4153} 4154 4155//--- 4156// Exception generation 4157//--- 4158 4159let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 4160class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 4161 : I<(outs), (ins i32_imm0_65535:$imm), asm, "\t$imm", "", []>, 4162 Sched<[WriteSys]> { 4163 bits<16> imm; 4164 let Inst{31-24} = 0b11010100; 4165 let Inst{23-21} = op1; 4166 let Inst{20-5} = imm; 4167 let Inst{4-2} = 0b000; 4168 let Inst{1-0} = ll; 4169} 4170 4171//--- 4172// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. 4173//-- 4174let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { 4175class UDFType<bits<16> opc, string asm> 4176 : I<(outs), (ins uimm16:$imm), 4177 asm, "\t$imm", "", []>, 4178 Sched<[]> { 4179 bits<16> imm; 4180 let Inst{31-16} = opc; 4181 let Inst{15-0} = imm; 4182} 4183} 4184let Predicates = [HasFPARMv8] in { 4185 4186//--- 4187// Floating point to integer conversion 4188//--- 4189 4190class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 4191 RegisterClass srcType, RegisterClass dstType, 4192 string asm, list<dag> pattern> 4193 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4194 asm, "\t$Rd, $Rn", "", pattern>, 4195 Sched<[WriteFCvt]> { 4196 bits<5> Rd; 4197 bits<5> Rn; 4198 let Inst{30-29} = 0b00; 4199 let Inst{28-24} = 0b11110; 4200 let Inst{23-22} = type; 4201 let Inst{21} = 1; 4202 let Inst{20-19} = rmode; 4203 let Inst{18-16} = opcode; 4204 let Inst{15-10} = 0; 4205 let Inst{9-5} = Rn; 4206 let Inst{4-0} = Rd; 4207} 4208 4209let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4210class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 4211 RegisterClass srcType, RegisterClass dstType, 4212 Operand immType, string asm, list<dag> pattern> 4213 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4214 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4215 Sched<[WriteFCvt]> { 4216 bits<5> Rd; 4217 bits<5> Rn; 4218 bits<6> scale; 4219 let Inst{30-29} = 0b00; 4220 let Inst{28-24} = 0b11110; 4221 let Inst{23-22} = type; 4222 let Inst{21} = 0; 4223 let Inst{20-19} = rmode; 4224 let Inst{18-16} = opcode; 4225 let Inst{15-10} = scale; 4226 let Inst{9-5} = Rn; 4227 let Inst{4-0} = Rd; 4228} 4229 4230multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 4231 SDPatternOperator OpN> { 4232 // Unscaled half-precision to 32-bit 4233 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 4234 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> { 4235 let Inst{31} = 0; // 32-bit GPR flag 4236 let Predicates = [HasFullFP16]; 4237 } 4238 4239 // Unscaled half-precision to 64-bit 4240 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 4241 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> { 4242 let Inst{31} = 1; // 64-bit GPR flag 4243 let Predicates = [HasFullFP16]; 4244 } 4245 4246 // Unscaled single-precision to 32-bit 4247 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 4248 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 4249 let Inst{31} = 0; // 32-bit GPR flag 4250 } 4251 4252 // Unscaled single-precision to 64-bit 4253 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 4254 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 4255 let Inst{31} = 1; // 64-bit GPR flag 4256 } 4257 4258 // Unscaled double-precision to 32-bit 4259 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 4260 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4261 let Inst{31} = 0; // 32-bit GPR flag 4262 } 4263 4264 // Unscaled double-precision to 64-bit 4265 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 4266 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 4267 let Inst{31} = 1; // 64-bit GPR flag 4268 } 4269} 4270 4271multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 4272 SDPatternOperator OpN> { 4273 // Scaled half-precision to 32-bit 4274 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 4275 fixedpoint_f16_i32, asm, 4276 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn, 4277 fixedpoint_f16_i32:$scale)))]> { 4278 let Inst{31} = 0; // 32-bit GPR flag 4279 let scale{5} = 1; 4280 let Predicates = [HasFullFP16]; 4281 } 4282 4283 // Scaled half-precision to 64-bit 4284 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 4285 fixedpoint_f16_i64, asm, 4286 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn, 4287 fixedpoint_f16_i64:$scale)))]> { 4288 let Inst{31} = 1; // 64-bit GPR flag 4289 let Predicates = [HasFullFP16]; 4290 } 4291 4292 // Scaled single-precision to 32-bit 4293 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 4294 fixedpoint_f32_i32, asm, 4295 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 4296 fixedpoint_f32_i32:$scale)))]> { 4297 let Inst{31} = 0; // 32-bit GPR flag 4298 let scale{5} = 1; 4299 } 4300 4301 // Scaled single-precision to 64-bit 4302 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 4303 fixedpoint_f32_i64, asm, 4304 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 4305 fixedpoint_f32_i64:$scale)))]> { 4306 let Inst{31} = 1; // 64-bit GPR flag 4307 } 4308 4309 // Scaled double-precision to 32-bit 4310 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 4311 fixedpoint_f64_i32, asm, 4312 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 4313 fixedpoint_f64_i32:$scale)))]> { 4314 let Inst{31} = 0; // 32-bit GPR flag 4315 let scale{5} = 1; 4316 } 4317 4318 // Scaled double-precision to 64-bit 4319 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 4320 fixedpoint_f64_i64, asm, 4321 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 4322 fixedpoint_f64_i64:$scale)))]> { 4323 let Inst{31} = 1; // 64-bit GPR flag 4324 } 4325} 4326 4327//--- 4328// Integer to floating point conversion 4329//--- 4330 4331let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 4332class BaseIntegerToFP<bit isUnsigned, 4333 RegisterClass srcType, RegisterClass dstType, 4334 Operand immType, string asm, list<dag> pattern> 4335 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 4336 asm, "\t$Rd, $Rn, $scale", "", pattern>, 4337 Sched<[WriteFCvt]> { 4338 bits<5> Rd; 4339 bits<5> Rn; 4340 bits<6> scale; 4341 let Inst{30-24} = 0b0011110; 4342 let Inst{21-17} = 0b00001; 4343 let Inst{16} = isUnsigned; 4344 let Inst{15-10} = scale; 4345 let Inst{9-5} = Rn; 4346 let Inst{4-0} = Rd; 4347} 4348 4349class BaseIntegerToFPUnscaled<bit isUnsigned, 4350 RegisterClass srcType, RegisterClass dstType, 4351 ValueType dvt, string asm, SDNode node> 4352 : I<(outs dstType:$Rd), (ins srcType:$Rn), 4353 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 4354 Sched<[WriteFCvt]> { 4355 bits<5> Rd; 4356 bits<5> Rn; 4357 bits<6> scale; 4358 let Inst{30-24} = 0b0011110; 4359 let Inst{21-17} = 0b10001; 4360 let Inst{16} = isUnsigned; 4361 let Inst{15-10} = 0b000000; 4362 let Inst{9-5} = Rn; 4363 let Inst{4-0} = Rd; 4364} 4365 4366multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 4367 // Unscaled 4368 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 4369 let Inst{31} = 0; // 32-bit GPR flag 4370 let Inst{23-22} = 0b11; // 16-bit FPR flag 4371 let Predicates = [HasFullFP16]; 4372 } 4373 4374 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 4375 let Inst{31} = 0; // 32-bit GPR flag 4376 let Inst{23-22} = 0b00; // 32-bit FPR flag 4377 } 4378 4379 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 4380 let Inst{31} = 0; // 32-bit GPR flag 4381 let Inst{23-22} = 0b01; // 64-bit FPR flag 4382 } 4383 4384 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 4385 let Inst{31} = 1; // 64-bit GPR flag 4386 let Inst{23-22} = 0b11; // 16-bit FPR flag 4387 let Predicates = [HasFullFP16]; 4388 } 4389 4390 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 4391 let Inst{31} = 1; // 64-bit GPR flag 4392 let Inst{23-22} = 0b00; // 32-bit FPR flag 4393 } 4394 4395 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 4396 let Inst{31} = 1; // 64-bit GPR flag 4397 let Inst{23-22} = 0b01; // 64-bit FPR flag 4398 } 4399 4400 // Scaled 4401 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 4402 [(set FPR16:$Rd, 4403 (fdiv (node GPR32:$Rn), 4404 fixedpoint_f16_i32:$scale))]> { 4405 let Inst{31} = 0; // 32-bit GPR flag 4406 let Inst{23-22} = 0b11; // 16-bit FPR flag 4407 let scale{5} = 1; 4408 let Predicates = [HasFullFP16]; 4409 } 4410 4411 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 4412 [(set FPR32:$Rd, 4413 (fdiv (node GPR32:$Rn), 4414 fixedpoint_f32_i32:$scale))]> { 4415 let Inst{31} = 0; // 32-bit GPR flag 4416 let Inst{23-22} = 0b00; // 32-bit FPR flag 4417 let scale{5} = 1; 4418 } 4419 4420 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 4421 [(set FPR64:$Rd, 4422 (fdiv (node GPR32:$Rn), 4423 fixedpoint_f64_i32:$scale))]> { 4424 let Inst{31} = 0; // 32-bit GPR flag 4425 let Inst{23-22} = 0b01; // 64-bit FPR flag 4426 let scale{5} = 1; 4427 } 4428 4429 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 4430 [(set FPR16:$Rd, 4431 (fdiv (node GPR64:$Rn), 4432 fixedpoint_f16_i64:$scale))]> { 4433 let Inst{31} = 1; // 64-bit GPR flag 4434 let Inst{23-22} = 0b11; // 16-bit FPR flag 4435 let Predicates = [HasFullFP16]; 4436 } 4437 4438 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 4439 [(set FPR32:$Rd, 4440 (fdiv (node GPR64:$Rn), 4441 fixedpoint_f32_i64:$scale))]> { 4442 let Inst{31} = 1; // 64-bit GPR flag 4443 let Inst{23-22} = 0b00; // 32-bit FPR flag 4444 } 4445 4446 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 4447 [(set FPR64:$Rd, 4448 (fdiv (node GPR64:$Rn), 4449 fixedpoint_f64_i64:$scale))]> { 4450 let Inst{31} = 1; // 64-bit GPR flag 4451 let Inst{23-22} = 0b01; // 64-bit FPR flag 4452 } 4453} 4454 4455//--- 4456// Unscaled integer <-> floating point conversion (i.e. FMOV) 4457//--- 4458 4459let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4460class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 4461 RegisterClass srcType, RegisterClass dstType, 4462 string asm> 4463 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 4464 // We use COPY_TO_REGCLASS for these bitconvert operations. 4465 // copyPhysReg() expands the resultant COPY instructions after 4466 // regalloc is done. This gives greater freedom for the allocator 4467 // and related passes (coalescing, copy propagation, et. al.) to 4468 // be more effective. 4469 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 4470 Sched<[WriteFCopy]> { 4471 bits<5> Rd; 4472 bits<5> Rn; 4473 let Inst{30-24} = 0b0011110; 4474 let Inst{21} = 1; 4475 let Inst{20-19} = rmode; 4476 let Inst{18-16} = opcode; 4477 let Inst{15-10} = 0b000000; 4478 let Inst{9-5} = Rn; 4479 let Inst{4-0} = Rd; 4480} 4481 4482let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4483class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 4484 RegisterClass srcType, RegisterOperand dstType, string asm, 4485 string kind> 4486 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4487 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 4488 Sched<[WriteFCopy]> { 4489 bits<5> Rd; 4490 bits<5> Rn; 4491 let Inst{30-23} = 0b00111101; 4492 let Inst{21} = 1; 4493 let Inst{20-19} = rmode; 4494 let Inst{18-16} = opcode; 4495 let Inst{15-10} = 0b000000; 4496 let Inst{9-5} = Rn; 4497 let Inst{4-0} = Rd; 4498 4499 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4500} 4501 4502let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4503class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 4504 RegisterOperand srcType, RegisterClass dstType, string asm, 4505 string kind> 4506 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 4507 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 4508 Sched<[WriteFCopy]> { 4509 bits<5> Rd; 4510 bits<5> Rn; 4511 let Inst{30-23} = 0b00111101; 4512 let Inst{21} = 1; 4513 let Inst{20-19} = rmode; 4514 let Inst{18-16} = opcode; 4515 let Inst{15-10} = 0b000000; 4516 let Inst{9-5} = Rn; 4517 let Inst{4-0} = Rd; 4518 4519 let DecoderMethod = "DecodeFMOVLaneInstruction"; 4520} 4521 4522 4523multiclass UnscaledConversion<string asm> { 4524 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 4525 let Inst{31} = 0; // 32-bit GPR flag 4526 let Inst{23-22} = 0b11; // 16-bit FPR flag 4527 let Predicates = [HasFullFP16]; 4528 } 4529 4530 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 4531 let Inst{31} = 1; // 64-bit GPR flag 4532 let Inst{23-22} = 0b11; // 16-bit FPR flag 4533 let Predicates = [HasFullFP16]; 4534 } 4535 4536 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 4537 let Inst{31} = 0; // 32-bit GPR flag 4538 let Inst{23-22} = 0b00; // 32-bit FPR flag 4539 } 4540 4541 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 4542 let Inst{31} = 1; // 64-bit GPR flag 4543 let Inst{23-22} = 0b01; // 64-bit FPR flag 4544 } 4545 4546 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 4547 let Inst{31} = 0; // 32-bit GPR flag 4548 let Inst{23-22} = 0b11; // 16-bit FPR flag 4549 let Predicates = [HasFullFP16]; 4550 } 4551 4552 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 4553 let Inst{31} = 1; // 64-bit GPR flag 4554 let Inst{23-22} = 0b11; // 16-bit FPR flag 4555 let Predicates = [HasFullFP16]; 4556 } 4557 4558 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 4559 let Inst{31} = 0; // 32-bit GPR flag 4560 let Inst{23-22} = 0b00; // 32-bit FPR flag 4561 } 4562 4563 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 4564 let Inst{31} = 1; // 64-bit GPR flag 4565 let Inst{23-22} = 0b01; // 64-bit FPR flag 4566 } 4567 4568 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 4569 asm, ".d"> { 4570 let Inst{31} = 1; 4571 let Inst{22} = 0; 4572 } 4573 4574 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 4575 asm, ".d"> { 4576 let Inst{31} = 1; 4577 let Inst{22} = 0; 4578 } 4579} 4580 4581//--- 4582// Floating point conversion 4583//--- 4584 4585class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 4586 RegisterClass srcType, string asm, list<dag> pattern> 4587 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 4588 Sched<[WriteFCvt]> { 4589 bits<5> Rd; 4590 bits<5> Rn; 4591 let Inst{31-24} = 0b00011110; 4592 let Inst{23-22} = type; 4593 let Inst{21-17} = 0b10001; 4594 let Inst{16-15} = opcode; 4595 let Inst{14-10} = 0b10000; 4596 let Inst{9-5} = Rn; 4597 let Inst{4-0} = Rd; 4598} 4599 4600multiclass FPConversion<string asm> { 4601 // Double-precision to Half-precision 4602 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 4603 [(set FPR16:$Rd, (fpround FPR64:$Rn))]>; 4604 4605 // Double-precision to Single-precision 4606 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 4607 [(set FPR32:$Rd, (fpround FPR64:$Rn))]>; 4608 4609 // Half-precision to Double-precision 4610 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 4611 [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>; 4612 4613 // Half-precision to Single-precision 4614 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 4615 [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>; 4616 4617 // Single-precision to Double-precision 4618 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 4619 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>; 4620 4621 // Single-precision to Half-precision 4622 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 4623 [(set FPR16:$Rd, (fpround FPR32:$Rn))]>; 4624} 4625 4626//--- 4627// Single operand floating point data processing 4628//--- 4629 4630let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4631class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype, 4632 ValueType vt, string asm, SDPatternOperator node> 4633 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 4634 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 4635 Sched<[WriteF]> { 4636 bits<5> Rd; 4637 bits<5> Rn; 4638 let Inst{31-24} = 0b00011110; 4639 let Inst{21} = 0b1; 4640 let Inst{20-15} = opcode; 4641 let Inst{14-10} = 0b10000; 4642 let Inst{9-5} = Rn; 4643 let Inst{4-0} = Rd; 4644} 4645 4646multiclass SingleOperandFPData<bits<4> opcode, string asm, 4647 SDPatternOperator node = null_frag> { 4648 4649 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> { 4650 let Inst{23-22} = 0b11; // 16-bit size flag 4651 let Predicates = [HasFullFP16]; 4652 } 4653 4654 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> { 4655 let Inst{23-22} = 0b00; // 32-bit size flag 4656 } 4657 4658 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> { 4659 let Inst{23-22} = 0b01; // 64-bit size flag 4660 } 4661} 4662 4663multiclass SingleOperandFPNo16<bits<6> opcode, string asm, 4664 SDPatternOperator node = null_frag>{ 4665 4666 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 4667 let Inst{23-22} = 0b00; // 32-bit registers 4668 } 4669 4670 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 4671 let Inst{23-22} = 0b01; // 64-bit registers 4672 } 4673} 4674 4675// FRInt[32|64][Z|N] instructions 4676multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> : 4677 SingleOperandFPNo16<{0b0100,opcode}, asm, node>; 4678 4679//--- 4680// Two operand floating point data processing 4681//--- 4682 4683let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4684class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4685 string asm, list<dag> pat> 4686 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4687 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4688 Sched<[WriteF]> { 4689 bits<5> Rd; 4690 bits<5> Rn; 4691 bits<5> Rm; 4692 let Inst{31-24} = 0b00011110; 4693 let Inst{21} = 1; 4694 let Inst{20-16} = Rm; 4695 let Inst{15-12} = opcode; 4696 let Inst{11-10} = 0b10; 4697 let Inst{9-5} = Rn; 4698 let Inst{4-0} = Rd; 4699} 4700 4701multiclass TwoOperandFPData<bits<4> opcode, string asm, 4702 SDPatternOperator node = null_frag> { 4703 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4704 [(set (f16 FPR16:$Rd), 4705 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4706 let Inst{23-22} = 0b11; // 16-bit size flag 4707 let Predicates = [HasFullFP16]; 4708 } 4709 4710 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4711 [(set (f32 FPR32:$Rd), 4712 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4713 let Inst{23-22} = 0b00; // 32-bit size flag 4714 } 4715 4716 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4717 [(set (f64 FPR64:$Rd), 4718 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4719 let Inst{23-22} = 0b01; // 64-bit size flag 4720 } 4721} 4722 4723multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4724 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4725 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> { 4726 let Inst{23-22} = 0b11; // 16-bit size flag 4727 let Predicates = [HasFullFP16]; 4728 } 4729 4730 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4731 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4732 let Inst{23-22} = 0b00; // 32-bit size flag 4733 } 4734 4735 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4736 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 4737 let Inst{23-22} = 0b01; // 64-bit size flag 4738 } 4739} 4740 4741 4742//--- 4743// Three operand floating point data processing 4744//--- 4745 4746class BaseThreeOperandFPData<bit isNegated, bit isSub, 4747 RegisterClass regtype, string asm, list<dag> pat> 4748 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 4749 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 4750 Sched<[WriteFMul]> { 4751 bits<5> Rd; 4752 bits<5> Rn; 4753 bits<5> Rm; 4754 bits<5> Ra; 4755 let Inst{31-24} = 0b00011111; 4756 let Inst{21} = isNegated; 4757 let Inst{20-16} = Rm; 4758 let Inst{15} = isSub; 4759 let Inst{14-10} = Ra; 4760 let Inst{9-5} = Rn; 4761 let Inst{4-0} = Rd; 4762} 4763 4764multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 4765 SDPatternOperator node> { 4766 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 4767 [(set FPR16:$Rd, 4768 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 4769 let Inst{23-22} = 0b11; // 16-bit size flag 4770 let Predicates = [HasFullFP16]; 4771 } 4772 4773 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 4774 [(set FPR32:$Rd, 4775 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 4776 let Inst{23-22} = 0b00; // 32-bit size flag 4777 } 4778 4779 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 4780 [(set FPR64:$Rd, 4781 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 4782 let Inst{23-22} = 0b01; // 64-bit size flag 4783 } 4784} 4785 4786//--- 4787// Floating point data comparisons 4788//--- 4789 4790let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4791class BaseOneOperandFPComparison<bit signalAllNans, 4792 RegisterClass regtype, string asm, 4793 list<dag> pat> 4794 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 4795 Sched<[WriteFCmp]> { 4796 bits<5> Rn; 4797 let Inst{31-24} = 0b00011110; 4798 let Inst{21} = 1; 4799 4800 let Inst{15-10} = 0b001000; 4801 let Inst{9-5} = Rn; 4802 let Inst{4} = signalAllNans; 4803 let Inst{3-0} = 0b1000; 4804 4805 // Rm should be 0b00000 canonically, but we need to accept any value. 4806 let PostEncoderMethod = "fixOneOperandFPComparison"; 4807} 4808 4809let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4810class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 4811 string asm, list<dag> pat> 4812 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 4813 Sched<[WriteFCmp]> { 4814 bits<5> Rm; 4815 bits<5> Rn; 4816 let Inst{31-24} = 0b00011110; 4817 let Inst{21} = 1; 4818 let Inst{20-16} = Rm; 4819 let Inst{15-10} = 0b001000; 4820 let Inst{9-5} = Rn; 4821 let Inst{4} = signalAllNans; 4822 let Inst{3-0} = 0b0000; 4823} 4824 4825multiclass FPComparison<bit signalAllNans, string asm, 4826 SDPatternOperator OpNode = null_frag> { 4827 let Defs = [NZCV] in { 4828 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 4829 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> { 4830 let Inst{23-22} = 0b11; 4831 let Predicates = [HasFullFP16]; 4832 } 4833 4834 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 4835 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 4836 let Inst{23-22} = 0b11; 4837 let Predicates = [HasFullFP16]; 4838 } 4839 4840 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 4841 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 4842 let Inst{23-22} = 0b00; 4843 } 4844 4845 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 4846 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 4847 let Inst{23-22} = 0b00; 4848 } 4849 4850 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 4851 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 4852 let Inst{23-22} = 0b01; 4853 } 4854 4855 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 4856 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 4857 let Inst{23-22} = 0b01; 4858 } 4859 } // Defs = [NZCV] 4860} 4861 4862//--- 4863// Floating point conditional comparisons 4864//--- 4865 4866let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4867class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 4868 string mnemonic, list<dag> pat> 4869 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 4870 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 4871 Sched<[WriteFCmp]> { 4872 let Uses = [NZCV]; 4873 let Defs = [NZCV]; 4874 4875 bits<5> Rn; 4876 bits<5> Rm; 4877 bits<4> nzcv; 4878 bits<4> cond; 4879 4880 let Inst{31-24} = 0b00011110; 4881 let Inst{21} = 1; 4882 let Inst{20-16} = Rm; 4883 let Inst{15-12} = cond; 4884 let Inst{11-10} = 0b01; 4885 let Inst{9-5} = Rn; 4886 let Inst{4} = signalAllNans; 4887 let Inst{3-0} = nzcv; 4888} 4889 4890multiclass FPCondComparison<bit signalAllNans, string mnemonic, 4891 SDPatternOperator OpNode = null_frag> { 4892 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, 4893 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv), 4894 (i32 imm:$cond), NZCV))]> { 4895 let Inst{23-22} = 0b11; 4896 let Predicates = [HasFullFP16]; 4897 } 4898 4899 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 4900 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 4901 (i32 imm:$cond), NZCV))]> { 4902 let Inst{23-22} = 0b00; 4903 } 4904 4905 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 4906 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 4907 (i32 imm:$cond), NZCV))]> { 4908 let Inst{23-22} = 0b01; 4909 } 4910} 4911 4912//--- 4913// Floating point conditional select 4914//--- 4915 4916class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 4917 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 4918 asm, "\t$Rd, $Rn, $Rm, $cond", "", 4919 [(set regtype:$Rd, 4920 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 4921 (i32 imm:$cond), NZCV))]>, 4922 Sched<[WriteF]> { 4923 bits<5> Rd; 4924 bits<5> Rn; 4925 bits<5> Rm; 4926 bits<4> cond; 4927 4928 let Inst{31-24} = 0b00011110; 4929 let Inst{21} = 1; 4930 let Inst{20-16} = Rm; 4931 let Inst{15-12} = cond; 4932 let Inst{11-10} = 0b11; 4933 let Inst{9-5} = Rn; 4934 let Inst{4-0} = Rd; 4935} 4936 4937multiclass FPCondSelect<string asm> { 4938 let Uses = [NZCV] in { 4939 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 4940 let Inst{23-22} = 0b11; 4941 let Predicates = [HasFullFP16]; 4942 } 4943 4944 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 4945 let Inst{23-22} = 0b00; 4946 } 4947 4948 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 4949 let Inst{23-22} = 0b01; 4950 } 4951 } // Uses = [NZCV] 4952} 4953 4954//--- 4955// Floating move immediate 4956//--- 4957 4958class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 4959 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 4960 [(set regtype:$Rd, fpimmtype:$imm)]>, 4961 Sched<[WriteFImm]> { 4962 bits<5> Rd; 4963 bits<8> imm; 4964 let Inst{31-24} = 0b00011110; 4965 let Inst{21} = 1; 4966 let Inst{20-13} = imm; 4967 let Inst{12-5} = 0b10000000; 4968 let Inst{4-0} = Rd; 4969} 4970 4971multiclass FPMoveImmediate<string asm> { 4972 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 4973 let Inst{23-22} = 0b11; 4974 let Predicates = [HasFullFP16]; 4975 } 4976 4977 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 4978 let Inst{23-22} = 0b00; 4979 } 4980 4981 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 4982 let Inst{23-22} = 0b01; 4983 } 4984} 4985} // end of 'let Predicates = [HasFPARMv8]' 4986 4987//---------------------------------------------------------------------------- 4988// AdvSIMD 4989//---------------------------------------------------------------------------- 4990 4991let Predicates = [HasNEON] in { 4992 4993//---------------------------------------------------------------------------- 4994// AdvSIMD three register vector instructions 4995//---------------------------------------------------------------------------- 4996 4997let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4998class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 4999 RegisterOperand regtype, string asm, string kind, 5000 list<dag> pattern> 5001 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5002 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5003 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 5004 Sched<[WriteV]> { 5005 bits<5> Rd; 5006 bits<5> Rn; 5007 bits<5> Rm; 5008 let Inst{31} = 0; 5009 let Inst{30} = Q; 5010 let Inst{29} = U; 5011 let Inst{28-24} = 0b01110; 5012 let Inst{23-21} = size; 5013 let Inst{20-16} = Rm; 5014 let Inst{15-11} = opcode; 5015 let Inst{10} = 1; 5016 let Inst{9-5} = Rn; 5017 let Inst{4-0} = Rd; 5018} 5019 5020let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5021class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 5022 RegisterOperand regtype, string asm, string kind, 5023 list<dag> pattern> 5024 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 5025 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5026 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5027 Sched<[WriteV]> { 5028 bits<5> Rd; 5029 bits<5> Rn; 5030 bits<5> Rm; 5031 let Inst{31} = 0; 5032 let Inst{30} = Q; 5033 let Inst{29} = U; 5034 let Inst{28-24} = 0b01110; 5035 let Inst{23-21} = size; 5036 let Inst{20-16} = Rm; 5037 let Inst{15-11} = opcode; 5038 let Inst{10} = 1; 5039 let Inst{9-5} = Rn; 5040 let Inst{4-0} = Rd; 5041} 5042 5043// All operand sizes distinguished in the encoding. 5044multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 5045 SDPatternOperator OpNode> { 5046 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5047 asm, ".8b", 5048 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5049 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5050 asm, ".16b", 5051 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5052 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5053 asm, ".4h", 5054 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5055 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5056 asm, ".8h", 5057 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5058 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5059 asm, ".2s", 5060 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5061 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5062 asm, ".4s", 5063 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5064 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 5065 asm, ".2d", 5066 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5067} 5068 5069// As above, but D sized elements unsupported. 5070multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 5071 SDPatternOperator OpNode> { 5072 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5073 asm, ".8b", 5074 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 5075 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5076 asm, ".16b", 5077 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 5078 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5079 asm, ".4h", 5080 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 5081 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5082 asm, ".8h", 5083 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 5084 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5085 asm, ".2s", 5086 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 5087 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5088 asm, ".4s", 5089 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 5090} 5091 5092multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 5093 SDPatternOperator OpNode> { 5094 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 5095 asm, ".8b", 5096 [(set (v8i8 V64:$dst), 5097 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5098 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 5099 asm, ".16b", 5100 [(set (v16i8 V128:$dst), 5101 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5102 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 5103 asm, ".4h", 5104 [(set (v4i16 V64:$dst), 5105 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5106 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 5107 asm, ".8h", 5108 [(set (v8i16 V128:$dst), 5109 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5110 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 5111 asm, ".2s", 5112 [(set (v2i32 V64:$dst), 5113 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5114 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 5115 asm, ".4s", 5116 [(set (v4i32 V128:$dst), 5117 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5118} 5119 5120// As above, but only B sized elements supported. 5121multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 5122 SDPatternOperator OpNode> { 5123 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 5124 asm, ".8b", 5125 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5126 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 5127 asm, ".16b", 5128 [(set (v16i8 V128:$Rd), 5129 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 5130} 5131 5132// As above, but only floating point elements supported. 5133multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 5134 string asm, SDPatternOperator OpNode> { 5135 let Predicates = [HasNEON, HasFullFP16] in { 5136 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5137 asm, ".4h", 5138 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5139 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5140 asm, ".8h", 5141 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5142 } // Predicates = [HasNEON, HasFullFP16] 5143 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5144 asm, ".2s", 5145 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5146 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5147 asm, ".4s", 5148 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5149 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5150 asm, ".2d", 5151 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5152} 5153 5154multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 5155 string asm, 5156 SDPatternOperator OpNode> { 5157 let Predicates = [HasNEON, HasFullFP16] in { 5158 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 5159 asm, ".4h", 5160 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5161 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 5162 asm, ".8h", 5163 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5164 } // Predicates = [HasNEON, HasFullFP16] 5165 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 5166 asm, ".2s", 5167 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5168 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 5169 asm, ".4s", 5170 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5171 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 5172 asm, ".2d", 5173 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5174} 5175 5176multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 5177 string asm, SDPatternOperator OpNode> { 5178 let Predicates = [HasNEON, HasFullFP16] in { 5179 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 5180 asm, ".4h", 5181 [(set (v4f16 V64:$dst), 5182 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 5183 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 5184 asm, ".8h", 5185 [(set (v8f16 V128:$dst), 5186 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 5187 } // Predicates = [HasNEON, HasFullFP16] 5188 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 5189 asm, ".2s", 5190 [(set (v2f32 V64:$dst), 5191 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 5192 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 5193 asm, ".4s", 5194 [(set (v4f32 V128:$dst), 5195 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 5196 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 5197 asm, ".2d", 5198 [(set (v2f64 V128:$dst), 5199 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 5200} 5201 5202// As above, but D and B sized elements unsupported. 5203multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 5204 SDPatternOperator OpNode> { 5205 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 5206 asm, ".4h", 5207 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5208 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 5209 asm, ".8h", 5210 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5211 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 5212 asm, ".2s", 5213 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5214 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 5215 asm, ".4s", 5216 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5217} 5218 5219// Logical three vector ops share opcode bits, and only use B sized elements. 5220multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 5221 SDPatternOperator OpNode = null_frag> { 5222 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 5223 asm, ".8b", 5224 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 5225 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 5226 asm, ".16b", 5227 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 5228 5229 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 5230 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5231 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 5232 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5233 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 5234 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 5235 5236 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 5237 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5238 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 5239 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5240 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 5241 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 5242} 5243 5244multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 5245 string asm, SDPatternOperator OpNode> { 5246 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 5247 asm, ".8b", 5248 [(set (v8i8 V64:$dst), 5249 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5250 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 5251 asm, ".16b", 5252 [(set (v16i8 V128:$dst), 5253 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 5254 (v16i8 V128:$Rm)))]>; 5255 5256 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 5257 (v4i16 V64:$RHS))), 5258 (!cast<Instruction>(NAME#"v8i8") 5259 V64:$LHS, V64:$MHS, V64:$RHS)>; 5260 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 5261 (v2i32 V64:$RHS))), 5262 (!cast<Instruction>(NAME#"v8i8") 5263 V64:$LHS, V64:$MHS, V64:$RHS)>; 5264 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 5265 (v1i64 V64:$RHS))), 5266 (!cast<Instruction>(NAME#"v8i8") 5267 V64:$LHS, V64:$MHS, V64:$RHS)>; 5268 5269 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 5270 (v8i16 V128:$RHS))), 5271 (!cast<Instruction>(NAME#"v16i8") 5272 V128:$LHS, V128:$MHS, V128:$RHS)>; 5273 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 5274 (v4i32 V128:$RHS))), 5275 (!cast<Instruction>(NAME#"v16i8") 5276 V128:$LHS, V128:$MHS, V128:$RHS)>; 5277 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 5278 (v2i64 V128:$RHS))), 5279 (!cast<Instruction>(NAME#"v16i8") 5280 V128:$LHS, V128:$MHS, V128:$RHS)>; 5281} 5282 5283// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract 5284// bytes from S-sized elements. 5285class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1, 5286 string kind2, RegisterOperand RegType, 5287 ValueType AccumType, ValueType InputType, 5288 SDPatternOperator OpNode> : 5289 BaseSIMDThreeSameVectorTied<Q, U, 0b100, 0b10010, RegType, asm, kind1, 5290 [(set (AccumType RegType:$dst), 5291 (OpNode (AccumType RegType:$Rd), 5292 (InputType RegType:$Rn), 5293 (InputType RegType:$Rm)))]> { 5294 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5295} 5296 5297multiclass SIMDThreeSameVectorDot<bit U, string asm, SDPatternOperator OpNode> { 5298 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, asm, ".2s", ".8b", V64, 5299 v2i32, v8i8, OpNode>; 5300 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, asm, ".4s", ".16b", V128, 5301 v4i32, v16i8, OpNode>; 5302} 5303 5304// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions 5305// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from 5306// 8H to 4S, when Q=1). 5307class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1, 5308 string kind2, RegisterOperand RegType, 5309 ValueType AccumType, ValueType InputType, 5310 SDPatternOperator OpNode> : 5311 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1, 5312 [(set (AccumType RegType:$dst), 5313 (OpNode (AccumType RegType:$Rd), 5314 (InputType RegType:$Rn), 5315 (InputType RegType:$Rm)))]> { 5316 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}"); 5317 let Inst{13} = b13; 5318} 5319 5320multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm, 5321 SDPatternOperator OpNode> { 5322 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64, 5323 v2f32, v4f16, OpNode>; 5324 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128, 5325 v4f32, v8f16, OpNode>; 5326} 5327 5328 5329//---------------------------------------------------------------------------- 5330// AdvSIMD two register vector instructions. 5331//---------------------------------------------------------------------------- 5332 5333let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5334class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5335 bits<2> size2, RegisterOperand regtype, string asm, 5336 string dstkind, string srckind, list<dag> pattern> 5337 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5338 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5339 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 5340 Sched<[WriteV]> { 5341 bits<5> Rd; 5342 bits<5> Rn; 5343 let Inst{31} = 0; 5344 let Inst{30} = Q; 5345 let Inst{29} = U; 5346 let Inst{28-24} = 0b01110; 5347 let Inst{23-22} = size; 5348 let Inst{21} = 0b1; 5349 let Inst{20-19} = size2; 5350 let Inst{18-17} = 0b00; 5351 let Inst{16-12} = opcode; 5352 let Inst{11-10} = 0b10; 5353 let Inst{9-5} = Rn; 5354 let Inst{4-0} = Rd; 5355} 5356 5357let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5358class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5359 bits<2> size2, RegisterOperand regtype, 5360 string asm, string dstkind, string srckind, 5361 list<dag> pattern> 5362 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 5363 "{\t$Rd" # dstkind # ", $Rn" # srckind # 5364 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5365 Sched<[WriteV]> { 5366 bits<5> Rd; 5367 bits<5> Rn; 5368 let Inst{31} = 0; 5369 let Inst{30} = Q; 5370 let Inst{29} = U; 5371 let Inst{28-24} = 0b01110; 5372 let Inst{23-22} = size; 5373 let Inst{21} = 0b1; 5374 let Inst{20-19} = size2; 5375 let Inst{18-17} = 0b00; 5376 let Inst{16-12} = opcode; 5377 let Inst{11-10} = 0b10; 5378 let Inst{9-5} = Rn; 5379 let Inst{4-0} = Rd; 5380} 5381 5382// Supports B, H, and S element sizes. 5383multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 5384 SDPatternOperator OpNode> { 5385 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5386 asm, ".8b", ".8b", 5387 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5388 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5389 asm, ".16b", ".16b", 5390 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5391 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5392 asm, ".4h", ".4h", 5393 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5394 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5395 asm, ".8h", ".8h", 5396 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5397 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5398 asm, ".2s", ".2s", 5399 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5400 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5401 asm, ".4s", ".4s", 5402 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5403} 5404 5405class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 5406 RegisterOperand regtype, string asm, string dstkind, 5407 string srckind, string amount> 5408 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 5409 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 5410 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 5411 Sched<[WriteV]> { 5412 bits<5> Rd; 5413 bits<5> Rn; 5414 let Inst{31} = 0; 5415 let Inst{30} = Q; 5416 let Inst{29-24} = 0b101110; 5417 let Inst{23-22} = size; 5418 let Inst{21-10} = 0b100001001110; 5419 let Inst{9-5} = Rn; 5420 let Inst{4-0} = Rd; 5421} 5422 5423multiclass SIMDVectorLShiftLongBySizeBHS { 5424 let hasSideEffects = 0 in { 5425 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 5426 "shll", ".8h", ".8b", "8">; 5427 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 5428 "shll2", ".8h", ".16b", "8">; 5429 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 5430 "shll", ".4s", ".4h", "16">; 5431 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 5432 "shll2", ".4s", ".8h", "16">; 5433 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 5434 "shll", ".2d", ".2s", "32">; 5435 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 5436 "shll2", ".2d", ".4s", "32">; 5437 } 5438} 5439 5440// Supports all element sizes. 5441multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 5442 SDPatternOperator OpNode> { 5443 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5444 asm, ".4h", ".8b", 5445 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5446 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5447 asm, ".8h", ".16b", 5448 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5449 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5450 asm, ".2s", ".4h", 5451 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5452 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5453 asm, ".4s", ".8h", 5454 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5455 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5456 asm, ".1d", ".2s", 5457 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5458 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5459 asm, ".2d", ".4s", 5460 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5461} 5462 5463multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 5464 SDPatternOperator OpNode> { 5465 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5466 asm, ".4h", ".8b", 5467 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 5468 (v8i8 V64:$Rn)))]>; 5469 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5470 asm, ".8h", ".16b", 5471 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 5472 (v16i8 V128:$Rn)))]>; 5473 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5474 asm, ".2s", ".4h", 5475 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 5476 (v4i16 V64:$Rn)))]>; 5477 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5478 asm, ".4s", ".8h", 5479 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 5480 (v8i16 V128:$Rn)))]>; 5481 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5482 asm, ".1d", ".2s", 5483 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 5484 (v2i32 V64:$Rn)))]>; 5485 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5486 asm, ".2d", ".4s", 5487 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 5488 (v4i32 V128:$Rn)))]>; 5489} 5490 5491// Supports all element sizes, except 1xD. 5492multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 5493 SDPatternOperator OpNode> { 5494 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 5495 asm, ".8b", ".8b", 5496 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 5497 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 5498 asm, ".16b", ".16b", 5499 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 5500 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 5501 asm, ".4h", ".4h", 5502 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 5503 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 5504 asm, ".8h", ".8h", 5505 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 5506 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 5507 asm, ".2s", ".2s", 5508 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 5509 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 5510 asm, ".4s", ".4s", 5511 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 5512 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 5513 asm, ".2d", ".2d", 5514 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 5515} 5516 5517multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 5518 SDPatternOperator OpNode = null_frag> { 5519 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5520 asm, ".8b", ".8b", 5521 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5522 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5523 asm, ".16b", ".16b", 5524 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5525 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5526 asm, ".4h", ".4h", 5527 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5528 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5529 asm, ".8h", ".8h", 5530 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5531 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 5532 asm, ".2s", ".2s", 5533 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5534 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 5535 asm, ".4s", ".4s", 5536 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5537 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 5538 asm, ".2d", ".2d", 5539 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5540} 5541 5542 5543// Supports only B element sizes. 5544multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 5545 SDPatternOperator OpNode> { 5546 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 5547 asm, ".8b", ".8b", 5548 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 5549 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 5550 asm, ".16b", ".16b", 5551 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 5552 5553} 5554 5555// Supports only B and H element sizes. 5556multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 5557 SDPatternOperator OpNode> { 5558 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 5559 asm, ".8b", ".8b", 5560 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 5561 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 5562 asm, ".16b", ".16b", 5563 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 5564 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 5565 asm, ".4h", ".4h", 5566 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 5567 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 5568 asm, ".8h", ".8h", 5569 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 5570} 5571 5572// Supports H, S and D element sizes, uses high bit of the size field 5573// as an extra opcode bit. 5574multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 5575 SDPatternOperator OpNode> { 5576 let Predicates = [HasNEON, HasFullFP16] in { 5577 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5578 asm, ".4h", ".4h", 5579 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5580 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5581 asm, ".8h", ".8h", 5582 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5583 } // Predicates = [HasNEON, HasFullFP16] 5584 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5585 asm, ".2s", ".2s", 5586 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5587 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5588 asm, ".4s", ".4s", 5589 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5590 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5591 asm, ".2d", ".2d", 5592 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5593} 5594 5595// Supports only S and D element sizes 5596multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm, 5597 SDPatternOperator OpNode = null_frag> { 5598 5599 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64, 5600 asm, ".2s", ".2s", 5601 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5602 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128, 5603 asm, ".4s", ".4s", 5604 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5605 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128, 5606 asm, ".2d", ".2d", 5607 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5608} 5609 5610multiclass FRIntNNTVector<bit U, bit op, string asm, 5611 SDPatternOperator OpNode = null_frag> : 5612 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>; 5613 5614// Supports only S element size. 5615multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 5616 SDPatternOperator OpNode> { 5617 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5618 asm, ".2s", ".2s", 5619 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5620 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5621 asm, ".4s", ".4s", 5622 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5623} 5624 5625 5626multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 5627 SDPatternOperator OpNode> { 5628 let Predicates = [HasNEON, HasFullFP16] in { 5629 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5630 asm, ".4h", ".4h", 5631 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 5632 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5633 asm, ".8h", ".8h", 5634 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 5635 } // Predicates = [HasNEON, HasFullFP16] 5636 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5637 asm, ".2s", ".2s", 5638 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 5639 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5640 asm, ".4s", ".4s", 5641 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 5642 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5643 asm, ".2d", ".2d", 5644 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5645} 5646 5647multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 5648 SDPatternOperator OpNode> { 5649 let Predicates = [HasNEON, HasFullFP16] in { 5650 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 5651 asm, ".4h", ".4h", 5652 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 5653 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 5654 asm, ".8h", ".8h", 5655 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5656 } // Predicates = [HasNEON, HasFullFP16] 5657 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 5658 asm, ".2s", ".2s", 5659 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 5660 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 5661 asm, ".4s", ".4s", 5662 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5663 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 5664 asm, ".2d", ".2d", 5665 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5666} 5667 5668 5669class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5670 RegisterOperand inreg, RegisterOperand outreg, 5671 string asm, string outkind, string inkind, 5672 list<dag> pattern> 5673 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 5674 "{\t$Rd" # outkind # ", $Rn" # inkind # 5675 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 5676 Sched<[WriteV]> { 5677 bits<5> Rd; 5678 bits<5> Rn; 5679 let Inst{31} = 0; 5680 let Inst{30} = Q; 5681 let Inst{29} = U; 5682 let Inst{28-24} = 0b01110; 5683 let Inst{23-22} = size; 5684 let Inst{21-17} = 0b10000; 5685 let Inst{16-12} = opcode; 5686 let Inst{11-10} = 0b10; 5687 let Inst{9-5} = Rn; 5688 let Inst{4-0} = Rd; 5689} 5690 5691class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5692 RegisterOperand inreg, RegisterOperand outreg, 5693 string asm, string outkind, string inkind, 5694 list<dag> pattern> 5695 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 5696 "{\t$Rd" # outkind # ", $Rn" # inkind # 5697 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 5698 Sched<[WriteV]> { 5699 bits<5> Rd; 5700 bits<5> Rn; 5701 let Inst{31} = 0; 5702 let Inst{30} = Q; 5703 let Inst{29} = U; 5704 let Inst{28-24} = 0b01110; 5705 let Inst{23-22} = size; 5706 let Inst{21-17} = 0b10000; 5707 let Inst{16-12} = opcode; 5708 let Inst{11-10} = 0b10; 5709 let Inst{9-5} = Rn; 5710 let Inst{4-0} = Rd; 5711} 5712 5713multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 5714 SDPatternOperator OpNode> { 5715 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 5716 asm, ".8b", ".8h", 5717 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 5718 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 5719 asm#"2", ".16b", ".8h", []>; 5720 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 5721 asm, ".4h", ".4s", 5722 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 5723 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 5724 asm#"2", ".8h", ".4s", []>; 5725 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 5726 asm, ".2s", ".2d", 5727 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 5728 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 5729 asm#"2", ".4s", ".2d", []>; 5730 5731 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 5732 (!cast<Instruction>(NAME # "v16i8") 5733 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5734 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 5735 (!cast<Instruction>(NAME # "v8i16") 5736 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5737 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 5738 (!cast<Instruction>(NAME # "v4i32") 5739 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5740} 5741 5742class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 5743 bits<5> opcode, RegisterOperand regtype, string asm, 5744 string kind, string zero, ValueType dty, 5745 ValueType sty, SDNode OpNode> 5746 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5747 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 5748 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 5749 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 5750 Sched<[WriteV]> { 5751 bits<5> Rd; 5752 bits<5> Rn; 5753 let Inst{31} = 0; 5754 let Inst{30} = Q; 5755 let Inst{29} = U; 5756 let Inst{28-24} = 0b01110; 5757 let Inst{23-22} = size; 5758 let Inst{21} = 0b1; 5759 let Inst{20-19} = size2; 5760 let Inst{18-17} = 0b00; 5761 let Inst{16-12} = opcode; 5762 let Inst{11-10} = 0b10; 5763 let Inst{9-5} = Rn; 5764 let Inst{4-0} = Rd; 5765} 5766 5767// Comparisons support all element sizes, except 1xD. 5768multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 5769 SDNode OpNode> { 5770 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 5771 asm, ".8b", "0", 5772 v8i8, v8i8, OpNode>; 5773 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 5774 asm, ".16b", "0", 5775 v16i8, v16i8, OpNode>; 5776 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 5777 asm, ".4h", "0", 5778 v4i16, v4i16, OpNode>; 5779 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 5780 asm, ".8h", "0", 5781 v8i16, v8i16, OpNode>; 5782 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 5783 asm, ".2s", "0", 5784 v2i32, v2i32, OpNode>; 5785 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 5786 asm, ".4s", "0", 5787 v4i32, v4i32, OpNode>; 5788 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 5789 asm, ".2d", "0", 5790 v2i64, v2i64, OpNode>; 5791} 5792 5793// FP Comparisons support only S and D element sizes (and H for v8.2a). 5794multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 5795 string asm, SDNode OpNode> { 5796 5797 let Predicates = [HasNEON, HasFullFP16] in { 5798 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 5799 asm, ".4h", "0.0", 5800 v4i16, v4f16, OpNode>; 5801 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 5802 asm, ".8h", "0.0", 5803 v8i16, v8f16, OpNode>; 5804 } // Predicates = [HasNEON, HasFullFP16] 5805 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 5806 asm, ".2s", "0.0", 5807 v2i32, v2f32, OpNode>; 5808 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 5809 asm, ".4s", "0.0", 5810 v4i32, v4f32, OpNode>; 5811 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 5812 asm, ".2d", "0.0", 5813 v2i64, v2f64, OpNode>; 5814 5815 let Predicates = [HasNEON, HasFullFP16] in { 5816 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 5817 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5818 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 5819 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5820 } 5821 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 5822 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5823 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 5824 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5825 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 5826 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5827 let Predicates = [HasNEON, HasFullFP16] in { 5828 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 5829 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5830 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 5831 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5832 } 5833 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 5834 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5835 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 5836 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5837 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 5838 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5839} 5840 5841let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5842class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5843 RegisterOperand outtype, RegisterOperand intype, 5844 string asm, string VdTy, string VnTy, 5845 list<dag> pattern> 5846 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 5847 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 5848 Sched<[WriteV]> { 5849 bits<5> Rd; 5850 bits<5> Rn; 5851 let Inst{31} = 0; 5852 let Inst{30} = Q; 5853 let Inst{29} = U; 5854 let Inst{28-24} = 0b01110; 5855 let Inst{23-22} = size; 5856 let Inst{21-17} = 0b10000; 5857 let Inst{16-12} = opcode; 5858 let Inst{11-10} = 0b10; 5859 let Inst{9-5} = Rn; 5860 let Inst{4-0} = Rd; 5861} 5862 5863class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5864 RegisterOperand outtype, RegisterOperand intype, 5865 string asm, string VdTy, string VnTy, 5866 list<dag> pattern> 5867 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 5868 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 5869 Sched<[WriteV]> { 5870 bits<5> Rd; 5871 bits<5> Rn; 5872 let Inst{31} = 0; 5873 let Inst{30} = Q; 5874 let Inst{29} = U; 5875 let Inst{28-24} = 0b01110; 5876 let Inst{23-22} = size; 5877 let Inst{21-17} = 0b10000; 5878 let Inst{16-12} = opcode; 5879 let Inst{11-10} = 0b10; 5880 let Inst{9-5} = Rn; 5881 let Inst{4-0} = Rd; 5882} 5883 5884multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 5885 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 5886 asm, ".4s", ".4h", []>; 5887 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 5888 asm#"2", ".4s", ".8h", []>; 5889 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 5890 asm, ".2d", ".2s", []>; 5891 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 5892 asm#"2", ".2d", ".4s", []>; 5893} 5894 5895multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 5896 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 5897 asm, ".4h", ".4s", []>; 5898 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 5899 asm#"2", ".8h", ".4s", []>; 5900 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 5901 asm, ".2s", ".2d", []>; 5902 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 5903 asm#"2", ".4s", ".2d", []>; 5904} 5905 5906multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 5907 Intrinsic OpNode> { 5908 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 5909 asm, ".2s", ".2d", 5910 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5911 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 5912 asm#"2", ".4s", ".2d", []>; 5913 5914 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 5915 (!cast<Instruction>(NAME # "v4f32") 5916 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5917} 5918 5919//---------------------------------------------------------------------------- 5920// AdvSIMD three register different-size vector instructions. 5921//---------------------------------------------------------------------------- 5922 5923let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5924class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 5925 RegisterOperand outtype, RegisterOperand intype1, 5926 RegisterOperand intype2, string asm, 5927 string outkind, string inkind1, string inkind2, 5928 list<dag> pattern> 5929 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 5930 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 5931 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 5932 Sched<[WriteV]> { 5933 bits<5> Rd; 5934 bits<5> Rn; 5935 bits<5> Rm; 5936 let Inst{31} = 0; 5937 let Inst{30} = size{0}; 5938 let Inst{29} = U; 5939 let Inst{28-24} = 0b01110; 5940 let Inst{23-22} = size{2-1}; 5941 let Inst{21} = 1; 5942 let Inst{20-16} = Rm; 5943 let Inst{15-12} = opcode; 5944 let Inst{11-10} = 0b00; 5945 let Inst{9-5} = Rn; 5946 let Inst{4-0} = Rd; 5947} 5948 5949let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5950class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 5951 RegisterOperand outtype, RegisterOperand intype1, 5952 RegisterOperand intype2, string asm, 5953 string outkind, string inkind1, string inkind2, 5954 list<dag> pattern> 5955 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 5956 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 5957 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5958 Sched<[WriteV]> { 5959 bits<5> Rd; 5960 bits<5> Rn; 5961 bits<5> Rm; 5962 let Inst{31} = 0; 5963 let Inst{30} = size{0}; 5964 let Inst{29} = U; 5965 let Inst{28-24} = 0b01110; 5966 let Inst{23-22} = size{2-1}; 5967 let Inst{21} = 1; 5968 let Inst{20-16} = Rm; 5969 let Inst{15-12} = opcode; 5970 let Inst{11-10} = 0b00; 5971 let Inst{9-5} = Rn; 5972 let Inst{4-0} = Rd; 5973} 5974 5975// FIXME: TableGen doesn't know how to deal with expanded types that also 5976// change the element count (in this case, placing the results in 5977// the high elements of the result register rather than the low 5978// elements). Until that's fixed, we can't code-gen those. 5979multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 5980 Intrinsic IntOp> { 5981 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5982 V64, V128, V128, 5983 asm, ".8b", ".8h", ".8h", 5984 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5985 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5986 V128, V128, V128, 5987 asm#"2", ".16b", ".8h", ".8h", 5988 []>; 5989 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5990 V64, V128, V128, 5991 asm, ".4h", ".4s", ".4s", 5992 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5993 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5994 V128, V128, V128, 5995 asm#"2", ".8h", ".4s", ".4s", 5996 []>; 5997 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5998 V64, V128, V128, 5999 asm, ".2s", ".2d", ".2d", 6000 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 6001 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6002 V128, V128, V128, 6003 asm#"2", ".4s", ".2d", ".2d", 6004 []>; 6005 6006 6007 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 6008 // a version attached to an instruction. 6009 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 6010 (v8i16 V128:$Rm))), 6011 (!cast<Instruction>(NAME # "v8i16_v16i8") 6012 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6013 V128:$Rn, V128:$Rm)>; 6014 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 6015 (v4i32 V128:$Rm))), 6016 (!cast<Instruction>(NAME # "v4i32_v8i16") 6017 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6018 V128:$Rn, V128:$Rm)>; 6019 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 6020 (v2i64 V128:$Rm))), 6021 (!cast<Instruction>(NAME # "v2i64_v4i32") 6022 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 6023 V128:$Rn, V128:$Rm)>; 6024} 6025 6026multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 6027 Intrinsic IntOp> { 6028 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6029 V128, V64, V64, 6030 asm, ".8h", ".8b", ".8b", 6031 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6032 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6033 V128, V128, V128, 6034 asm#"2", ".8h", ".16b", ".16b", []>; 6035 let Predicates = [HasAES] in { 6036 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 6037 V128, V64, V64, 6038 asm, ".1q", ".1d", ".1d", []>; 6039 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 6040 V128, V128, V128, 6041 asm#"2", ".1q", ".2d", ".2d", []>; 6042 } 6043 6044 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 6045 (v8i8 (extract_high_v16i8 V128:$Rm)))), 6046 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 6047} 6048 6049multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 6050 SDPatternOperator OpNode> { 6051 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6052 V128, V64, V64, 6053 asm, ".4s", ".4h", ".4h", 6054 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6055 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6056 V128, V128, V128, 6057 asm#"2", ".4s", ".8h", ".8h", 6058 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6059 (extract_high_v8i16 V128:$Rm)))]>; 6060 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6061 V128, V64, V64, 6062 asm, ".2d", ".2s", ".2s", 6063 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6064 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6065 V128, V128, V128, 6066 asm#"2", ".2d", ".4s", ".4s", 6067 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6068 (extract_high_v4i32 V128:$Rm)))]>; 6069} 6070 6071multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 6072 SDPatternOperator OpNode = null_frag> { 6073 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6074 V128, V64, V64, 6075 asm, ".8h", ".8b", ".8b", 6076 [(set (v8i16 V128:$Rd), 6077 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 6078 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6079 V128, V128, V128, 6080 asm#"2", ".8h", ".16b", ".16b", 6081 [(set (v8i16 V128:$Rd), 6082 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6083 (extract_high_v16i8 V128:$Rm)))))]>; 6084 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6085 V128, V64, V64, 6086 asm, ".4s", ".4h", ".4h", 6087 [(set (v4i32 V128:$Rd), 6088 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 6089 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6090 V128, V128, V128, 6091 asm#"2", ".4s", ".8h", ".8h", 6092 [(set (v4i32 V128:$Rd), 6093 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6094 (extract_high_v8i16 V128:$Rm)))))]>; 6095 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6096 V128, V64, V64, 6097 asm, ".2d", ".2s", ".2s", 6098 [(set (v2i64 V128:$Rd), 6099 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 6100 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6101 V128, V128, V128, 6102 asm#"2", ".2d", ".4s", ".4s", 6103 [(set (v2i64 V128:$Rd), 6104 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6105 (extract_high_v4i32 V128:$Rm)))))]>; 6106} 6107 6108multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 6109 string asm, 6110 SDPatternOperator OpNode> { 6111 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6112 V128, V64, V64, 6113 asm, ".8h", ".8b", ".8b", 6114 [(set (v8i16 V128:$dst), 6115 (add (v8i16 V128:$Rd), 6116 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 6117 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6118 V128, V128, V128, 6119 asm#"2", ".8h", ".16b", ".16b", 6120 [(set (v8i16 V128:$dst), 6121 (add (v8i16 V128:$Rd), 6122 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 6123 (extract_high_v16i8 V128:$Rm))))))]>; 6124 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6125 V128, V64, V64, 6126 asm, ".4s", ".4h", ".4h", 6127 [(set (v4i32 V128:$dst), 6128 (add (v4i32 V128:$Rd), 6129 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 6130 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6131 V128, V128, V128, 6132 asm#"2", ".4s", ".8h", ".8h", 6133 [(set (v4i32 V128:$dst), 6134 (add (v4i32 V128:$Rd), 6135 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 6136 (extract_high_v8i16 V128:$Rm))))))]>; 6137 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6138 V128, V64, V64, 6139 asm, ".2d", ".2s", ".2s", 6140 [(set (v2i64 V128:$dst), 6141 (add (v2i64 V128:$Rd), 6142 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 6143 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6144 V128, V128, V128, 6145 asm#"2", ".2d", ".4s", ".4s", 6146 [(set (v2i64 V128:$dst), 6147 (add (v2i64 V128:$Rd), 6148 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 6149 (extract_high_v4i32 V128:$Rm))))))]>; 6150} 6151 6152multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 6153 SDPatternOperator OpNode = null_frag> { 6154 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6155 V128, V64, V64, 6156 asm, ".8h", ".8b", ".8b", 6157 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6158 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6159 V128, V128, V128, 6160 asm#"2", ".8h", ".16b", ".16b", 6161 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 6162 (extract_high_v16i8 V128:$Rm)))]>; 6163 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6164 V128, V64, V64, 6165 asm, ".4s", ".4h", ".4h", 6166 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6167 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6168 V128, V128, V128, 6169 asm#"2", ".4s", ".8h", ".8h", 6170 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 6171 (extract_high_v8i16 V128:$Rm)))]>; 6172 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6173 V128, V64, V64, 6174 asm, ".2d", ".2s", ".2s", 6175 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6176 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6177 V128, V128, V128, 6178 asm#"2", ".2d", ".4s", ".4s", 6179 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 6180 (extract_high_v4i32 V128:$Rm)))]>; 6181} 6182 6183multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 6184 string asm, 6185 SDPatternOperator OpNode> { 6186 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 6187 V128, V64, V64, 6188 asm, ".8h", ".8b", ".8b", 6189 [(set (v8i16 V128:$dst), 6190 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 6191 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 6192 V128, V128, V128, 6193 asm#"2", ".8h", ".16b", ".16b", 6194 [(set (v8i16 V128:$dst), 6195 (OpNode (v8i16 V128:$Rd), 6196 (extract_high_v16i8 V128:$Rn), 6197 (extract_high_v16i8 V128:$Rm)))]>; 6198 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6199 V128, V64, V64, 6200 asm, ".4s", ".4h", ".4h", 6201 [(set (v4i32 V128:$dst), 6202 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 6203 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6204 V128, V128, V128, 6205 asm#"2", ".4s", ".8h", ".8h", 6206 [(set (v4i32 V128:$dst), 6207 (OpNode (v4i32 V128:$Rd), 6208 (extract_high_v8i16 V128:$Rn), 6209 (extract_high_v8i16 V128:$Rm)))]>; 6210 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6211 V128, V64, V64, 6212 asm, ".2d", ".2s", ".2s", 6213 [(set (v2i64 V128:$dst), 6214 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 6215 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6216 V128, V128, V128, 6217 asm#"2", ".2d", ".4s", ".4s", 6218 [(set (v2i64 V128:$dst), 6219 (OpNode (v2i64 V128:$Rd), 6220 (extract_high_v4i32 V128:$Rn), 6221 (extract_high_v4i32 V128:$Rm)))]>; 6222} 6223 6224multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 6225 SDPatternOperator Accum> { 6226 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 6227 V128, V64, V64, 6228 asm, ".4s", ".4h", ".4h", 6229 [(set (v4i32 V128:$dst), 6230 (Accum (v4i32 V128:$Rd), 6231 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6232 (v4i16 V64:$Rm)))))]>; 6233 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 6234 V128, V128, V128, 6235 asm#"2", ".4s", ".8h", ".8h", 6236 [(set (v4i32 V128:$dst), 6237 (Accum (v4i32 V128:$Rd), 6238 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 6239 (extract_high_v8i16 V128:$Rm)))))]>; 6240 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 6241 V128, V64, V64, 6242 asm, ".2d", ".2s", ".2s", 6243 [(set (v2i64 V128:$dst), 6244 (Accum (v2i64 V128:$Rd), 6245 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 6246 (v2i32 V64:$Rm)))))]>; 6247 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 6248 V128, V128, V128, 6249 asm#"2", ".2d", ".4s", ".4s", 6250 [(set (v2i64 V128:$dst), 6251 (Accum (v2i64 V128:$Rd), 6252 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 6253 (extract_high_v4i32 V128:$Rm)))))]>; 6254} 6255 6256multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 6257 SDPatternOperator OpNode> { 6258 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 6259 V128, V128, V64, 6260 asm, ".8h", ".8h", ".8b", 6261 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 6262 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 6263 V128, V128, V128, 6264 asm#"2", ".8h", ".8h", ".16b", 6265 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 6266 (extract_high_v16i8 V128:$Rm)))]>; 6267 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 6268 V128, V128, V64, 6269 asm, ".4s", ".4s", ".4h", 6270 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 6271 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 6272 V128, V128, V128, 6273 asm#"2", ".4s", ".4s", ".8h", 6274 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 6275 (extract_high_v8i16 V128:$Rm)))]>; 6276 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 6277 V128, V128, V64, 6278 asm, ".2d", ".2d", ".2s", 6279 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 6280 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 6281 V128, V128, V128, 6282 asm#"2", ".2d", ".2d", ".4s", 6283 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 6284 (extract_high_v4i32 V128:$Rm)))]>; 6285} 6286 6287//---------------------------------------------------------------------------- 6288// AdvSIMD bitwise extract from vector 6289//---------------------------------------------------------------------------- 6290 6291class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 6292 string asm, string kind> 6293 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 6294 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 6295 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 6296 [(set (vty regtype:$Rd), 6297 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 6298 Sched<[WriteV]> { 6299 bits<5> Rd; 6300 bits<5> Rn; 6301 bits<5> Rm; 6302 bits<4> imm; 6303 let Inst{31} = 0; 6304 let Inst{30} = size; 6305 let Inst{29-21} = 0b101110000; 6306 let Inst{20-16} = Rm; 6307 let Inst{15} = 0; 6308 let Inst{14-11} = imm; 6309 let Inst{10} = 0; 6310 let Inst{9-5} = Rn; 6311 let Inst{4-0} = Rd; 6312} 6313 6314 6315multiclass SIMDBitwiseExtract<string asm> { 6316 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 6317 let imm{3} = 0; 6318 } 6319 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 6320} 6321 6322//---------------------------------------------------------------------------- 6323// AdvSIMD zip vector 6324//---------------------------------------------------------------------------- 6325 6326class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 6327 string asm, string kind, SDNode OpNode, ValueType valty> 6328 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6329 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 6330 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 6331 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 6332 Sched<[WriteV]> { 6333 bits<5> Rd; 6334 bits<5> Rn; 6335 bits<5> Rm; 6336 let Inst{31} = 0; 6337 let Inst{30} = size{0}; 6338 let Inst{29-24} = 0b001110; 6339 let Inst{23-22} = size{2-1}; 6340 let Inst{21} = 0; 6341 let Inst{20-16} = Rm; 6342 let Inst{15} = 0; 6343 let Inst{14-12} = opc; 6344 let Inst{11-10} = 0b10; 6345 let Inst{9-5} = Rn; 6346 let Inst{4-0} = Rd; 6347} 6348 6349multiclass SIMDZipVector<bits<3>opc, string asm, 6350 SDNode OpNode> { 6351 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 6352 asm, ".8b", OpNode, v8i8>; 6353 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 6354 asm, ".16b", OpNode, v16i8>; 6355 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 6356 asm, ".4h", OpNode, v4i16>; 6357 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 6358 asm, ".8h", OpNode, v8i16>; 6359 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 6360 asm, ".2s", OpNode, v2i32>; 6361 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 6362 asm, ".4s", OpNode, v4i32>; 6363 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 6364 asm, ".2d", OpNode, v2i64>; 6365 6366 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 6367 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 6368 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 6369 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 6370 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 6371 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 6372 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 6373 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 6374 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 6375 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 6376} 6377 6378//---------------------------------------------------------------------------- 6379// AdvSIMD three register scalar instructions 6380//---------------------------------------------------------------------------- 6381 6382let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6383class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 6384 RegisterClass regtype, string asm, 6385 list<dag> pattern> 6386 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 6387 "\t$Rd, $Rn, $Rm", "", pattern>, 6388 Sched<[WriteV]> { 6389 bits<5> Rd; 6390 bits<5> Rn; 6391 bits<5> Rm; 6392 let Inst{31-30} = 0b01; 6393 let Inst{29} = U; 6394 let Inst{28-24} = 0b11110; 6395 let Inst{23-21} = size; 6396 let Inst{20-16} = Rm; 6397 let Inst{15-11} = opcode; 6398 let Inst{10} = 1; 6399 let Inst{9-5} = Rn; 6400 let Inst{4-0} = Rd; 6401} 6402 6403let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6404class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 6405 dag oops, dag iops, string asm, 6406 list<dag> pattern> 6407 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 6408 Sched<[WriteV]> { 6409 bits<5> Rd; 6410 bits<5> Rn; 6411 bits<5> Rm; 6412 let Inst{31-30} = 0b01; 6413 let Inst{29} = U; 6414 let Inst{28-24} = 0b11110; 6415 let Inst{23-22} = size; 6416 let Inst{21} = R; 6417 let Inst{20-16} = Rm; 6418 let Inst{15-11} = opcode; 6419 let Inst{10} = 1; 6420 let Inst{9-5} = Rn; 6421 let Inst{4-0} = Rd; 6422} 6423 6424multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 6425 SDPatternOperator OpNode> { 6426 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6427 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6428} 6429 6430multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 6431 SDPatternOperator OpNode> { 6432 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 6433 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 6434 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 6435 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6436 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 6437 6438 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 6439 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 6440 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 6441 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 6442} 6443 6444multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 6445 SDPatternOperator OpNode> { 6446 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 6447 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6448 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 6449} 6450 6451multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 6452 SDPatternOperator OpNode = null_frag> { 6453 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 6454 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 6455 asm, []>; 6456 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 6457 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 6458 asm, []>; 6459} 6460 6461multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 6462 SDPatternOperator OpNode = null_frag> { 6463 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6464 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6465 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6466 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6467 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 6468 let Predicates = [HasNEON, HasFullFP16] in { 6469 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6470 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>; 6471 } // Predicates = [HasNEON, HasFullFP16] 6472 } 6473 6474 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6475 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6476} 6477 6478multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 6479 SDPatternOperator OpNode = null_frag> { 6480 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6481 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 6482 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 6483 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 6484 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 6485 let Predicates = [HasNEON, HasFullFP16] in { 6486 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 6487 []>; 6488 } // Predicates = [HasNEON, HasFullFP16] 6489 } 6490 6491 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 6492 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 6493} 6494 6495class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 6496 dag oops, dag iops, string asm, string cstr, list<dag> pat> 6497 : I<oops, iops, asm, 6498 "\t$Rd, $Rn, $Rm", cstr, pat>, 6499 Sched<[WriteV]> { 6500 bits<5> Rd; 6501 bits<5> Rn; 6502 bits<5> Rm; 6503 let Inst{31-30} = 0b01; 6504 let Inst{29} = U; 6505 let Inst{28-24} = 0b11110; 6506 let Inst{23-22} = size; 6507 let Inst{21} = 1; 6508 let Inst{20-16} = Rm; 6509 let Inst{15-11} = opcode; 6510 let Inst{10} = 0; 6511 let Inst{9-5} = Rn; 6512 let Inst{4-0} = Rd; 6513} 6514 6515let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6516multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 6517 SDPatternOperator OpNode = null_frag> { 6518 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6519 (outs FPR32:$Rd), 6520 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 6521 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6522 (outs FPR64:$Rd), 6523 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 6524 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6525} 6526 6527let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6528multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 6529 SDPatternOperator OpNode = null_frag> { 6530 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 6531 (outs FPR32:$dst), 6532 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 6533 asm, "$Rd = $dst", []>; 6534 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 6535 (outs FPR64:$dst), 6536 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 6537 asm, "$Rd = $dst", 6538 [(set (i64 FPR64:$dst), 6539 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 6540} 6541 6542//---------------------------------------------------------------------------- 6543// AdvSIMD two register scalar instructions 6544//---------------------------------------------------------------------------- 6545 6546let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6547class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6548 RegisterClass regtype, RegisterClass regtype2, 6549 string asm, list<dag> pat> 6550 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 6551 "\t$Rd, $Rn", "", pat>, 6552 Sched<[WriteV]> { 6553 bits<5> Rd; 6554 bits<5> Rn; 6555 let Inst{31-30} = 0b01; 6556 let Inst{29} = U; 6557 let Inst{28-24} = 0b11110; 6558 let Inst{23-22} = size; 6559 let Inst{21} = 0b1; 6560 let Inst{20-19} = size2; 6561 let Inst{18-17} = 0b00; 6562 let Inst{16-12} = opcode; 6563 let Inst{11-10} = 0b10; 6564 let Inst{9-5} = Rn; 6565 let Inst{4-0} = Rd; 6566} 6567 6568let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6569class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 6570 RegisterClass regtype, RegisterClass regtype2, 6571 string asm, list<dag> pat> 6572 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 6573 "\t$Rd, $Rn", "$Rd = $dst", pat>, 6574 Sched<[WriteV]> { 6575 bits<5> Rd; 6576 bits<5> Rn; 6577 let Inst{31-30} = 0b01; 6578 let Inst{29} = U; 6579 let Inst{28-24} = 0b11110; 6580 let Inst{23-22} = size; 6581 let Inst{21-17} = 0b10000; 6582 let Inst{16-12} = opcode; 6583 let Inst{11-10} = 0b10; 6584 let Inst{9-5} = Rn; 6585 let Inst{4-0} = Rd; 6586} 6587 6588 6589let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6590class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 6591 RegisterClass regtype, string asm, string zero> 6592 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 6593 "\t$Rd, $Rn, #" # zero, "", []>, 6594 Sched<[WriteV]> { 6595 bits<5> Rd; 6596 bits<5> Rn; 6597 let Inst{31-30} = 0b01; 6598 let Inst{29} = U; 6599 let Inst{28-24} = 0b11110; 6600 let Inst{23-22} = size; 6601 let Inst{21} = 0b1; 6602 let Inst{20-19} = size2; 6603 let Inst{18-17} = 0b00; 6604 let Inst{16-12} = opcode; 6605 let Inst{11-10} = 0b10; 6606 let Inst{9-5} = Rn; 6607 let Inst{4-0} = Rd; 6608} 6609 6610class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 6611 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 6612 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 6613 Sched<[WriteV]> { 6614 bits<5> Rd; 6615 bits<5> Rn; 6616 let Inst{31-17} = 0b011111100110000; 6617 let Inst{16-12} = opcode; 6618 let Inst{11-10} = 0b10; 6619 let Inst{9-5} = Rn; 6620 let Inst{4-0} = Rd; 6621} 6622 6623multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 6624 SDPatternOperator OpNode> { 6625 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 6626 6627 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 6628 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6629} 6630 6631multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 6632 SDPatternOperator OpNode> { 6633 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 6634 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 6635 let Predicates = [HasNEON, HasFullFP16] in { 6636 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 6637 } 6638 6639 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6640 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 6641 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6642 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 6643 let Predicates = [HasNEON, HasFullFP16] in { 6644 def : InstAlias<asm # "\t$Rd, $Rn, #0", 6645 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 6646 } 6647 6648 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 6649 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 6650} 6651 6652multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 6653 SDPatternOperator OpNode = null_frag> { 6654 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6655 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 6656 6657 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 6658 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 6659} 6660 6661multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 6662 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 6663 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 6664 let Predicates = [HasNEON, HasFullFP16] in { 6665 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 6666 } 6667} 6668 6669multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 6670 SDPatternOperator OpNode> { 6671 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 6672 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 6673 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 6674 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 6675 let Predicates = [HasNEON, HasFullFP16] in { 6676 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 6677 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>; 6678 } 6679} 6680 6681multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 6682 SDPatternOperator OpNode = null_frag> { 6683 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6684 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 6685 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6686 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 6687 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 6688 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 6689 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 6690 } 6691 6692 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 6693 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 6694} 6695 6696multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 6697 Intrinsic OpNode> { 6698 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6699 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 6700 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 6701 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 6702 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 6703 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 6704 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 6705 } 6706 6707 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 6708 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 6709} 6710 6711 6712 6713let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6714multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 6715 SDPatternOperator OpNode = null_frag> { 6716 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 6717 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 6718 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 6719 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 6720} 6721 6722//---------------------------------------------------------------------------- 6723// AdvSIMD scalar pairwise instructions 6724//---------------------------------------------------------------------------- 6725 6726let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6727class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 6728 RegisterOperand regtype, RegisterOperand vectype, 6729 string asm, string kind> 6730 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 6731 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 6732 Sched<[WriteV]> { 6733 bits<5> Rd; 6734 bits<5> Rn; 6735 let Inst{31-30} = 0b01; 6736 let Inst{29} = U; 6737 let Inst{28-24} = 0b11110; 6738 let Inst{23-22} = size; 6739 let Inst{21-17} = 0b11000; 6740 let Inst{16-12} = opcode; 6741 let Inst{11-10} = 0b10; 6742 let Inst{9-5} = Rn; 6743 let Inst{4-0} = Rd; 6744} 6745 6746multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 6747 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 6748 asm, ".2d">; 6749} 6750 6751multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 6752 let Predicates = [HasNEON, HasFullFP16] in { 6753 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 6754 asm, ".2h">; 6755 } 6756 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 6757 asm, ".2s">; 6758 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 6759 asm, ".2d">; 6760} 6761 6762//---------------------------------------------------------------------------- 6763// AdvSIMD across lanes instructions 6764//---------------------------------------------------------------------------- 6765 6766let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6767class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 6768 RegisterClass regtype, RegisterOperand vectype, 6769 string asm, string kind, list<dag> pattern> 6770 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 6771 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 6772 Sched<[WriteV]> { 6773 bits<5> Rd; 6774 bits<5> Rn; 6775 let Inst{31} = 0; 6776 let Inst{30} = Q; 6777 let Inst{29} = U; 6778 let Inst{28-24} = 0b01110; 6779 let Inst{23-22} = size; 6780 let Inst{21-17} = 0b11000; 6781 let Inst{16-12} = opcode; 6782 let Inst{11-10} = 0b10; 6783 let Inst{9-5} = Rn; 6784 let Inst{4-0} = Rd; 6785} 6786 6787multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 6788 string asm> { 6789 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 6790 asm, ".8b", []>; 6791 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 6792 asm, ".16b", []>; 6793 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 6794 asm, ".4h", []>; 6795 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 6796 asm, ".8h", []>; 6797 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 6798 asm, ".4s", []>; 6799} 6800 6801multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 6802 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 6803 asm, ".8b", []>; 6804 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 6805 asm, ".16b", []>; 6806 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 6807 asm, ".4h", []>; 6808 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 6809 asm, ".8h", []>; 6810 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 6811 asm, ".4s", []>; 6812} 6813 6814multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 6815 Intrinsic intOp> { 6816 let Predicates = [HasNEON, HasFullFP16] in { 6817 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 6818 asm, ".4h", 6819 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>; 6820 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 6821 asm, ".8h", 6822 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>; 6823 } // Predicates = [HasNEON, HasFullFP16] 6824 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 6825 asm, ".4s", 6826 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 6827} 6828 6829//---------------------------------------------------------------------------- 6830// AdvSIMD INS/DUP instructions 6831//---------------------------------------------------------------------------- 6832 6833// FIXME: There has got to be a better way to factor these. ugh. 6834 6835class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 6836 string operands, string constraints, list<dag> pattern> 6837 : I<outs, ins, asm, operands, constraints, pattern>, 6838 Sched<[WriteV]> { 6839 bits<5> Rd; 6840 bits<5> Rn; 6841 let Inst{31} = 0; 6842 let Inst{30} = Q; 6843 let Inst{29} = op; 6844 let Inst{28-21} = 0b01110000; 6845 let Inst{15} = 0; 6846 let Inst{10} = 1; 6847 let Inst{9-5} = Rn; 6848 let Inst{4-0} = Rd; 6849} 6850 6851class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 6852 RegisterOperand vecreg, RegisterClass regtype> 6853 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 6854 "{\t$Rd" # size # ", $Rn" # 6855 "|" # size # "\t$Rd, $Rn}", "", 6856 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 6857 let Inst{20-16} = imm5; 6858 let Inst{14-11} = 0b0001; 6859} 6860 6861class SIMDDupFromElement<bit Q, string dstkind, string srckind, 6862 ValueType vectype, ValueType insreg, 6863 RegisterOperand vecreg, Operand idxtype, 6864 ValueType elttype, SDNode OpNode> 6865 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 6866 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 6867 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 6868 [(set (vectype vecreg:$Rd), 6869 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 6870 let Inst{14-11} = 0b0000; 6871} 6872 6873class SIMDDup64FromElement 6874 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 6875 VectorIndexD, i64, AArch64duplane64> { 6876 bits<1> idx; 6877 let Inst{20} = idx; 6878 let Inst{19-16} = 0b1000; 6879} 6880 6881class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 6882 RegisterOperand vecreg> 6883 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 6884 VectorIndexS, i64, AArch64duplane32> { 6885 bits<2> idx; 6886 let Inst{20-19} = idx; 6887 let Inst{18-16} = 0b100; 6888} 6889 6890class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 6891 RegisterOperand vecreg> 6892 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 6893 VectorIndexH, i64, AArch64duplane16> { 6894 bits<3> idx; 6895 let Inst{20-18} = idx; 6896 let Inst{17-16} = 0b10; 6897} 6898 6899class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 6900 RegisterOperand vecreg> 6901 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 6902 VectorIndexB, i64, AArch64duplane8> { 6903 bits<4> idx; 6904 let Inst{20-17} = idx; 6905 let Inst{16} = 1; 6906} 6907 6908class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 6909 Operand idxtype, string asm, list<dag> pattern> 6910 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 6911 "{\t$Rd, $Rn" # size # "$idx" # 6912 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 6913 let Inst{14-11} = imm4; 6914} 6915 6916class SIMDSMov<bit Q, string size, RegisterClass regtype, 6917 Operand idxtype> 6918 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 6919class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 6920 Operand idxtype> 6921 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 6922 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 6923 6924class SIMDMovAlias<string asm, string size, Instruction inst, 6925 RegisterClass regtype, Operand idxtype> 6926 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 6927 "|" # size # "\t$dst, $src$idx}", 6928 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 6929 6930multiclass SMov { 6931 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 6932 bits<4> idx; 6933 let Inst{20-17} = idx; 6934 let Inst{16} = 1; 6935 } 6936 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 6937 bits<4> idx; 6938 let Inst{20-17} = idx; 6939 let Inst{16} = 1; 6940 } 6941 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 6942 bits<3> idx; 6943 let Inst{20-18} = idx; 6944 let Inst{17-16} = 0b10; 6945 } 6946 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 6947 bits<3> idx; 6948 let Inst{20-18} = idx; 6949 let Inst{17-16} = 0b10; 6950 } 6951 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 6952 bits<2> idx; 6953 let Inst{20-19} = idx; 6954 let Inst{18-16} = 0b100; 6955 } 6956} 6957 6958multiclass UMov { 6959 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 6960 bits<4> idx; 6961 let Inst{20-17} = idx; 6962 let Inst{16} = 1; 6963 } 6964 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 6965 bits<3> idx; 6966 let Inst{20-18} = idx; 6967 let Inst{17-16} = 0b10; 6968 } 6969 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 6970 bits<2> idx; 6971 let Inst{20-19} = idx; 6972 let Inst{18-16} = 0b100; 6973 } 6974 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 6975 bits<1> idx; 6976 let Inst{20} = idx; 6977 let Inst{19-16} = 0b1000; 6978 } 6979 def : SIMDMovAlias<"mov", ".s", 6980 !cast<Instruction>(NAME#"vi32"), 6981 GPR32, VectorIndexS>; 6982 def : SIMDMovAlias<"mov", ".d", 6983 !cast<Instruction>(NAME#"vi64"), 6984 GPR64, VectorIndexD>; 6985} 6986 6987class SIMDInsFromMain<string size, ValueType vectype, 6988 RegisterClass regtype, Operand idxtype> 6989 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 6990 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 6991 "{\t$Rd" # size # "$idx, $Rn" # 6992 "|" # size # "\t$Rd$idx, $Rn}", 6993 "$Rd = $dst", 6994 [(set V128:$dst, 6995 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 6996 let Inst{14-11} = 0b0011; 6997} 6998 6999class SIMDInsFromElement<string size, ValueType vectype, 7000 ValueType elttype, Operand idxtype> 7001 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 7002 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 7003 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 7004 "|" # size # "\t$Rd$idx, $Rn$idx2}", 7005 "$Rd = $dst", 7006 [(set V128:$dst, 7007 (vector_insert 7008 (vectype V128:$Rd), 7009 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 7010 idxtype:$idx))]>; 7011 7012class SIMDInsMainMovAlias<string size, Instruction inst, 7013 RegisterClass regtype, Operand idxtype> 7014 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 7015 "|" # size #"\t$dst$idx, $src}", 7016 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 7017class SIMDInsElementMovAlias<string size, Instruction inst, 7018 Operand idxtype> 7019 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" # 7020 # "|" # size #"\t$dst$idx, $src$idx2}", 7021 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 7022 7023 7024multiclass SIMDIns { 7025 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 7026 bits<4> idx; 7027 let Inst{20-17} = idx; 7028 let Inst{16} = 1; 7029 } 7030 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 7031 bits<3> idx; 7032 let Inst{20-18} = idx; 7033 let Inst{17-16} = 0b10; 7034 } 7035 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 7036 bits<2> idx; 7037 let Inst{20-19} = idx; 7038 let Inst{18-16} = 0b100; 7039 } 7040 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 7041 bits<1> idx; 7042 let Inst{20} = idx; 7043 let Inst{19-16} = 0b1000; 7044 } 7045 7046 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 7047 bits<4> idx; 7048 bits<4> idx2; 7049 let Inst{20-17} = idx; 7050 let Inst{16} = 1; 7051 let Inst{14-11} = idx2; 7052 } 7053 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 7054 bits<3> idx; 7055 bits<3> idx2; 7056 let Inst{20-18} = idx; 7057 let Inst{17-16} = 0b10; 7058 let Inst{14-12} = idx2; 7059 let Inst{11} = {?}; 7060 } 7061 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 7062 bits<2> idx; 7063 bits<2> idx2; 7064 let Inst{20-19} = idx; 7065 let Inst{18-16} = 0b100; 7066 let Inst{14-13} = idx2; 7067 let Inst{12-11} = {?,?}; 7068 } 7069 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 7070 bits<1> idx; 7071 bits<1> idx2; 7072 let Inst{20} = idx; 7073 let Inst{19-16} = 0b1000; 7074 let Inst{14} = idx2; 7075 let Inst{13-11} = {?,?,?}; 7076 } 7077 7078 // For all forms of the INS instruction, the "mov" mnemonic is the 7079 // preferred alias. Why they didn't just call the instruction "mov" in 7080 // the first place is a very good question indeed... 7081 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 7082 GPR32, VectorIndexB>; 7083 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 7084 GPR32, VectorIndexH>; 7085 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 7086 GPR32, VectorIndexS>; 7087 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 7088 GPR64, VectorIndexD>; 7089 7090 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 7091 VectorIndexB>; 7092 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 7093 VectorIndexH>; 7094 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 7095 VectorIndexS>; 7096 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 7097 VectorIndexD>; 7098} 7099 7100//---------------------------------------------------------------------------- 7101// AdvSIMD TBL/TBX 7102//---------------------------------------------------------------------------- 7103 7104let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7105class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7106 RegisterOperand listtype, string asm, string kind> 7107 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 7108 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 7109 Sched<[WriteV]> { 7110 bits<5> Vd; 7111 bits<5> Vn; 7112 bits<5> Vm; 7113 let Inst{31} = 0; 7114 let Inst{30} = Q; 7115 let Inst{29-21} = 0b001110000; 7116 let Inst{20-16} = Vm; 7117 let Inst{15} = 0; 7118 let Inst{14-13} = len; 7119 let Inst{12} = op; 7120 let Inst{11-10} = 0b00; 7121 let Inst{9-5} = Vn; 7122 let Inst{4-0} = Vd; 7123} 7124 7125let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7126class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 7127 RegisterOperand listtype, string asm, string kind> 7128 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 7129 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 7130 Sched<[WriteV]> { 7131 bits<5> Vd; 7132 bits<5> Vn; 7133 bits<5> Vm; 7134 let Inst{31} = 0; 7135 let Inst{30} = Q; 7136 let Inst{29-21} = 0b001110000; 7137 let Inst{20-16} = Vm; 7138 let Inst{15} = 0; 7139 let Inst{14-13} = len; 7140 let Inst{12} = op; 7141 let Inst{11-10} = 0b00; 7142 let Inst{9-5} = Vn; 7143 let Inst{4-0} = Vd; 7144} 7145 7146class SIMDTableLookupAlias<string asm, Instruction inst, 7147 RegisterOperand vectype, RegisterOperand listtype> 7148 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 7149 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 7150 7151multiclass SIMDTableLookup<bit op, string asm> { 7152 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 7153 asm, ".8b">; 7154 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 7155 asm, ".8b">; 7156 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 7157 asm, ".8b">; 7158 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 7159 asm, ".8b">; 7160 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 7161 asm, ".16b">; 7162 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 7163 asm, ".16b">; 7164 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 7165 asm, ".16b">; 7166 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 7167 asm, ".16b">; 7168 7169 def : SIMDTableLookupAlias<asm # ".8b", 7170 !cast<Instruction>(NAME#"v8i8One"), 7171 V64, VecListOne128>; 7172 def : SIMDTableLookupAlias<asm # ".8b", 7173 !cast<Instruction>(NAME#"v8i8Two"), 7174 V64, VecListTwo128>; 7175 def : SIMDTableLookupAlias<asm # ".8b", 7176 !cast<Instruction>(NAME#"v8i8Three"), 7177 V64, VecListThree128>; 7178 def : SIMDTableLookupAlias<asm # ".8b", 7179 !cast<Instruction>(NAME#"v8i8Four"), 7180 V64, VecListFour128>; 7181 def : SIMDTableLookupAlias<asm # ".16b", 7182 !cast<Instruction>(NAME#"v16i8One"), 7183 V128, VecListOne128>; 7184 def : SIMDTableLookupAlias<asm # ".16b", 7185 !cast<Instruction>(NAME#"v16i8Two"), 7186 V128, VecListTwo128>; 7187 def : SIMDTableLookupAlias<asm # ".16b", 7188 !cast<Instruction>(NAME#"v16i8Three"), 7189 V128, VecListThree128>; 7190 def : SIMDTableLookupAlias<asm # ".16b", 7191 !cast<Instruction>(NAME#"v16i8Four"), 7192 V128, VecListFour128>; 7193} 7194 7195multiclass SIMDTableLookupTied<bit op, string asm> { 7196 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 7197 asm, ".8b">; 7198 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 7199 asm, ".8b">; 7200 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 7201 asm, ".8b">; 7202 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 7203 asm, ".8b">; 7204 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 7205 asm, ".16b">; 7206 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 7207 asm, ".16b">; 7208 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 7209 asm, ".16b">; 7210 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 7211 asm, ".16b">; 7212 7213 def : SIMDTableLookupAlias<asm # ".8b", 7214 !cast<Instruction>(NAME#"v8i8One"), 7215 V64, VecListOne128>; 7216 def : SIMDTableLookupAlias<asm # ".8b", 7217 !cast<Instruction>(NAME#"v8i8Two"), 7218 V64, VecListTwo128>; 7219 def : SIMDTableLookupAlias<asm # ".8b", 7220 !cast<Instruction>(NAME#"v8i8Three"), 7221 V64, VecListThree128>; 7222 def : SIMDTableLookupAlias<asm # ".8b", 7223 !cast<Instruction>(NAME#"v8i8Four"), 7224 V64, VecListFour128>; 7225 def : SIMDTableLookupAlias<asm # ".16b", 7226 !cast<Instruction>(NAME#"v16i8One"), 7227 V128, VecListOne128>; 7228 def : SIMDTableLookupAlias<asm # ".16b", 7229 !cast<Instruction>(NAME#"v16i8Two"), 7230 V128, VecListTwo128>; 7231 def : SIMDTableLookupAlias<asm # ".16b", 7232 !cast<Instruction>(NAME#"v16i8Three"), 7233 V128, VecListThree128>; 7234 def : SIMDTableLookupAlias<asm # ".16b", 7235 !cast<Instruction>(NAME#"v16i8Four"), 7236 V128, VecListFour128>; 7237} 7238 7239 7240//---------------------------------------------------------------------------- 7241// AdvSIMD scalar CPY 7242//---------------------------------------------------------------------------- 7243let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7244class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 7245 string kind, Operand idxtype> 7246 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 7247 "{\t$dst, $src" # kind # "$idx" # 7248 "|\t$dst, $src$idx}", "", []>, 7249 Sched<[WriteV]> { 7250 bits<5> dst; 7251 bits<5> src; 7252 let Inst{31-21} = 0b01011110000; 7253 let Inst{15-10} = 0b000001; 7254 let Inst{9-5} = src; 7255 let Inst{4-0} = dst; 7256} 7257 7258class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 7259 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 7260 : InstAlias<asm # "{\t$dst, $src" # size # "$index" # 7261 # "|\t$dst, $src$index}", 7262 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 7263 7264 7265multiclass SIMDScalarCPY<string asm> { 7266 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 7267 bits<4> idx; 7268 let Inst{20-17} = idx; 7269 let Inst{16} = 1; 7270 } 7271 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 7272 bits<3> idx; 7273 let Inst{20-18} = idx; 7274 let Inst{17-16} = 0b10; 7275 } 7276 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 7277 bits<2> idx; 7278 let Inst{20-19} = idx; 7279 let Inst{18-16} = 0b100; 7280 } 7281 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 7282 bits<1> idx; 7283 let Inst{20} = idx; 7284 let Inst{19-16} = 0b1000; 7285 } 7286 7287 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 7288 VectorIndexD:$idx)))), 7289 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 7290 7291 // 'DUP' mnemonic aliases. 7292 def : SIMDScalarCPYAlias<"dup", ".b", 7293 !cast<Instruction>(NAME#"i8"), 7294 FPR8, V128, VectorIndexB>; 7295 def : SIMDScalarCPYAlias<"dup", ".h", 7296 !cast<Instruction>(NAME#"i16"), 7297 FPR16, V128, VectorIndexH>; 7298 def : SIMDScalarCPYAlias<"dup", ".s", 7299 !cast<Instruction>(NAME#"i32"), 7300 FPR32, V128, VectorIndexS>; 7301 def : SIMDScalarCPYAlias<"dup", ".d", 7302 !cast<Instruction>(NAME#"i64"), 7303 FPR64, V128, VectorIndexD>; 7304} 7305 7306//---------------------------------------------------------------------------- 7307// AdvSIMD modified immediate instructions 7308//---------------------------------------------------------------------------- 7309 7310class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 7311 string asm, string op_string, 7312 string cstr, list<dag> pattern> 7313 : I<oops, iops, asm, op_string, cstr, pattern>, 7314 Sched<[WriteV]> { 7315 bits<5> Rd; 7316 bits<8> imm8; 7317 let Inst{31} = 0; 7318 let Inst{30} = Q; 7319 let Inst{29} = op; 7320 let Inst{28-19} = 0b0111100000; 7321 let Inst{18-16} = imm8{7-5}; 7322 let Inst{11} = op2; 7323 let Inst{10} = 1; 7324 let Inst{9-5} = imm8{4-0}; 7325 let Inst{4-0} = Rd; 7326} 7327 7328class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 7329 Operand immtype, dag opt_shift_iop, 7330 string opt_shift, string asm, string kind, 7331 list<dag> pattern> 7332 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 7333 !con((ins immtype:$imm8), opt_shift_iop), asm, 7334 "{\t$Rd" # kind # ", $imm8" # opt_shift # 7335 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7336 "", pattern> { 7337 let DecoderMethod = "DecodeModImmInstruction"; 7338} 7339 7340class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 7341 Operand immtype, dag opt_shift_iop, 7342 string opt_shift, string asm, string kind, 7343 list<dag> pattern> 7344 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 7345 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 7346 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 7347 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 7348 "$Rd = $dst", pattern> { 7349 let DecoderMethod = "DecodeModImmTiedInstruction"; 7350} 7351 7352class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 7353 RegisterOperand vectype, string asm, 7354 string kind, list<dag> pattern> 7355 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7356 (ins logical_vec_shift:$shift), 7357 "$shift", asm, kind, pattern> { 7358 bits<2> shift; 7359 let Inst{15} = b15_b12{1}; 7360 let Inst{14-13} = shift; 7361 let Inst{12} = b15_b12{0}; 7362} 7363 7364class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 7365 RegisterOperand vectype, string asm, 7366 string kind, list<dag> pattern> 7367 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7368 (ins logical_vec_shift:$shift), 7369 "$shift", asm, kind, pattern> { 7370 bits<2> shift; 7371 let Inst{15} = b15_b12{1}; 7372 let Inst{14-13} = shift; 7373 let Inst{12} = b15_b12{0}; 7374} 7375 7376 7377class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 7378 RegisterOperand vectype, string asm, 7379 string kind, list<dag> pattern> 7380 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7381 (ins logical_vec_hw_shift:$shift), 7382 "$shift", asm, kind, pattern> { 7383 bits<2> shift; 7384 let Inst{15} = b15_b12{1}; 7385 let Inst{14} = 0; 7386 let Inst{13} = shift{0}; 7387 let Inst{12} = b15_b12{0}; 7388} 7389 7390class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 7391 RegisterOperand vectype, string asm, 7392 string kind, list<dag> pattern> 7393 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 7394 (ins logical_vec_hw_shift:$shift), 7395 "$shift", asm, kind, pattern> { 7396 bits<2> shift; 7397 let Inst{15} = b15_b12{1}; 7398 let Inst{14} = 0; 7399 let Inst{13} = shift{0}; 7400 let Inst{12} = b15_b12{0}; 7401} 7402 7403multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 7404 string asm> { 7405 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 7406 asm, ".4h", []>; 7407 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 7408 asm, ".8h", []>; 7409 7410 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 7411 asm, ".2s", []>; 7412 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 7413 asm, ".4s", []>; 7414} 7415 7416multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 7417 bits<2> w_cmode, string asm, 7418 SDNode OpNode> { 7419 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 7420 asm, ".4h", 7421 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 7422 imm0_255:$imm8, 7423 (i32 imm:$shift)))]>; 7424 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 7425 asm, ".8h", 7426 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 7427 imm0_255:$imm8, 7428 (i32 imm:$shift)))]>; 7429 7430 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 7431 asm, ".2s", 7432 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 7433 imm0_255:$imm8, 7434 (i32 imm:$shift)))]>; 7435 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 7436 asm, ".4s", 7437 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 7438 imm0_255:$imm8, 7439 (i32 imm:$shift)))]>; 7440} 7441 7442class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 7443 RegisterOperand vectype, string asm, 7444 string kind, list<dag> pattern> 7445 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 7446 (ins move_vec_shift:$shift), 7447 "$shift", asm, kind, pattern> { 7448 bits<1> shift; 7449 let Inst{15-13} = cmode{3-1}; 7450 let Inst{12} = shift; 7451} 7452 7453class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 7454 RegisterOperand vectype, 7455 Operand imm_type, string asm, 7456 string kind, list<dag> pattern> 7457 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 7458 asm, kind, pattern> { 7459 let Inst{15-12} = cmode; 7460} 7461 7462class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 7463 list<dag> pattern> 7464 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 7465 "\t$Rd, $imm8", "", pattern> { 7466 let Inst{15-12} = cmode; 7467 let DecoderMethod = "DecodeModImmInstruction"; 7468} 7469 7470//---------------------------------------------------------------------------- 7471// AdvSIMD indexed element 7472//---------------------------------------------------------------------------- 7473 7474let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7475class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7476 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7477 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7478 string apple_kind, string dst_kind, string lhs_kind, 7479 string rhs_kind, list<dag> pattern> 7480 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 7481 asm, 7482 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7483 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 7484 Sched<[WriteV]> { 7485 bits<5> Rd; 7486 bits<5> Rn; 7487 bits<5> Rm; 7488 7489 let Inst{31} = 0; 7490 let Inst{30} = Q; 7491 let Inst{29} = U; 7492 let Inst{28} = Scalar; 7493 let Inst{27-24} = 0b1111; 7494 let Inst{23-22} = size; 7495 // Bit 21 must be set by the derived class. 7496 let Inst{20-16} = Rm; 7497 let Inst{15-12} = opc; 7498 // Bit 11 must be set by the derived class. 7499 let Inst{10} = 0; 7500 let Inst{9-5} = Rn; 7501 let Inst{4-0} = Rd; 7502} 7503 7504let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7505class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 7506 RegisterOperand dst_reg, RegisterOperand lhs_reg, 7507 RegisterOperand rhs_reg, Operand vec_idx, string asm, 7508 string apple_kind, string dst_kind, string lhs_kind, 7509 string rhs_kind, list<dag> pattern> 7510 : I<(outs dst_reg:$dst), 7511 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 7512 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 7513 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 7514 Sched<[WriteV]> { 7515 bits<5> Rd; 7516 bits<5> Rn; 7517 bits<5> Rm; 7518 7519 let Inst{31} = 0; 7520 let Inst{30} = Q; 7521 let Inst{29} = U; 7522 let Inst{28} = Scalar; 7523 let Inst{27-24} = 0b1111; 7524 let Inst{23-22} = size; 7525 // Bit 21 must be set by the derived class. 7526 let Inst{20-16} = Rm; 7527 let Inst{15-12} = opc; 7528 // Bit 11 must be set by the derived class. 7529 let Inst{10} = 0; 7530 let Inst{9-5} = Rn; 7531 let Inst{4-0} = Rd; 7532} 7533 7534// ARMv8.2-A Dot Product Instructions (Indexed) 7535class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind, 7536 string lhs_kind, string rhs_kind, 7537 RegisterOperand RegType, 7538 ValueType AccumType, ValueType InputType, 7539 SDPatternOperator OpNode> : 7540 BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, RegType, RegType, V128, 7541 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind, 7542 [(set (AccumType RegType:$dst), 7543 (AccumType (OpNode (AccumType RegType:$Rd), 7544 (InputType RegType:$Rn), 7545 (InputType (bitconvert (AccumType 7546 (AArch64duplane32 (v4i32 V128:$Rm), 7547 VectorIndexS:$idx)))))))]> { 7548 bits<2> idx; 7549 let Inst{21} = idx{0}; // L 7550 let Inst{11} = idx{1}; // H 7551} 7552 7553multiclass SIMDThreeSameVectorDotIndex<bit U, string asm, 7554 SDPatternOperator OpNode> { 7555 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, asm, ".2s", ".8b", ".4b", 7556 V64, v2i32, v8i8, OpNode>; 7557 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, asm, ".4s", ".16b", ".4b", 7558 V128, v4i32, v16i8, OpNode>; 7559} 7560 7561// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed) 7562class BaseSIMDThreeSameVectorFMLIndex<bit Q, bit U, bits<4> opc, string asm, 7563 string dst_kind, string lhs_kind, 7564 string rhs_kind, RegisterOperand RegType, 7565 ValueType AccumType, ValueType InputType, 7566 SDPatternOperator OpNode> : 7567 BaseSIMDIndexedTied<Q, U, 0, 0b10, opc, RegType, RegType, V128, 7568 VectorIndexH, asm, "", dst_kind, lhs_kind, rhs_kind, 7569 [(set (AccumType RegType:$dst), 7570 (AccumType (OpNode (AccumType RegType:$Rd), 7571 (InputType RegType:$Rn), 7572 (InputType (AArch64duplane16 (v8f16 V128:$Rm), 7573 VectorIndexH:$idx)))))]> { 7574 // idx = H:L:M 7575 bits<3> idx; 7576 let Inst{11} = idx{2}; // H 7577 let Inst{21} = idx{1}; // L 7578 let Inst{20} = idx{0}; // M 7579} 7580 7581multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm, 7582 SDPatternOperator OpNode> { 7583 def v4f16 : BaseSIMDThreeSameVectorFMLIndex<0, U, opc, asm, ".2s", ".2h", ".h", 7584 V64, v2f32, v4f16, OpNode>; 7585 def v8f16 : BaseSIMDThreeSameVectorFMLIndex<1, U, opc, asm, ".4s", ".4h", ".h", 7586 V128, v4f32, v8f16, OpNode>; 7587} 7588 7589multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 7590 SDPatternOperator OpNode> { 7591 let Predicates = [HasNEON, HasFullFP16] in { 7592 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 7593 V64, V64, 7594 V128_lo, VectorIndexH, 7595 asm, ".4h", ".4h", ".4h", ".h", 7596 [(set (v4f16 V64:$Rd), 7597 (OpNode (v4f16 V64:$Rn), 7598 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7599 bits<3> idx; 7600 let Inst{11} = idx{2}; 7601 let Inst{21} = idx{1}; 7602 let Inst{20} = idx{0}; 7603 } 7604 7605 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 7606 V128, V128, 7607 V128_lo, VectorIndexH, 7608 asm, ".8h", ".8h", ".8h", ".h", 7609 [(set (v8f16 V128:$Rd), 7610 (OpNode (v8f16 V128:$Rn), 7611 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7612 bits<3> idx; 7613 let Inst{11} = idx{2}; 7614 let Inst{21} = idx{1}; 7615 let Inst{20} = idx{0}; 7616 } 7617 } // Predicates = [HasNEON, HasFullFP16] 7618 7619 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7620 V64, V64, 7621 V128, VectorIndexS, 7622 asm, ".2s", ".2s", ".2s", ".s", 7623 [(set (v2f32 V64:$Rd), 7624 (OpNode (v2f32 V64:$Rn), 7625 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 7626 bits<2> idx; 7627 let Inst{11} = idx{1}; 7628 let Inst{21} = idx{0}; 7629 } 7630 7631 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7632 V128, V128, 7633 V128, VectorIndexS, 7634 asm, ".4s", ".4s", ".4s", ".s", 7635 [(set (v4f32 V128:$Rd), 7636 (OpNode (v4f32 V128:$Rn), 7637 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 7638 bits<2> idx; 7639 let Inst{11} = idx{1}; 7640 let Inst{21} = idx{0}; 7641 } 7642 7643 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 7644 V128, V128, 7645 V128, VectorIndexD, 7646 asm, ".2d", ".2d", ".2d", ".d", 7647 [(set (v2f64 V128:$Rd), 7648 (OpNode (v2f64 V128:$Rn), 7649 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 7650 bits<1> idx; 7651 let Inst{11} = idx{0}; 7652 let Inst{21} = 0; 7653 } 7654 7655 let Predicates = [HasNEON, HasFullFP16] in { 7656 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 7657 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7658 asm, ".h", "", "", ".h", 7659 [(set (f16 FPR16Op:$Rd), 7660 (OpNode (f16 FPR16Op:$Rn), 7661 (f16 (vector_extract (v8f16 V128_lo:$Rm), 7662 VectorIndexH:$idx))))]> { 7663 bits<3> idx; 7664 let Inst{11} = idx{2}; 7665 let Inst{21} = idx{1}; 7666 let Inst{20} = idx{0}; 7667 } 7668 } // Predicates = [HasNEON, HasFullFP16] 7669 7670 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7671 FPR32Op, FPR32Op, V128, VectorIndexS, 7672 asm, ".s", "", "", ".s", 7673 [(set (f32 FPR32Op:$Rd), 7674 (OpNode (f32 FPR32Op:$Rn), 7675 (f32 (vector_extract (v4f32 V128:$Rm), 7676 VectorIndexS:$idx))))]> { 7677 bits<2> idx; 7678 let Inst{11} = idx{1}; 7679 let Inst{21} = idx{0}; 7680 } 7681 7682 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 7683 FPR64Op, FPR64Op, V128, VectorIndexD, 7684 asm, ".d", "", "", ".d", 7685 [(set (f64 FPR64Op:$Rd), 7686 (OpNode (f64 FPR64Op:$Rn), 7687 (f64 (vector_extract (v2f64 V128:$Rm), 7688 VectorIndexD:$idx))))]> { 7689 bits<1> idx; 7690 let Inst{11} = idx{0}; 7691 let Inst{21} = 0; 7692 } 7693} 7694 7695multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 7696 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 7697 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 7698 (AArch64duplane32 (v4f32 V128:$Rm), 7699 VectorIndexS:$idx))), 7700 (!cast<Instruction>(INST # v2i32_indexed) 7701 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 7702 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 7703 (AArch64dup (f32 FPR32Op:$Rm)))), 7704 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 7705 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 7706 7707 7708 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 7709 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 7710 (AArch64duplane32 (v4f32 V128:$Rm), 7711 VectorIndexS:$idx))), 7712 (!cast<Instruction>(INST # "v4i32_indexed") 7713 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 7714 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 7715 (AArch64dup (f32 FPR32Op:$Rm)))), 7716 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 7717 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 7718 7719 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 7720 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 7721 (AArch64duplane64 (v2f64 V128:$Rm), 7722 VectorIndexD:$idx))), 7723 (!cast<Instruction>(INST # "v2i64_indexed") 7724 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 7725 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 7726 (AArch64dup (f64 FPR64Op:$Rm)))), 7727 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 7728 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 7729 7730 // 2 variants for 32-bit scalar version: extract from .2s or from .4s 7731 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 7732 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 7733 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 7734 V128:$Rm, VectorIndexS:$idx)>; 7735 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 7736 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))), 7737 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 7738 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>; 7739 7740 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 7741 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 7742 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 7743 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 7744 V128:$Rm, VectorIndexD:$idx)>; 7745} 7746 7747multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 7748 let Predicates = [HasNEON, HasFullFP16] in { 7749 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 7750 V128_lo, VectorIndexH, 7751 asm, ".4h", ".4h", ".4h", ".h", []> { 7752 bits<3> idx; 7753 let Inst{11} = idx{2}; 7754 let Inst{21} = idx{1}; 7755 let Inst{20} = idx{0}; 7756 } 7757 7758 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 7759 V128, V128, 7760 V128_lo, VectorIndexH, 7761 asm, ".8h", ".8h", ".8h", ".h", []> { 7762 bits<3> idx; 7763 let Inst{11} = idx{2}; 7764 let Inst{21} = idx{1}; 7765 let Inst{20} = idx{0}; 7766 } 7767 } // Predicates = [HasNEON, HasFullFP16] 7768 7769 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 7770 V128, VectorIndexS, 7771 asm, ".2s", ".2s", ".2s", ".s", []> { 7772 bits<2> idx; 7773 let Inst{11} = idx{1}; 7774 let Inst{21} = idx{0}; 7775 } 7776 7777 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7778 V128, V128, 7779 V128, VectorIndexS, 7780 asm, ".4s", ".4s", ".4s", ".s", []> { 7781 bits<2> idx; 7782 let Inst{11} = idx{1}; 7783 let Inst{21} = idx{0}; 7784 } 7785 7786 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 7787 V128, V128, 7788 V128, VectorIndexD, 7789 asm, ".2d", ".2d", ".2d", ".d", []> { 7790 bits<1> idx; 7791 let Inst{11} = idx{0}; 7792 let Inst{21} = 0; 7793 } 7794 7795 let Predicates = [HasNEON, HasFullFP16] in { 7796 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 7797 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7798 asm, ".h", "", "", ".h", []> { 7799 bits<3> idx; 7800 let Inst{11} = idx{2}; 7801 let Inst{21} = idx{1}; 7802 let Inst{20} = idx{0}; 7803 } 7804 } // Predicates = [HasNEON, HasFullFP16] 7805 7806 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 7807 FPR32Op, FPR32Op, V128, VectorIndexS, 7808 asm, ".s", "", "", ".s", []> { 7809 bits<2> idx; 7810 let Inst{11} = idx{1}; 7811 let Inst{21} = idx{0}; 7812 } 7813 7814 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 7815 FPR64Op, FPR64Op, V128, VectorIndexD, 7816 asm, ".d", "", "", ".d", []> { 7817 bits<1> idx; 7818 let Inst{11} = idx{0}; 7819 let Inst{21} = 0; 7820 } 7821} 7822 7823multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 7824 SDPatternOperator OpNode> { 7825 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 7826 V128_lo, VectorIndexH, 7827 asm, ".4h", ".4h", ".4h", ".h", 7828 [(set (v4i16 V64:$Rd), 7829 (OpNode (v4i16 V64:$Rn), 7830 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7831 bits<3> idx; 7832 let Inst{11} = idx{2}; 7833 let Inst{21} = idx{1}; 7834 let Inst{20} = idx{0}; 7835 } 7836 7837 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7838 V128, V128, 7839 V128_lo, VectorIndexH, 7840 asm, ".8h", ".8h", ".8h", ".h", 7841 [(set (v8i16 V128:$Rd), 7842 (OpNode (v8i16 V128:$Rn), 7843 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7844 bits<3> idx; 7845 let Inst{11} = idx{2}; 7846 let Inst{21} = idx{1}; 7847 let Inst{20} = idx{0}; 7848 } 7849 7850 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7851 V64, V64, 7852 V128, VectorIndexS, 7853 asm, ".2s", ".2s", ".2s", ".s", 7854 [(set (v2i32 V64:$Rd), 7855 (OpNode (v2i32 V64:$Rn), 7856 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7857 bits<2> idx; 7858 let Inst{11} = idx{1}; 7859 let Inst{21} = idx{0}; 7860 } 7861 7862 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7863 V128, V128, 7864 V128, VectorIndexS, 7865 asm, ".4s", ".4s", ".4s", ".s", 7866 [(set (v4i32 V128:$Rd), 7867 (OpNode (v4i32 V128:$Rn), 7868 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7869 bits<2> idx; 7870 let Inst{11} = idx{1}; 7871 let Inst{21} = idx{0}; 7872 } 7873 7874 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 7875 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7876 asm, ".h", "", "", ".h", []> { 7877 bits<3> idx; 7878 let Inst{11} = idx{2}; 7879 let Inst{21} = idx{1}; 7880 let Inst{20} = idx{0}; 7881 } 7882 7883 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7884 FPR32Op, FPR32Op, V128, VectorIndexS, 7885 asm, ".s", "", "", ".s", 7886 [(set (i32 FPR32Op:$Rd), 7887 (OpNode FPR32Op:$Rn, 7888 (i32 (vector_extract (v4i32 V128:$Rm), 7889 VectorIndexS:$idx))))]> { 7890 bits<2> idx; 7891 let Inst{11} = idx{1}; 7892 let Inst{21} = idx{0}; 7893 } 7894} 7895 7896multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 7897 SDPatternOperator OpNode> { 7898 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7899 V64, V64, 7900 V128_lo, VectorIndexH, 7901 asm, ".4h", ".4h", ".4h", ".h", 7902 [(set (v4i16 V64:$Rd), 7903 (OpNode (v4i16 V64:$Rn), 7904 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7905 bits<3> idx; 7906 let Inst{11} = idx{2}; 7907 let Inst{21} = idx{1}; 7908 let Inst{20} = idx{0}; 7909 } 7910 7911 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7912 V128, V128, 7913 V128_lo, VectorIndexH, 7914 asm, ".8h", ".8h", ".8h", ".h", 7915 [(set (v8i16 V128:$Rd), 7916 (OpNode (v8i16 V128:$Rn), 7917 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7918 bits<3> idx; 7919 let Inst{11} = idx{2}; 7920 let Inst{21} = idx{1}; 7921 let Inst{20} = idx{0}; 7922 } 7923 7924 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7925 V64, V64, 7926 V128, VectorIndexS, 7927 asm, ".2s", ".2s", ".2s", ".s", 7928 [(set (v2i32 V64:$Rd), 7929 (OpNode (v2i32 V64:$Rn), 7930 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7931 bits<2> idx; 7932 let Inst{11} = idx{1}; 7933 let Inst{21} = idx{0}; 7934 } 7935 7936 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7937 V128, V128, 7938 V128, VectorIndexS, 7939 asm, ".4s", ".4s", ".4s", ".s", 7940 [(set (v4i32 V128:$Rd), 7941 (OpNode (v4i32 V128:$Rn), 7942 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7943 bits<2> idx; 7944 let Inst{11} = idx{1}; 7945 let Inst{21} = idx{0}; 7946 } 7947} 7948 7949multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 7950 SDPatternOperator OpNode> { 7951 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 7952 V128_lo, VectorIndexH, 7953 asm, ".4h", ".4h", ".4h", ".h", 7954 [(set (v4i16 V64:$dst), 7955 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 7956 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7957 bits<3> idx; 7958 let Inst{11} = idx{2}; 7959 let Inst{21} = idx{1}; 7960 let Inst{20} = idx{0}; 7961 } 7962 7963 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7964 V128, V128, 7965 V128_lo, VectorIndexH, 7966 asm, ".8h", ".8h", ".8h", ".h", 7967 [(set (v8i16 V128:$dst), 7968 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 7969 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7970 bits<3> idx; 7971 let Inst{11} = idx{2}; 7972 let Inst{21} = idx{1}; 7973 let Inst{20} = idx{0}; 7974 } 7975 7976 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7977 V64, V64, 7978 V128, VectorIndexS, 7979 asm, ".2s", ".2s", ".2s", ".s", 7980 [(set (v2i32 V64:$dst), 7981 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 7982 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7983 bits<2> idx; 7984 let Inst{11} = idx{1}; 7985 let Inst{21} = idx{0}; 7986 } 7987 7988 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7989 V128, V128, 7990 V128, VectorIndexS, 7991 asm, ".4s", ".4s", ".4s", ".s", 7992 [(set (v4i32 V128:$dst), 7993 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 7994 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7995 bits<2> idx; 7996 let Inst{11} = idx{1}; 7997 let Inst{21} = idx{0}; 7998 } 7999} 8000 8001multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 8002 SDPatternOperator OpNode> { 8003 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8004 V128, V64, 8005 V128_lo, VectorIndexH, 8006 asm, ".4s", ".4s", ".4h", ".h", 8007 [(set (v4i32 V128:$Rd), 8008 (OpNode (v4i16 V64:$Rn), 8009 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8010 bits<3> idx; 8011 let Inst{11} = idx{2}; 8012 let Inst{21} = idx{1}; 8013 let Inst{20} = idx{0}; 8014 } 8015 8016 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8017 V128, V128, 8018 V128_lo, VectorIndexH, 8019 asm#"2", ".4s", ".4s", ".8h", ".h", 8020 [(set (v4i32 V128:$Rd), 8021 (OpNode (extract_high_v8i16 V128:$Rn), 8022 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8023 VectorIndexH:$idx))))]> { 8024 8025 bits<3> idx; 8026 let Inst{11} = idx{2}; 8027 let Inst{21} = idx{1}; 8028 let Inst{20} = idx{0}; 8029 } 8030 8031 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8032 V128, V64, 8033 V128, VectorIndexS, 8034 asm, ".2d", ".2d", ".2s", ".s", 8035 [(set (v2i64 V128:$Rd), 8036 (OpNode (v2i32 V64:$Rn), 8037 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8038 bits<2> idx; 8039 let Inst{11} = idx{1}; 8040 let Inst{21} = idx{0}; 8041 } 8042 8043 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8044 V128, V128, 8045 V128, VectorIndexS, 8046 asm#"2", ".2d", ".2d", ".4s", ".s", 8047 [(set (v2i64 V128:$Rd), 8048 (OpNode (extract_high_v4i32 V128:$Rn), 8049 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8050 VectorIndexS:$idx))))]> { 8051 bits<2> idx; 8052 let Inst{11} = idx{1}; 8053 let Inst{21} = idx{0}; 8054 } 8055 8056 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 8057 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8058 asm, ".h", "", "", ".h", []> { 8059 bits<3> idx; 8060 let Inst{11} = idx{2}; 8061 let Inst{21} = idx{1}; 8062 let Inst{20} = idx{0}; 8063 } 8064 8065 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 8066 FPR64Op, FPR32Op, V128, VectorIndexS, 8067 asm, ".s", "", "", ".s", []> { 8068 bits<2> idx; 8069 let Inst{11} = idx{1}; 8070 let Inst{21} = idx{0}; 8071 } 8072} 8073 8074multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 8075 SDPatternOperator Accum> { 8076 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8077 V128, V64, 8078 V128_lo, VectorIndexH, 8079 asm, ".4s", ".4s", ".4h", ".h", 8080 [(set (v4i32 V128:$dst), 8081 (Accum (v4i32 V128:$Rd), 8082 (v4i32 (int_aarch64_neon_sqdmull 8083 (v4i16 V64:$Rn), 8084 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8085 VectorIndexH:$idx))))))]> { 8086 bits<3> idx; 8087 let Inst{11} = idx{2}; 8088 let Inst{21} = idx{1}; 8089 let Inst{20} = idx{0}; 8090 } 8091 8092 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 8093 // intermediate EXTRACT_SUBREG would be untyped. 8094 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 8095 (i32 (vector_extract (v4i32 8096 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 8097 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8098 VectorIndexH:$idx)))), 8099 (i64 0))))), 8100 (EXTRACT_SUBREG 8101 (!cast<Instruction>(NAME # v4i16_indexed) 8102 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 8103 V128_lo:$Rm, VectorIndexH:$idx), 8104 ssub)>; 8105 8106 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8107 V128, V128, 8108 V128_lo, VectorIndexH, 8109 asm#"2", ".4s", ".4s", ".8h", ".h", 8110 [(set (v4i32 V128:$dst), 8111 (Accum (v4i32 V128:$Rd), 8112 (v4i32 (int_aarch64_neon_sqdmull 8113 (extract_high_v8i16 V128:$Rn), 8114 (extract_high_v8i16 8115 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8116 VectorIndexH:$idx))))))]> { 8117 bits<3> idx; 8118 let Inst{11} = idx{2}; 8119 let Inst{21} = idx{1}; 8120 let Inst{20} = idx{0}; 8121 } 8122 8123 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8124 V128, V64, 8125 V128, VectorIndexS, 8126 asm, ".2d", ".2d", ".2s", ".s", 8127 [(set (v2i64 V128:$dst), 8128 (Accum (v2i64 V128:$Rd), 8129 (v2i64 (int_aarch64_neon_sqdmull 8130 (v2i32 V64:$Rn), 8131 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 8132 VectorIndexS:$idx))))))]> { 8133 bits<2> idx; 8134 let Inst{11} = idx{1}; 8135 let Inst{21} = idx{0}; 8136 } 8137 8138 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8139 V128, V128, 8140 V128, VectorIndexS, 8141 asm#"2", ".2d", ".2d", ".4s", ".s", 8142 [(set (v2i64 V128:$dst), 8143 (Accum (v2i64 V128:$Rd), 8144 (v2i64 (int_aarch64_neon_sqdmull 8145 (extract_high_v4i32 V128:$Rn), 8146 (extract_high_v4i32 8147 (AArch64duplane32 (v4i32 V128:$Rm), 8148 VectorIndexS:$idx))))))]> { 8149 bits<2> idx; 8150 let Inst{11} = idx{1}; 8151 let Inst{21} = idx{0}; 8152 } 8153 8154 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 8155 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 8156 asm, ".h", "", "", ".h", []> { 8157 bits<3> idx; 8158 let Inst{11} = idx{2}; 8159 let Inst{21} = idx{1}; 8160 let Inst{20} = idx{0}; 8161 } 8162 8163 8164 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 8165 FPR64Op, FPR32Op, V128, VectorIndexS, 8166 asm, ".s", "", "", ".s", 8167 [(set (i64 FPR64Op:$dst), 8168 (Accum (i64 FPR64Op:$Rd), 8169 (i64 (int_aarch64_neon_sqdmulls_scalar 8170 (i32 FPR32Op:$Rn), 8171 (i32 (vector_extract (v4i32 V128:$Rm), 8172 VectorIndexS:$idx))))))]> { 8173 8174 bits<2> idx; 8175 let Inst{11} = idx{1}; 8176 let Inst{21} = idx{0}; 8177 } 8178} 8179 8180multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 8181 SDPatternOperator OpNode> { 8182 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8183 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 8184 V128, V64, 8185 V128_lo, VectorIndexH, 8186 asm, ".4s", ".4s", ".4h", ".h", 8187 [(set (v4i32 V128:$Rd), 8188 (OpNode (v4i16 V64:$Rn), 8189 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8190 bits<3> idx; 8191 let Inst{11} = idx{2}; 8192 let Inst{21} = idx{1}; 8193 let Inst{20} = idx{0}; 8194 } 8195 8196 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 8197 V128, V128, 8198 V128_lo, VectorIndexH, 8199 asm#"2", ".4s", ".4s", ".8h", ".h", 8200 [(set (v4i32 V128:$Rd), 8201 (OpNode (extract_high_v8i16 V128:$Rn), 8202 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8203 VectorIndexH:$idx))))]> { 8204 8205 bits<3> idx; 8206 let Inst{11} = idx{2}; 8207 let Inst{21} = idx{1}; 8208 let Inst{20} = idx{0}; 8209 } 8210 8211 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 8212 V128, V64, 8213 V128, VectorIndexS, 8214 asm, ".2d", ".2d", ".2s", ".s", 8215 [(set (v2i64 V128:$Rd), 8216 (OpNode (v2i32 V64:$Rn), 8217 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8218 bits<2> idx; 8219 let Inst{11} = idx{1}; 8220 let Inst{21} = idx{0}; 8221 } 8222 8223 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 8224 V128, V128, 8225 V128, VectorIndexS, 8226 asm#"2", ".2d", ".2d", ".4s", ".s", 8227 [(set (v2i64 V128:$Rd), 8228 (OpNode (extract_high_v4i32 V128:$Rn), 8229 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8230 VectorIndexS:$idx))))]> { 8231 bits<2> idx; 8232 let Inst{11} = idx{1}; 8233 let Inst{21} = idx{0}; 8234 } 8235 } 8236} 8237 8238multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 8239 SDPatternOperator OpNode> { 8240 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 8241 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 8242 V128, V64, 8243 V128_lo, VectorIndexH, 8244 asm, ".4s", ".4s", ".4h", ".h", 8245 [(set (v4i32 V128:$dst), 8246 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 8247 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 8248 bits<3> idx; 8249 let Inst{11} = idx{2}; 8250 let Inst{21} = idx{1}; 8251 let Inst{20} = idx{0}; 8252 } 8253 8254 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 8255 V128, V128, 8256 V128_lo, VectorIndexH, 8257 asm#"2", ".4s", ".4s", ".8h", ".h", 8258 [(set (v4i32 V128:$dst), 8259 (OpNode (v4i32 V128:$Rd), 8260 (extract_high_v8i16 V128:$Rn), 8261 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 8262 VectorIndexH:$idx))))]> { 8263 bits<3> idx; 8264 let Inst{11} = idx{2}; 8265 let Inst{21} = idx{1}; 8266 let Inst{20} = idx{0}; 8267 } 8268 8269 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 8270 V128, V64, 8271 V128, VectorIndexS, 8272 asm, ".2d", ".2d", ".2s", ".s", 8273 [(set (v2i64 V128:$dst), 8274 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 8275 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 8276 bits<2> idx; 8277 let Inst{11} = idx{1}; 8278 let Inst{21} = idx{0}; 8279 } 8280 8281 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 8282 V128, V128, 8283 V128, VectorIndexS, 8284 asm#"2", ".2d", ".2d", ".4s", ".s", 8285 [(set (v2i64 V128:$dst), 8286 (OpNode (v2i64 V128:$Rd), 8287 (extract_high_v4i32 V128:$Rn), 8288 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 8289 VectorIndexS:$idx))))]> { 8290 bits<2> idx; 8291 let Inst{11} = idx{1}; 8292 let Inst{21} = idx{0}; 8293 } 8294 } 8295} 8296 8297//---------------------------------------------------------------------------- 8298// AdvSIMD scalar shift by immediate 8299//---------------------------------------------------------------------------- 8300 8301let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8302class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 8303 RegisterClass regtype1, RegisterClass regtype2, 8304 Operand immtype, string asm, list<dag> pattern> 8305 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 8306 asm, "\t$Rd, $Rn, $imm", "", pattern>, 8307 Sched<[WriteV]> { 8308 bits<5> Rd; 8309 bits<5> Rn; 8310 bits<7> imm; 8311 let Inst{31-30} = 0b01; 8312 let Inst{29} = U; 8313 let Inst{28-23} = 0b111110; 8314 let Inst{22-16} = fixed_imm; 8315 let Inst{15-11} = opc; 8316 let Inst{10} = 1; 8317 let Inst{9-5} = Rn; 8318 let Inst{4-0} = Rd; 8319} 8320 8321let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8322class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 8323 RegisterClass regtype1, RegisterClass regtype2, 8324 Operand immtype, string asm, list<dag> pattern> 8325 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 8326 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 8327 Sched<[WriteV]> { 8328 bits<5> Rd; 8329 bits<5> Rn; 8330 bits<7> imm; 8331 let Inst{31-30} = 0b01; 8332 let Inst{29} = U; 8333 let Inst{28-23} = 0b111110; 8334 let Inst{22-16} = fixed_imm; 8335 let Inst{15-11} = opc; 8336 let Inst{10} = 1; 8337 let Inst{9-5} = Rn; 8338 let Inst{4-0} = Rd; 8339} 8340 8341 8342multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 8343 let Predicates = [HasNEON, HasFullFP16] in { 8344 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8345 FPR16, FPR16, vecshiftR16, asm, []> { 8346 let Inst{19-16} = imm{3-0}; 8347 } 8348 } // Predicates = [HasNEON, HasFullFP16] 8349 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8350 FPR32, FPR32, vecshiftR32, asm, []> { 8351 let Inst{20-16} = imm{4-0}; 8352 } 8353 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8354 FPR64, FPR64, vecshiftR64, asm, []> { 8355 let Inst{21-16} = imm{5-0}; 8356 } 8357} 8358 8359multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 8360 SDPatternOperator OpNode> { 8361 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8362 FPR64, FPR64, vecshiftR64, asm, 8363 [(set (i64 FPR64:$Rd), 8364 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 8365 let Inst{21-16} = imm{5-0}; 8366 } 8367 8368 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 8369 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 8370} 8371 8372multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 8373 SDPatternOperator OpNode = null_frag> { 8374 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8375 FPR64, FPR64, vecshiftR64, asm, 8376 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 8377 (i32 vecshiftR64:$imm)))]> { 8378 let Inst{21-16} = imm{5-0}; 8379 } 8380 8381 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 8382 (i32 vecshiftR64:$imm))), 8383 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 8384 vecshiftR64:$imm)>; 8385} 8386 8387multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 8388 SDPatternOperator OpNode> { 8389 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8390 FPR64, FPR64, vecshiftL64, asm, 8391 [(set (v1i64 FPR64:$Rd), 8392 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8393 let Inst{21-16} = imm{5-0}; 8394 } 8395} 8396 8397let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8398multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 8399 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 8400 FPR64, FPR64, vecshiftL64, asm, []> { 8401 let Inst{21-16} = imm{5-0}; 8402 } 8403} 8404 8405let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8406multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 8407 SDPatternOperator OpNode = null_frag> { 8408 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8409 FPR8, FPR16, vecshiftR8, asm, []> { 8410 let Inst{18-16} = imm{2-0}; 8411 } 8412 8413 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8414 FPR16, FPR32, vecshiftR16, asm, []> { 8415 let Inst{19-16} = imm{3-0}; 8416 } 8417 8418 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8419 FPR32, FPR64, vecshiftR32, asm, 8420 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 8421 let Inst{20-16} = imm{4-0}; 8422 } 8423} 8424 8425multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 8426 SDPatternOperator OpNode> { 8427 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8428 FPR8, FPR8, vecshiftL8, asm, []> { 8429 let Inst{18-16} = imm{2-0}; 8430 } 8431 8432 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8433 FPR16, FPR16, vecshiftL16, asm, []> { 8434 let Inst{19-16} = imm{3-0}; 8435 } 8436 8437 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8438 FPR32, FPR32, vecshiftL32, asm, 8439 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 8440 let Inst{20-16} = imm{4-0}; 8441 } 8442 8443 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8444 FPR64, FPR64, vecshiftL64, asm, 8445 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 8446 let Inst{21-16} = imm{5-0}; 8447 } 8448 8449 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 8450 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 8451} 8452 8453multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 8454 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 8455 FPR8, FPR8, vecshiftR8, asm, []> { 8456 let Inst{18-16} = imm{2-0}; 8457 } 8458 8459 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 8460 FPR16, FPR16, vecshiftR16, asm, []> { 8461 let Inst{19-16} = imm{3-0}; 8462 } 8463 8464 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 8465 FPR32, FPR32, vecshiftR32, asm, []> { 8466 let Inst{20-16} = imm{4-0}; 8467 } 8468 8469 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 8470 FPR64, FPR64, vecshiftR64, asm, []> { 8471 let Inst{21-16} = imm{5-0}; 8472 } 8473} 8474 8475//---------------------------------------------------------------------------- 8476// AdvSIMD vector x indexed element 8477//---------------------------------------------------------------------------- 8478 8479let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8480class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 8481 RegisterOperand dst_reg, RegisterOperand src_reg, 8482 Operand immtype, 8483 string asm, string dst_kind, string src_kind, 8484 list<dag> pattern> 8485 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 8486 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 8487 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 8488 Sched<[WriteV]> { 8489 bits<5> Rd; 8490 bits<5> Rn; 8491 let Inst{31} = 0; 8492 let Inst{30} = Q; 8493 let Inst{29} = U; 8494 let Inst{28-23} = 0b011110; 8495 let Inst{22-16} = fixed_imm; 8496 let Inst{15-11} = opc; 8497 let Inst{10} = 1; 8498 let Inst{9-5} = Rn; 8499 let Inst{4-0} = Rd; 8500} 8501 8502let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 8503class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 8504 RegisterOperand vectype1, RegisterOperand vectype2, 8505 Operand immtype, 8506 string asm, string dst_kind, string src_kind, 8507 list<dag> pattern> 8508 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 8509 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 8510 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 8511 Sched<[WriteV]> { 8512 bits<5> Rd; 8513 bits<5> Rn; 8514 let Inst{31} = 0; 8515 let Inst{30} = Q; 8516 let Inst{29} = U; 8517 let Inst{28-23} = 0b011110; 8518 let Inst{22-16} = fixed_imm; 8519 let Inst{15-11} = opc; 8520 let Inst{10} = 1; 8521 let Inst{9-5} = Rn; 8522 let Inst{4-0} = Rd; 8523} 8524 8525multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 8526 Intrinsic OpNode> { 8527 let Predicates = [HasNEON, HasFullFP16] in { 8528 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8529 V64, V64, vecshiftR16, 8530 asm, ".4h", ".4h", 8531 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 8532 bits<4> imm; 8533 let Inst{19-16} = imm; 8534 } 8535 8536 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8537 V128, V128, vecshiftR16, 8538 asm, ".8h", ".8h", 8539 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 8540 bits<4> imm; 8541 let Inst{19-16} = imm; 8542 } 8543 } // Predicates = [HasNEON, HasFullFP16] 8544 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8545 V64, V64, vecshiftR32, 8546 asm, ".2s", ".2s", 8547 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 8548 bits<5> imm; 8549 let Inst{20-16} = imm; 8550 } 8551 8552 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8553 V128, V128, vecshiftR32, 8554 asm, ".4s", ".4s", 8555 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 8556 bits<5> imm; 8557 let Inst{20-16} = imm; 8558 } 8559 8560 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8561 V128, V128, vecshiftR64, 8562 asm, ".2d", ".2d", 8563 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 8564 bits<6> imm; 8565 let Inst{21-16} = imm; 8566 } 8567} 8568 8569multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 8570 Intrinsic OpNode> { 8571 let Predicates = [HasNEON, HasFullFP16] in { 8572 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8573 V64, V64, vecshiftR16, 8574 asm, ".4h", ".4h", 8575 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 8576 bits<4> imm; 8577 let Inst{19-16} = imm; 8578 } 8579 8580 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8581 V128, V128, vecshiftR16, 8582 asm, ".8h", ".8h", 8583 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 8584 bits<4> imm; 8585 let Inst{19-16} = imm; 8586 } 8587 } // Predicates = [HasNEON, HasFullFP16] 8588 8589 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8590 V64, V64, vecshiftR32, 8591 asm, ".2s", ".2s", 8592 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 8593 bits<5> imm; 8594 let Inst{20-16} = imm; 8595 } 8596 8597 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8598 V128, V128, vecshiftR32, 8599 asm, ".4s", ".4s", 8600 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 8601 bits<5> imm; 8602 let Inst{20-16} = imm; 8603 } 8604 8605 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8606 V128, V128, vecshiftR64, 8607 asm, ".2d", ".2d", 8608 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 8609 bits<6> imm; 8610 let Inst{21-16} = imm; 8611 } 8612} 8613 8614multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 8615 SDPatternOperator OpNode> { 8616 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8617 V64, V128, vecshiftR16Narrow, 8618 asm, ".8b", ".8h", 8619 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 8620 bits<3> imm; 8621 let Inst{18-16} = imm; 8622 } 8623 8624 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8625 V128, V128, vecshiftR16Narrow, 8626 asm#"2", ".16b", ".8h", []> { 8627 bits<3> imm; 8628 let Inst{18-16} = imm; 8629 let hasSideEffects = 0; 8630 } 8631 8632 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8633 V64, V128, vecshiftR32Narrow, 8634 asm, ".4h", ".4s", 8635 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 8636 bits<4> imm; 8637 let Inst{19-16} = imm; 8638 } 8639 8640 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8641 V128, V128, vecshiftR32Narrow, 8642 asm#"2", ".8h", ".4s", []> { 8643 bits<4> imm; 8644 let Inst{19-16} = imm; 8645 let hasSideEffects = 0; 8646 } 8647 8648 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8649 V64, V128, vecshiftR64Narrow, 8650 asm, ".2s", ".2d", 8651 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 8652 bits<5> imm; 8653 let Inst{20-16} = imm; 8654 } 8655 8656 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8657 V128, V128, vecshiftR64Narrow, 8658 asm#"2", ".4s", ".2d", []> { 8659 bits<5> imm; 8660 let Inst{20-16} = imm; 8661 let hasSideEffects = 0; 8662 } 8663 8664 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 8665 // themselves, so put them here instead. 8666 8667 // Patterns involving what's effectively an insert high and a normal 8668 // intrinsic, represented by CONCAT_VECTORS. 8669 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 8670 vecshiftR16Narrow:$imm)), 8671 (!cast<Instruction>(NAME # "v16i8_shift") 8672 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 8673 V128:$Rn, vecshiftR16Narrow:$imm)>; 8674 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 8675 vecshiftR32Narrow:$imm)), 8676 (!cast<Instruction>(NAME # "v8i16_shift") 8677 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 8678 V128:$Rn, vecshiftR32Narrow:$imm)>; 8679 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 8680 vecshiftR64Narrow:$imm)), 8681 (!cast<Instruction>(NAME # "v4i32_shift") 8682 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 8683 V128:$Rn, vecshiftR64Narrow:$imm)>; 8684} 8685 8686multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 8687 SDPatternOperator OpNode> { 8688 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8689 V64, V64, vecshiftL8, 8690 asm, ".8b", ".8b", 8691 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 8692 (i32 vecshiftL8:$imm)))]> { 8693 bits<3> imm; 8694 let Inst{18-16} = imm; 8695 } 8696 8697 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8698 V128, V128, vecshiftL8, 8699 asm, ".16b", ".16b", 8700 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 8701 (i32 vecshiftL8:$imm)))]> { 8702 bits<3> imm; 8703 let Inst{18-16} = imm; 8704 } 8705 8706 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8707 V64, V64, vecshiftL16, 8708 asm, ".4h", ".4h", 8709 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 8710 (i32 vecshiftL16:$imm)))]> { 8711 bits<4> imm; 8712 let Inst{19-16} = imm; 8713 } 8714 8715 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8716 V128, V128, vecshiftL16, 8717 asm, ".8h", ".8h", 8718 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 8719 (i32 vecshiftL16:$imm)))]> { 8720 bits<4> imm; 8721 let Inst{19-16} = imm; 8722 } 8723 8724 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8725 V64, V64, vecshiftL32, 8726 asm, ".2s", ".2s", 8727 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 8728 (i32 vecshiftL32:$imm)))]> { 8729 bits<5> imm; 8730 let Inst{20-16} = imm; 8731 } 8732 8733 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8734 V128, V128, vecshiftL32, 8735 asm, ".4s", ".4s", 8736 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 8737 (i32 vecshiftL32:$imm)))]> { 8738 bits<5> imm; 8739 let Inst{20-16} = imm; 8740 } 8741 8742 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8743 V128, V128, vecshiftL64, 8744 asm, ".2d", ".2d", 8745 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 8746 (i32 vecshiftL64:$imm)))]> { 8747 bits<6> imm; 8748 let Inst{21-16} = imm; 8749 } 8750} 8751 8752multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 8753 SDPatternOperator OpNode> { 8754 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8755 V64, V64, vecshiftR8, 8756 asm, ".8b", ".8b", 8757 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 8758 (i32 vecshiftR8:$imm)))]> { 8759 bits<3> imm; 8760 let Inst{18-16} = imm; 8761 } 8762 8763 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8764 V128, V128, vecshiftR8, 8765 asm, ".16b", ".16b", 8766 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 8767 (i32 vecshiftR8:$imm)))]> { 8768 bits<3> imm; 8769 let Inst{18-16} = imm; 8770 } 8771 8772 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8773 V64, V64, vecshiftR16, 8774 asm, ".4h", ".4h", 8775 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 8776 (i32 vecshiftR16:$imm)))]> { 8777 bits<4> imm; 8778 let Inst{19-16} = imm; 8779 } 8780 8781 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8782 V128, V128, vecshiftR16, 8783 asm, ".8h", ".8h", 8784 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 8785 (i32 vecshiftR16:$imm)))]> { 8786 bits<4> imm; 8787 let Inst{19-16} = imm; 8788 } 8789 8790 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8791 V64, V64, vecshiftR32, 8792 asm, ".2s", ".2s", 8793 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 8794 (i32 vecshiftR32:$imm)))]> { 8795 bits<5> imm; 8796 let Inst{20-16} = imm; 8797 } 8798 8799 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8800 V128, V128, vecshiftR32, 8801 asm, ".4s", ".4s", 8802 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 8803 (i32 vecshiftR32:$imm)))]> { 8804 bits<5> imm; 8805 let Inst{20-16} = imm; 8806 } 8807 8808 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8809 V128, V128, vecshiftR64, 8810 asm, ".2d", ".2d", 8811 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 8812 (i32 vecshiftR64:$imm)))]> { 8813 bits<6> imm; 8814 let Inst{21-16} = imm; 8815 } 8816} 8817 8818let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8819multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 8820 SDPatternOperator OpNode = null_frag> { 8821 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8822 V64, V64, vecshiftR8, asm, ".8b", ".8b", 8823 [(set (v8i8 V64:$dst), 8824 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8825 (i32 vecshiftR8:$imm)))]> { 8826 bits<3> imm; 8827 let Inst{18-16} = imm; 8828 } 8829 8830 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8831 V128, V128, vecshiftR8, asm, ".16b", ".16b", 8832 [(set (v16i8 V128:$dst), 8833 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8834 (i32 vecshiftR8:$imm)))]> { 8835 bits<3> imm; 8836 let Inst{18-16} = imm; 8837 } 8838 8839 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8840 V64, V64, vecshiftR16, asm, ".4h", ".4h", 8841 [(set (v4i16 V64:$dst), 8842 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8843 (i32 vecshiftR16:$imm)))]> { 8844 bits<4> imm; 8845 let Inst{19-16} = imm; 8846 } 8847 8848 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8849 V128, V128, vecshiftR16, asm, ".8h", ".8h", 8850 [(set (v8i16 V128:$dst), 8851 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8852 (i32 vecshiftR16:$imm)))]> { 8853 bits<4> imm; 8854 let Inst{19-16} = imm; 8855 } 8856 8857 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8858 V64, V64, vecshiftR32, asm, ".2s", ".2s", 8859 [(set (v2i32 V64:$dst), 8860 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8861 (i32 vecshiftR32:$imm)))]> { 8862 bits<5> imm; 8863 let Inst{20-16} = imm; 8864 } 8865 8866 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8867 V128, V128, vecshiftR32, asm, ".4s", ".4s", 8868 [(set (v4i32 V128:$dst), 8869 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8870 (i32 vecshiftR32:$imm)))]> { 8871 bits<5> imm; 8872 let Inst{20-16} = imm; 8873 } 8874 8875 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8876 V128, V128, vecshiftR64, 8877 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 8878 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8879 (i32 vecshiftR64:$imm)))]> { 8880 bits<6> imm; 8881 let Inst{21-16} = imm; 8882 } 8883} 8884 8885multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 8886 SDPatternOperator OpNode = null_frag> { 8887 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8888 V64, V64, vecshiftL8, 8889 asm, ".8b", ".8b", 8890 [(set (v8i8 V64:$dst), 8891 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8892 (i32 vecshiftL8:$imm)))]> { 8893 bits<3> imm; 8894 let Inst{18-16} = imm; 8895 } 8896 8897 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8898 V128, V128, vecshiftL8, 8899 asm, ".16b", ".16b", 8900 [(set (v16i8 V128:$dst), 8901 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8902 (i32 vecshiftL8:$imm)))]> { 8903 bits<3> imm; 8904 let Inst{18-16} = imm; 8905 } 8906 8907 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8908 V64, V64, vecshiftL16, 8909 asm, ".4h", ".4h", 8910 [(set (v4i16 V64:$dst), 8911 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8912 (i32 vecshiftL16:$imm)))]> { 8913 bits<4> imm; 8914 let Inst{19-16} = imm; 8915 } 8916 8917 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8918 V128, V128, vecshiftL16, 8919 asm, ".8h", ".8h", 8920 [(set (v8i16 V128:$dst), 8921 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8922 (i32 vecshiftL16:$imm)))]> { 8923 bits<4> imm; 8924 let Inst{19-16} = imm; 8925 } 8926 8927 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8928 V64, V64, vecshiftL32, 8929 asm, ".2s", ".2s", 8930 [(set (v2i32 V64:$dst), 8931 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8932 (i32 vecshiftL32:$imm)))]> { 8933 bits<5> imm; 8934 let Inst{20-16} = imm; 8935 } 8936 8937 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8938 V128, V128, vecshiftL32, 8939 asm, ".4s", ".4s", 8940 [(set (v4i32 V128:$dst), 8941 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8942 (i32 vecshiftL32:$imm)))]> { 8943 bits<5> imm; 8944 let Inst{20-16} = imm; 8945 } 8946 8947 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8948 V128, V128, vecshiftL64, 8949 asm, ".2d", ".2d", 8950 [(set (v2i64 V128:$dst), 8951 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8952 (i32 vecshiftL64:$imm)))]> { 8953 bits<6> imm; 8954 let Inst{21-16} = imm; 8955 } 8956} 8957 8958multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 8959 SDPatternOperator OpNode> { 8960 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8961 V128, V64, vecshiftL8, asm, ".8h", ".8b", 8962 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 8963 bits<3> imm; 8964 let Inst{18-16} = imm; 8965 } 8966 8967 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8968 V128, V128, vecshiftL8, 8969 asm#"2", ".8h", ".16b", 8970 [(set (v8i16 V128:$Rd), 8971 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 8972 bits<3> imm; 8973 let Inst{18-16} = imm; 8974 } 8975 8976 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8977 V128, V64, vecshiftL16, asm, ".4s", ".4h", 8978 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 8979 bits<4> imm; 8980 let Inst{19-16} = imm; 8981 } 8982 8983 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8984 V128, V128, vecshiftL16, 8985 asm#"2", ".4s", ".8h", 8986 [(set (v4i32 V128:$Rd), 8987 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 8988 8989 bits<4> imm; 8990 let Inst{19-16} = imm; 8991 } 8992 8993 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8994 V128, V64, vecshiftL32, asm, ".2d", ".2s", 8995 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 8996 bits<5> imm; 8997 let Inst{20-16} = imm; 8998 } 8999 9000 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 9001 V128, V128, vecshiftL32, 9002 asm#"2", ".2d", ".4s", 9003 [(set (v2i64 V128:$Rd), 9004 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 9005 bits<5> imm; 9006 let Inst{20-16} = imm; 9007 } 9008} 9009 9010 9011//--- 9012// Vector load/store 9013//--- 9014// SIMD ldX/stX no-index memory references don't allow the optional 9015// ", #0" constant and handle post-indexing explicitly, so we use 9016// a more specialized parse method for them. Otherwise, it's the same as 9017// the general GPR64sp handling. 9018 9019class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 9020 string asm, dag oops, dag iops, list<dag> pattern> 9021 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 9022 bits<5> Vt; 9023 bits<5> Rn; 9024 let Inst{31} = 0; 9025 let Inst{30} = Q; 9026 let Inst{29-23} = 0b0011000; 9027 let Inst{22} = L; 9028 let Inst{21-16} = 0b000000; 9029 let Inst{15-12} = opcode; 9030 let Inst{11-10} = size; 9031 let Inst{9-5} = Rn; 9032 let Inst{4-0} = Vt; 9033} 9034 9035class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 9036 string asm, dag oops, dag iops> 9037 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 9038 bits<5> Vt; 9039 bits<5> Rn; 9040 bits<5> Xm; 9041 let Inst{31} = 0; 9042 let Inst{30} = Q; 9043 let Inst{29-23} = 0b0011001; 9044 let Inst{22} = L; 9045 let Inst{21} = 0; 9046 let Inst{20-16} = Xm; 9047 let Inst{15-12} = opcode; 9048 let Inst{11-10} = size; 9049 let Inst{9-5} = Rn; 9050 let Inst{4-0} = Vt; 9051} 9052 9053// The immediate form of AdvSIMD post-indexed addressing is encoded with 9054// register post-index addressing from the zero register. 9055multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count, 9056 int Offset, int Size> { 9057 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 9058 // "ld1\t$Vt, [$Rn], #16" 9059 // may get mapped to 9060 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 9061 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9062 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9063 GPR64sp:$Rn, 9064 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9065 XZR), 1>; 9066 9067 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 9068 // "ld1.8b\t$Vt, [$Rn], #16" 9069 // may get mapped to 9070 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 9071 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9072 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9073 GPR64sp:$Rn, 9074 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9075 XZR), 0>; 9076 9077 // E.g. "ld1.8b { v0, v1 }, [x1]" 9078 // "ld1\t$Vt, [$Rn]" 9079 // may get mapped to 9080 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 9081 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9082 (!cast<Instruction>(BaseName # Count # "v" # layout) 9083 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9084 GPR64sp:$Rn), 0>; 9085 9086 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 9087 // "ld1\t$Vt, [$Rn], $Xm" 9088 // may get mapped to 9089 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 9090 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9091 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST") 9092 GPR64sp:$Rn, 9093 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9094 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9095} 9096 9097multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist, 9098 int Offset128, int Offset64, bits<4> opcode> { 9099 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9100 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 9101 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 9102 (ins GPR64sp:$Rn), []>; 9103 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 9104 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 9105 (ins GPR64sp:$Rn), []>; 9106 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 9107 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 9108 (ins GPR64sp:$Rn), []>; 9109 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 9110 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 9111 (ins GPR64sp:$Rn), []>; 9112 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 9113 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 9114 (ins GPR64sp:$Rn), []>; 9115 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 9116 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 9117 (ins GPR64sp:$Rn), []>; 9118 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 9119 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 9120 (ins GPR64sp:$Rn), []>; 9121 9122 9123 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 9124 (outs GPR64sp:$wback, 9125 !cast<RegisterOperand>(veclist # "16b"):$Vt), 9126 (ins GPR64sp:$Rn, 9127 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9128 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 9129 (outs GPR64sp:$wback, 9130 !cast<RegisterOperand>(veclist # "8h"):$Vt), 9131 (ins GPR64sp:$Rn, 9132 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9133 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 9134 (outs GPR64sp:$wback, 9135 !cast<RegisterOperand>(veclist # "4s"):$Vt), 9136 (ins GPR64sp:$Rn, 9137 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9138 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 9139 (outs GPR64sp:$wback, 9140 !cast<RegisterOperand>(veclist # "2d"):$Vt), 9141 (ins GPR64sp:$Rn, 9142 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9143 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 9144 (outs GPR64sp:$wback, 9145 !cast<RegisterOperand>(veclist # "8b"):$Vt), 9146 (ins GPR64sp:$Rn, 9147 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9148 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 9149 (outs GPR64sp:$wback, 9150 !cast<RegisterOperand>(veclist # "4h"):$Vt), 9151 (ins GPR64sp:$Rn, 9152 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9153 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 9154 (outs GPR64sp:$wback, 9155 !cast<RegisterOperand>(veclist # "2s"):$Vt), 9156 (ins GPR64sp:$Rn, 9157 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9158 } 9159 9160 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9161 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9162 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9163 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9164 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9165 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9166 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9167} 9168 9169// Only ld1/st1 has a v1d version. 9170multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist, 9171 int Offset128, int Offset64, bits<4> opcode> { 9172 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 9173 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 9174 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9175 GPR64sp:$Rn), []>; 9176 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 9177 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9178 GPR64sp:$Rn), []>; 9179 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 9180 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9181 GPR64sp:$Rn), []>; 9182 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 9183 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9184 GPR64sp:$Rn), []>; 9185 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 9186 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9187 GPR64sp:$Rn), []>; 9188 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 9189 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9190 GPR64sp:$Rn), []>; 9191 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 9192 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9193 GPR64sp:$Rn), []>; 9194 9195 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 9196 (outs GPR64sp:$wback), 9197 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 9198 GPR64sp:$Rn, 9199 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9200 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 9201 (outs GPR64sp:$wback), 9202 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 9203 GPR64sp:$Rn, 9204 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9205 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 9206 (outs GPR64sp:$wback), 9207 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 9208 GPR64sp:$Rn, 9209 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9210 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 9211 (outs GPR64sp:$wback), 9212 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 9213 GPR64sp:$Rn, 9214 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 9215 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 9216 (outs GPR64sp:$wback), 9217 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 9218 GPR64sp:$Rn, 9219 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9220 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 9221 (outs GPR64sp:$wback), 9222 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 9223 GPR64sp:$Rn, 9224 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9225 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 9226 (outs GPR64sp:$wback), 9227 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 9228 GPR64sp:$Rn, 9229 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9230 } 9231 9232 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>; 9233 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>; 9234 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>; 9235 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>; 9236 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>; 9237 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>; 9238 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>; 9239} 9240 9241multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist, 9242 int Offset128, int Offset64, bits<4> opcode> 9243 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9244 9245 // LD1 instructions have extra "1d" variants. 9246 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 9247 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 9248 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 9249 (ins GPR64sp:$Rn), []>; 9250 9251 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 9252 (outs GPR64sp:$wback, 9253 !cast<RegisterOperand>(veclist # "1d"):$Vt), 9254 (ins GPR64sp:$Rn, 9255 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9256 } 9257 9258 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9259} 9260 9261multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist, 9262 int Offset128, int Offset64, bits<4> opcode> 9263 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> { 9264 9265 // ST1 instructions have extra "1d" variants. 9266 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 9267 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 9268 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9269 GPR64sp:$Rn), []>; 9270 9271 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 9272 (outs GPR64sp:$wback), 9273 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 9274 GPR64sp:$Rn, 9275 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 9276 } 9277 9278 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>; 9279} 9280 9281multiclass SIMDLd1Multiple<string asm> { 9282 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9283 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9284 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9285 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9286} 9287 9288multiclass SIMDSt1Multiple<string asm> { 9289 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>; 9290 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>; 9291 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>; 9292 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>; 9293} 9294 9295multiclass SIMDLd2Multiple<string asm> { 9296 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9297} 9298 9299multiclass SIMDSt2Multiple<string asm> { 9300 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>; 9301} 9302 9303multiclass SIMDLd3Multiple<string asm> { 9304 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9305} 9306 9307multiclass SIMDSt3Multiple<string asm> { 9308 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>; 9309} 9310 9311multiclass SIMDLd4Multiple<string asm> { 9312 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9313} 9314 9315multiclass SIMDSt4Multiple<string asm> { 9316 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>; 9317} 9318 9319//--- 9320// AdvSIMD Load/store single-element 9321//--- 9322 9323class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 9324 string asm, string operands, string cst, 9325 dag oops, dag iops, list<dag> pattern> 9326 : I<oops, iops, asm, operands, cst, pattern> { 9327 bits<5> Vt; 9328 bits<5> Rn; 9329 let Inst{31} = 0; 9330 let Inst{29-24} = 0b001101; 9331 let Inst{22} = L; 9332 let Inst{21} = R; 9333 let Inst{15-13} = opcode; 9334 let Inst{9-5} = Rn; 9335 let Inst{4-0} = Vt; 9336} 9337 9338class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 9339 string asm, string operands, string cst, 9340 dag oops, dag iops, list<dag> pattern> 9341 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 9342 bits<5> Vt; 9343 bits<5> Rn; 9344 let Inst{31} = 0; 9345 let Inst{29-24} = 0b001101; 9346 let Inst{22} = L; 9347 let Inst{21} = R; 9348 let Inst{15-13} = opcode; 9349 let Inst{9-5} = Rn; 9350 let Inst{4-0} = Vt; 9351} 9352 9353 9354let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9355class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 9356 DAGOperand listtype> 9357 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 9358 (outs listtype:$Vt), (ins GPR64sp:$Rn), 9359 []> { 9360 let Inst{30} = Q; 9361 let Inst{23} = 0; 9362 let Inst{20-16} = 0b00000; 9363 let Inst{12} = S; 9364 let Inst{11-10} = size; 9365} 9366let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9367class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 9368 string asm, DAGOperand listtype, DAGOperand GPR64pi> 9369 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 9370 "$Rn = $wback", 9371 (outs GPR64sp:$wback, listtype:$Vt), 9372 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 9373 bits<5> Xm; 9374 let Inst{30} = Q; 9375 let Inst{23} = 1; 9376 let Inst{20-16} = Xm; 9377 let Inst{12} = S; 9378 let Inst{11-10} = size; 9379} 9380 9381multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count, 9382 int Offset, int Size> { 9383 // E.g. "ld1r { v0.8b }, [x1], #1" 9384 // "ld1r.8b\t$Vt, [$Rn], #1" 9385 // may get mapped to 9386 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9387 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 9388 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9389 GPR64sp:$Rn, 9390 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9391 XZR), 1>; 9392 9393 // E.g. "ld1r.8b { v0 }, [x1], #1" 9394 // "ld1r.8b\t$Vt, [$Rn], #1" 9395 // may get mapped to 9396 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9397 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 9398 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9399 GPR64sp:$Rn, 9400 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9401 XZR), 0>; 9402 9403 // E.g. "ld1r.8b { v0 }, [x1]" 9404 // "ld1r.8b\t$Vt, [$Rn]" 9405 // may get mapped to 9406 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9407 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 9408 (!cast<Instruction>(BaseName # "v" # layout) 9409 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9410 GPR64sp:$Rn), 0>; 9411 9412 // E.g. "ld1r.8b { v0 }, [x1], x2" 9413 // "ld1r.8b\t$Vt, [$Rn], $Xm" 9414 // may get mapped to 9415 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9416 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 9417 (!cast<Instruction>(BaseName # "v" # layout # "_POST") 9418 GPR64sp:$Rn, 9419 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 9420 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9421} 9422 9423multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 9424 int Offset1, int Offset2, int Offset4, int Offset8> { 9425 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 9426 !cast<DAGOperand>("VecList" # Count # "8b")>; 9427 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 9428 !cast<DAGOperand>("VecList" # Count #"16b")>; 9429 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 9430 !cast<DAGOperand>("VecList" # Count #"4h")>; 9431 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 9432 !cast<DAGOperand>("VecList" # Count #"8h")>; 9433 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 9434 !cast<DAGOperand>("VecList" # Count #"2s")>; 9435 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 9436 !cast<DAGOperand>("VecList" # Count #"4s")>; 9437 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 9438 !cast<DAGOperand>("VecList" # Count #"1d")>; 9439 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 9440 !cast<DAGOperand>("VecList" # Count #"2d")>; 9441 9442 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 9443 !cast<DAGOperand>("VecList" # Count # "8b"), 9444 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9445 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 9446 !cast<DAGOperand>("VecList" # Count # "16b"), 9447 !cast<DAGOperand>("GPR64pi" # Offset1)>; 9448 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 9449 !cast<DAGOperand>("VecList" # Count # "4h"), 9450 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9451 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 9452 !cast<DAGOperand>("VecList" # Count # "8h"), 9453 !cast<DAGOperand>("GPR64pi" # Offset2)>; 9454 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 9455 !cast<DAGOperand>("VecList" # Count # "2s"), 9456 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9457 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 9458 !cast<DAGOperand>("VecList" # Count # "4s"), 9459 !cast<DAGOperand>("GPR64pi" # Offset4)>; 9460 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 9461 !cast<DAGOperand>("VecList" # Count # "1d"), 9462 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9463 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 9464 !cast<DAGOperand>("VecList" # Count # "2d"), 9465 !cast<DAGOperand>("GPR64pi" # Offset8)>; 9466 9467 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>; 9468 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>; 9469 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>; 9470 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>; 9471 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>; 9472 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>; 9473 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>; 9474 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>; 9475} 9476 9477class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 9478 dag oops, dag iops, list<dag> pattern> 9479 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9480 pattern> { 9481 // idx encoded in Q:S:size fields. 9482 bits<4> idx; 9483 let Inst{30} = idx{3}; 9484 let Inst{23} = 0; 9485 let Inst{20-16} = 0b00000; 9486 let Inst{12} = idx{2}; 9487 let Inst{11-10} = idx{1-0}; 9488} 9489class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 9490 dag oops, dag iops, list<dag> pattern> 9491 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9492 oops, iops, pattern> { 9493 // idx encoded in Q:S:size fields. 9494 bits<4> idx; 9495 let Inst{30} = idx{3}; 9496 let Inst{23} = 0; 9497 let Inst{20-16} = 0b00000; 9498 let Inst{12} = idx{2}; 9499 let Inst{11-10} = idx{1-0}; 9500} 9501class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 9502 dag oops, dag iops> 9503 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9504 "$Rn = $wback", oops, iops, []> { 9505 // idx encoded in Q:S:size fields. 9506 bits<4> idx; 9507 bits<5> Xm; 9508 let Inst{30} = idx{3}; 9509 let Inst{23} = 1; 9510 let Inst{20-16} = Xm; 9511 let Inst{12} = idx{2}; 9512 let Inst{11-10} = idx{1-0}; 9513} 9514class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 9515 dag oops, dag iops> 9516 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9517 "$Rn = $wback", oops, iops, []> { 9518 // idx encoded in Q:S:size fields. 9519 bits<4> idx; 9520 bits<5> Xm; 9521 let Inst{30} = idx{3}; 9522 let Inst{23} = 1; 9523 let Inst{20-16} = Xm; 9524 let Inst{12} = idx{2}; 9525 let Inst{11-10} = idx{1-0}; 9526} 9527 9528class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 9529 dag oops, dag iops, list<dag> pattern> 9530 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9531 pattern> { 9532 // idx encoded in Q:S:size<1> fields. 9533 bits<3> idx; 9534 let Inst{30} = idx{2}; 9535 let Inst{23} = 0; 9536 let Inst{20-16} = 0b00000; 9537 let Inst{12} = idx{1}; 9538 let Inst{11} = idx{0}; 9539 let Inst{10} = size; 9540} 9541class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 9542 dag oops, dag iops, list<dag> pattern> 9543 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9544 oops, iops, pattern> { 9545 // idx encoded in Q:S:size<1> fields. 9546 bits<3> idx; 9547 let Inst{30} = idx{2}; 9548 let Inst{23} = 0; 9549 let Inst{20-16} = 0b00000; 9550 let Inst{12} = idx{1}; 9551 let Inst{11} = idx{0}; 9552 let Inst{10} = size; 9553} 9554 9555class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 9556 dag oops, dag iops> 9557 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9558 "$Rn = $wback", oops, iops, []> { 9559 // idx encoded in Q:S:size<1> fields. 9560 bits<3> idx; 9561 bits<5> Xm; 9562 let Inst{30} = idx{2}; 9563 let Inst{23} = 1; 9564 let Inst{20-16} = Xm; 9565 let Inst{12} = idx{1}; 9566 let Inst{11} = idx{0}; 9567 let Inst{10} = size; 9568} 9569class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 9570 dag oops, dag iops> 9571 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9572 "$Rn = $wback", oops, iops, []> { 9573 // idx encoded in Q:S:size<1> fields. 9574 bits<3> idx; 9575 bits<5> Xm; 9576 let Inst{30} = idx{2}; 9577 let Inst{23} = 1; 9578 let Inst{20-16} = Xm; 9579 let Inst{12} = idx{1}; 9580 let Inst{11} = idx{0}; 9581 let Inst{10} = size; 9582} 9583class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9584 dag oops, dag iops, list<dag> pattern> 9585 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9586 pattern> { 9587 // idx encoded in Q:S fields. 9588 bits<2> idx; 9589 let Inst{30} = idx{1}; 9590 let Inst{23} = 0; 9591 let Inst{20-16} = 0b00000; 9592 let Inst{12} = idx{0}; 9593 let Inst{11-10} = size; 9594} 9595class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9596 dag oops, dag iops, list<dag> pattern> 9597 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9598 oops, iops, pattern> { 9599 // idx encoded in Q:S fields. 9600 bits<2> idx; 9601 let Inst{30} = idx{1}; 9602 let Inst{23} = 0; 9603 let Inst{20-16} = 0b00000; 9604 let Inst{12} = idx{0}; 9605 let Inst{11-10} = size; 9606} 9607class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 9608 string asm, dag oops, dag iops> 9609 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9610 "$Rn = $wback", oops, iops, []> { 9611 // idx encoded in Q:S fields. 9612 bits<2> idx; 9613 bits<5> Xm; 9614 let Inst{30} = idx{1}; 9615 let Inst{23} = 1; 9616 let Inst{20-16} = Xm; 9617 let Inst{12} = idx{0}; 9618 let Inst{11-10} = size; 9619} 9620class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 9621 string asm, dag oops, dag iops> 9622 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9623 "$Rn = $wback", oops, iops, []> { 9624 // idx encoded in Q:S fields. 9625 bits<2> idx; 9626 bits<5> Xm; 9627 let Inst{30} = idx{1}; 9628 let Inst{23} = 1; 9629 let Inst{20-16} = Xm; 9630 let Inst{12} = idx{0}; 9631 let Inst{11-10} = size; 9632} 9633class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9634 dag oops, dag iops, list<dag> pattern> 9635 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 9636 pattern> { 9637 // idx encoded in Q field. 9638 bits<1> idx; 9639 let Inst{30} = idx; 9640 let Inst{23} = 0; 9641 let Inst{20-16} = 0b00000; 9642 let Inst{12} = 0; 9643 let Inst{11-10} = size; 9644} 9645class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 9646 dag oops, dag iops, list<dag> pattern> 9647 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 9648 oops, iops, pattern> { 9649 // idx encoded in Q field. 9650 bits<1> idx; 9651 let Inst{30} = idx; 9652 let Inst{23} = 0; 9653 let Inst{20-16} = 0b00000; 9654 let Inst{12} = 0; 9655 let Inst{11-10} = size; 9656} 9657class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 9658 string asm, dag oops, dag iops> 9659 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9660 "$Rn = $wback", oops, iops, []> { 9661 // idx encoded in Q field. 9662 bits<1> idx; 9663 bits<5> Xm; 9664 let Inst{30} = idx; 9665 let Inst{23} = 1; 9666 let Inst{20-16} = Xm; 9667 let Inst{12} = 0; 9668 let Inst{11-10} = size; 9669} 9670class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 9671 string asm, dag oops, dag iops> 9672 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 9673 "$Rn = $wback", oops, iops, []> { 9674 // idx encoded in Q field. 9675 bits<1> idx; 9676 bits<5> Xm; 9677 let Inst{30} = idx; 9678 let Inst{23} = 1; 9679 let Inst{20-16} = Xm; 9680 let Inst{12} = 0; 9681 let Inst{11-10} = size; 9682} 9683 9684let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9685multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 9686 RegisterOperand listtype, 9687 RegisterOperand GPR64pi> { 9688 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 9689 (outs listtype:$dst), 9690 (ins listtype:$Vt, VectorIndexB:$idx, 9691 GPR64sp:$Rn), []>; 9692 9693 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 9694 (outs GPR64sp:$wback, listtype:$dst), 9695 (ins listtype:$Vt, VectorIndexB:$idx, 9696 GPR64sp:$Rn, GPR64pi:$Xm)>; 9697} 9698let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9699multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 9700 RegisterOperand listtype, 9701 RegisterOperand GPR64pi> { 9702 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 9703 (outs listtype:$dst), 9704 (ins listtype:$Vt, VectorIndexH:$idx, 9705 GPR64sp:$Rn), []>; 9706 9707 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 9708 (outs GPR64sp:$wback, listtype:$dst), 9709 (ins listtype:$Vt, VectorIndexH:$idx, 9710 GPR64sp:$Rn, GPR64pi:$Xm)>; 9711} 9712let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9713multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 9714 RegisterOperand listtype, 9715 RegisterOperand GPR64pi> { 9716 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 9717 (outs listtype:$dst), 9718 (ins listtype:$Vt, VectorIndexS:$idx, 9719 GPR64sp:$Rn), []>; 9720 9721 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 9722 (outs GPR64sp:$wback, listtype:$dst), 9723 (ins listtype:$Vt, VectorIndexS:$idx, 9724 GPR64sp:$Rn, GPR64pi:$Xm)>; 9725} 9726let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 9727multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 9728 RegisterOperand listtype, RegisterOperand GPR64pi> { 9729 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 9730 (outs listtype:$dst), 9731 (ins listtype:$Vt, VectorIndexD:$idx, 9732 GPR64sp:$Rn), []>; 9733 9734 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 9735 (outs GPR64sp:$wback, listtype:$dst), 9736 (ins listtype:$Vt, VectorIndexD:$idx, 9737 GPR64sp:$Rn, GPR64pi:$Xm)>; 9738} 9739let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9740multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 9741 RegisterOperand listtype, RegisterOperand GPR64pi> { 9742 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 9743 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 9744 GPR64sp:$Rn), []>; 9745 9746 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 9747 (outs GPR64sp:$wback), 9748 (ins listtype:$Vt, VectorIndexB:$idx, 9749 GPR64sp:$Rn, GPR64pi:$Xm)>; 9750} 9751let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9752multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 9753 RegisterOperand listtype, RegisterOperand GPR64pi> { 9754 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 9755 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 9756 GPR64sp:$Rn), []>; 9757 9758 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 9759 (outs GPR64sp:$wback), 9760 (ins listtype:$Vt, VectorIndexH:$idx, 9761 GPR64sp:$Rn, GPR64pi:$Xm)>; 9762} 9763let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9764multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 9765 RegisterOperand listtype, RegisterOperand GPR64pi> { 9766 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 9767 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 9768 GPR64sp:$Rn), []>; 9769 9770 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 9771 (outs GPR64sp:$wback), 9772 (ins listtype:$Vt, VectorIndexS:$idx, 9773 GPR64sp:$Rn, GPR64pi:$Xm)>; 9774} 9775let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 9776multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 9777 RegisterOperand listtype, RegisterOperand GPR64pi> { 9778 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 9779 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 9780 GPR64sp:$Rn), []>; 9781 9782 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 9783 (outs GPR64sp:$wback), 9784 (ins listtype:$Vt, VectorIndexD:$idx, 9785 GPR64sp:$Rn, GPR64pi:$Xm)>; 9786} 9787 9788multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 9789 string Count, int Offset, Operand idxtype> { 9790 // E.g. "ld1 { v0.8b }[0], [x1], #1" 9791 // "ld1\t$Vt, [$Rn], #1" 9792 // may get mapped to 9793 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 9794 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 9795 (!cast<Instruction>(NAME # Type # "_POST") 9796 GPR64sp:$Rn, 9797 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9798 idxtype:$idx, XZR), 1>; 9799 9800 // E.g. "ld1.8b { v0 }[0], [x1], #1" 9801 // "ld1.8b\t$Vt, [$Rn], #1" 9802 // may get mapped to 9803 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9804 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 9805 (!cast<Instruction>(NAME # Type # "_POST") 9806 GPR64sp:$Rn, 9807 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9808 idxtype:$idx, XZR), 0>; 9809 9810 // E.g. "ld1.8b { v0 }[0], [x1]" 9811 // "ld1.8b\t$Vt, [$Rn]" 9812 // may get mapped to 9813 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9814 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 9815 (!cast<Instruction>(NAME # Type) 9816 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9817 idxtype:$idx, GPR64sp:$Rn), 0>; 9818 9819 // E.g. "ld1.8b { v0 }[0], [x1], x2" 9820 // "ld1.8b\t$Vt, [$Rn], $Xm" 9821 // may get mapped to 9822 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9823 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 9824 (!cast<Instruction>(NAME # Type # "_POST") 9825 GPR64sp:$Rn, 9826 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9827 idxtype:$idx, 9828 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9829} 9830 9831multiclass SIMDLdSt1SingleAliases<string asm> { 9832 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 9833 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 9834 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 9835 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 9836} 9837 9838multiclass SIMDLdSt2SingleAliases<string asm> { 9839 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 9840 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 9841 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 9842 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 9843} 9844 9845multiclass SIMDLdSt3SingleAliases<string asm> { 9846 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 9847 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 9848 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 9849 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 9850} 9851 9852multiclass SIMDLdSt4SingleAliases<string asm> { 9853 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 9854 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 9855 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 9856 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 9857} 9858} // end of 'let Predicates = [HasNEON]' 9859 9860//---------------------------------------------------------------------------- 9861// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 9862//---------------------------------------------------------------------------- 9863 9864let Predicates = [HasNEON, HasRDM] in { 9865 9866class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 9867 RegisterOperand regtype, string asm, 9868 string kind, list<dag> pattern> 9869 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 9870 pattern> { 9871} 9872multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 9873 SDPatternOperator Accum> { 9874 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 9875 [(set (v4i16 V64:$dst), 9876 (Accum (v4i16 V64:$Rd), 9877 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 9878 (v4i16 V64:$Rm)))))]>; 9879 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 9880 [(set (v8i16 V128:$dst), 9881 (Accum (v8i16 V128:$Rd), 9882 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 9883 (v8i16 V128:$Rm)))))]>; 9884 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 9885 [(set (v2i32 V64:$dst), 9886 (Accum (v2i32 V64:$Rd), 9887 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 9888 (v2i32 V64:$Rm)))))]>; 9889 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 9890 [(set (v4i32 V128:$dst), 9891 (Accum (v4i32 V128:$Rd), 9892 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 9893 (v4i32 V128:$Rm)))))]>; 9894} 9895 9896multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 9897 SDPatternOperator Accum> { 9898 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9899 V64, V64, V128_lo, VectorIndexH, 9900 asm, ".4h", ".4h", ".4h", ".h", 9901 [(set (v4i16 V64:$dst), 9902 (Accum (v4i16 V64:$Rd), 9903 (v4i16 (int_aarch64_neon_sqrdmulh 9904 (v4i16 V64:$Rn), 9905 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9906 VectorIndexH:$idx))))))]> { 9907 bits<3> idx; 9908 let Inst{11} = idx{2}; 9909 let Inst{21} = idx{1}; 9910 let Inst{20} = idx{0}; 9911 } 9912 9913 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9914 V128, V128, V128_lo, VectorIndexH, 9915 asm, ".8h", ".8h", ".8h", ".h", 9916 [(set (v8i16 V128:$dst), 9917 (Accum (v8i16 V128:$Rd), 9918 (v8i16 (int_aarch64_neon_sqrdmulh 9919 (v8i16 V128:$Rn), 9920 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9921 VectorIndexH:$idx))))))]> { 9922 bits<3> idx; 9923 let Inst{11} = idx{2}; 9924 let Inst{21} = idx{1}; 9925 let Inst{20} = idx{0}; 9926 } 9927 9928 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9929 V64, V64, V128, VectorIndexS, 9930 asm, ".2s", ".2s", ".2s", ".s", 9931 [(set (v2i32 V64:$dst), 9932 (Accum (v2i32 V64:$Rd), 9933 (v2i32 (int_aarch64_neon_sqrdmulh 9934 (v2i32 V64:$Rn), 9935 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 9936 VectorIndexS:$idx))))))]> { 9937 bits<2> idx; 9938 let Inst{11} = idx{1}; 9939 let Inst{21} = idx{0}; 9940 } 9941 9942 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 9943 // an intermediate EXTRACT_SUBREG would be untyped. 9944 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 9945 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 9946 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9947 (i32 (vector_extract 9948 (v4i32 (insert_subvector 9949 (undef), 9950 (v2i32 (int_aarch64_neon_sqrdmulh 9951 (v2i32 V64:$Rn), 9952 (v2i32 (AArch64duplane32 9953 (v4i32 V128:$Rm), 9954 VectorIndexS:$idx)))), 9955 (i32 0))), 9956 (i64 0))))), 9957 (EXTRACT_SUBREG 9958 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 9959 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 9960 FPR32Op:$Rd, 9961 ssub)), 9962 V64:$Rn, 9963 V128:$Rm, 9964 VectorIndexS:$idx)), 9965 ssub)>; 9966 9967 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9968 V128, V128, V128, VectorIndexS, 9969 asm, ".4s", ".4s", ".4s", ".s", 9970 [(set (v4i32 V128:$dst), 9971 (Accum (v4i32 V128:$Rd), 9972 (v4i32 (int_aarch64_neon_sqrdmulh 9973 (v4i32 V128:$Rn), 9974 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 9975 VectorIndexS:$idx))))))]> { 9976 bits<2> idx; 9977 let Inst{11} = idx{1}; 9978 let Inst{21} = idx{0}; 9979 } 9980 9981 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 9982 // an intermediate EXTRACT_SUBREG would be untyped. 9983 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9984 (i32 (vector_extract 9985 (v4i32 (int_aarch64_neon_sqrdmulh 9986 (v4i32 V128:$Rn), 9987 (v4i32 (AArch64duplane32 9988 (v4i32 V128:$Rm), 9989 VectorIndexS:$idx)))), 9990 (i64 0))))), 9991 (EXTRACT_SUBREG 9992 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 9993 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 9994 FPR32Op:$Rd, 9995 ssub)), 9996 V128:$Rn, 9997 V128:$Rm, 9998 VectorIndexS:$idx)), 9999 ssub)>; 10000 10001 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 10002 FPR16Op, FPR16Op, V128_lo, 10003 VectorIndexH, asm, ".h", "", "", ".h", 10004 []> { 10005 bits<3> idx; 10006 let Inst{11} = idx{2}; 10007 let Inst{21} = idx{1}; 10008 let Inst{20} = idx{0}; 10009 } 10010 10011 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 10012 FPR32Op, FPR32Op, V128, VectorIndexS, 10013 asm, ".s", "", "", ".s", 10014 [(set (i32 FPR32Op:$dst), 10015 (Accum (i32 FPR32Op:$Rd), 10016 (i32 (int_aarch64_neon_sqrdmulh 10017 (i32 FPR32Op:$Rn), 10018 (i32 (vector_extract (v4i32 V128:$Rm), 10019 VectorIndexS:$idx))))))]> { 10020 bits<2> idx; 10021 let Inst{11} = idx{1}; 10022 let Inst{21} = idx{0}; 10023 } 10024} 10025} // let Predicates = [HasNeon, HasRDM] 10026 10027//---------------------------------------------------------------------------- 10028// ARMv8.3 Complex ADD/MLA instructions 10029//---------------------------------------------------------------------------- 10030 10031class ComplexRotationOperand<int Angle, int Remainder, string Type> 10032 : AsmOperandClass { 10033 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">"; 10034 let DiagnosticType = "InvalidComplexRotation" # Type; 10035 let Name = "ComplexRotation" # Type; 10036} 10037def complexrotateop : Operand<i32> { 10038 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">; 10039 let PrintMethod = "printComplexRotationOp<90, 0>"; 10040} 10041def complexrotateopodd : Operand<i32> { 10042 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">; 10043 let PrintMethod = "printComplexRotationOp<180, 90>"; 10044} 10045 10046let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10047class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode, 10048 RegisterOperand regtype, Operand rottype, 10049 string asm, string kind, list<dag> pattern> 10050 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10051 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10052 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>, 10053 Sched<[WriteV]> { 10054 bits<5> Rd; 10055 bits<5> Rn; 10056 bits<5> Rm; 10057 bits<1> rot; 10058 let Inst{31} = 0; 10059 let Inst{30} = Q; 10060 let Inst{29} = U; 10061 let Inst{28-24} = 0b01110; 10062 let Inst{23-22} = size; 10063 let Inst{21} = 0; 10064 let Inst{20-16} = Rm; 10065 let Inst{15-13} = opcode; 10066 // Non-tied version (FCADD) only has one rotation bit 10067 let Inst{12} = rot; 10068 let Inst{11} = 0; 10069 let Inst{10} = 1; 10070 let Inst{9-5} = Rn; 10071 let Inst{4-0} = Rd; 10072} 10073 10074//8.3 CompNum - Floating-point complex number support 10075multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype, 10076 string asm, SDPatternOperator OpNode>{ 10077 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10078 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype, 10079 asm, ".4h", 10080 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10081 (v4f16 V64:$Rn), 10082 (v4f16 V64:$Rm), 10083 (rottype i32:$rot)))]>; 10084 10085 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype, 10086 asm, ".8h", 10087 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10088 (v8f16 V128:$Rn), 10089 (v8f16 V128:$Rm), 10090 (rottype i32:$rot)))]>; 10091 } 10092 10093 let Predicates = [HasComplxNum, HasNEON] in { 10094 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype, 10095 asm, ".2s", 10096 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10097 (v2f32 V64:$Rn), 10098 (v2f32 V64:$Rm), 10099 (rottype i32:$rot)))]>; 10100 10101 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype, 10102 asm, ".4s", 10103 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10104 (v4f32 V128:$Rn), 10105 (v4f32 V128:$Rm), 10106 (rottype i32:$rot)))]>; 10107 10108 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype, 10109 asm, ".2d", 10110 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10111 (v2f64 V128:$Rn), 10112 (v2f64 V128:$Rm), 10113 (rottype i32:$rot)))]>; 10114 } 10115} 10116 10117let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10118class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size, 10119 bits<3> opcode, 10120 RegisterOperand regtype, 10121 Operand rottype, string asm, 10122 string kind, list<dag> pattern> 10123 : I<(outs regtype:$dst), 10124 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm, 10125 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot" 10126 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>, 10127 Sched<[WriteV]> { 10128 bits<5> Rd; 10129 bits<5> Rn; 10130 bits<5> Rm; 10131 bits<2> rot; 10132 let Inst{31} = 0; 10133 let Inst{30} = Q; 10134 let Inst{29} = U; 10135 let Inst{28-24} = 0b01110; 10136 let Inst{23-22} = size; 10137 let Inst{21} = 0; 10138 let Inst{20-16} = Rm; 10139 let Inst{15-13} = opcode; 10140 let Inst{12-11} = rot; 10141 let Inst{10} = 1; 10142 let Inst{9-5} = Rn; 10143 let Inst{4-0} = Rd; 10144} 10145 10146multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode, 10147 Operand rottype, string asm, 10148 SDPatternOperator OpNode> { 10149 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10150 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64, 10151 rottype, asm, ".4h", 10152 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd), 10153 (v4f16 V64:$Rn), 10154 (v4f16 V64:$Rm), 10155 (rottype i32:$rot)))]>; 10156 10157 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128, 10158 rottype, asm, ".8h", 10159 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd), 10160 (v8f16 V128:$Rn), 10161 (v8f16 V128:$Rm), 10162 (rottype i32:$rot)))]>; 10163 } 10164 10165 let Predicates = [HasComplxNum, HasNEON] in { 10166 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64, 10167 rottype, asm, ".2s", 10168 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd), 10169 (v2f32 V64:$Rn), 10170 (v2f32 V64:$Rm), 10171 (rottype i32:$rot)))]>; 10172 10173 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128, 10174 rottype, asm, ".4s", 10175 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd), 10176 (v4f32 V128:$Rn), 10177 (v4f32 V128:$Rm), 10178 (rottype i32:$rot)))]>; 10179 10180 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128, 10181 rottype, asm, ".2d", 10182 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd), 10183 (v2f64 V128:$Rn), 10184 (v2f64 V128:$Rm), 10185 (rottype i32:$rot)))]>; 10186 } 10187} 10188 10189let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10190class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size, 10191 bit opc1, bit opc2, RegisterOperand dst_reg, 10192 RegisterOperand lhs_reg, 10193 RegisterOperand rhs_reg, Operand vec_idx, 10194 Operand rottype, string asm, string apple_kind, 10195 string dst_kind, string lhs_kind, 10196 string rhs_kind, list<dag> pattern> 10197 : I<(outs dst_reg:$dst), 10198 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot), 10199 asm, 10200 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # 10201 "$idx, $rot" # "|" # apple_kind # 10202 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>, 10203 Sched<[WriteV]> { 10204 bits<5> Rd; 10205 bits<5> Rn; 10206 bits<5> Rm; 10207 bits<2> rot; 10208 10209 let Inst{31} = 0; 10210 let Inst{30} = Q; 10211 let Inst{29} = U; 10212 let Inst{28} = Scalar; 10213 let Inst{27-24} = 0b1111; 10214 let Inst{23-22} = size; 10215 // Bit 21 must be set by the derived class. 10216 let Inst{20-16} = Rm; 10217 let Inst{15} = opc1; 10218 let Inst{14-13} = rot; 10219 let Inst{12} = opc2; 10220 // Bit 11 must be set by the derived class. 10221 let Inst{10} = 0; 10222 let Inst{9-5} = Rn; 10223 let Inst{4-0} = Rd; 10224} 10225 10226// The complex instructions index by pairs of elements, so the VectorIndexes 10227// don't match the lane types, and the index bits are different to the other 10228// classes. 10229multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype, 10230 string asm, SDPatternOperator OpNode> { 10231 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in { 10232 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64, 10233 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h", 10234 ".4h", ".h", []> { 10235 bits<1> idx; 10236 let Inst{11} = 0; 10237 let Inst{21} = idx{0}; 10238 } 10239 10240 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2, 10241 V128, V128, V128, VectorIndexS, rottype, asm, ".8h", 10242 ".8h", ".8h", ".h", []> { 10243 bits<2> idx; 10244 let Inst{11} = idx{1}; 10245 let Inst{21} = idx{0}; 10246 } 10247 } // Predicates = HasComplxNum, HasNEON, HasFullFP16] 10248 10249 let Predicates = [HasComplxNum, HasNEON] in { 10250 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2, 10251 V128, V128, V128, VectorIndexD, rottype, asm, ".4s", 10252 ".4s", ".4s", ".s", []> { 10253 bits<1> idx; 10254 let Inst{11} = idx{0}; 10255 let Inst{21} = 0; 10256 } 10257 } // Predicates = [HasComplxNum, HasNEON] 10258} 10259 10260//---------------------------------------------------------------------------- 10261// Crypto extensions 10262//---------------------------------------------------------------------------- 10263 10264let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10265class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 10266 list<dag> pat> 10267 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 10268 Sched<[WriteV]>{ 10269 bits<5> Rd; 10270 bits<5> Rn; 10271 let Inst{31-16} = 0b0100111000101000; 10272 let Inst{15-12} = opc; 10273 let Inst{11-10} = 0b10; 10274 let Inst{9-5} = Rn; 10275 let Inst{4-0} = Rd; 10276} 10277 10278class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 10279 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 10280 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 10281 10282class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 10283 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 10284 "$Rd = $dst", 10285 [(set (v16i8 V128:$dst), 10286 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 10287 10288let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10289class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 10290 dag oops, dag iops, list<dag> pat> 10291 : I<oops, iops, asm, 10292 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 10293 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 10294 Sched<[WriteV]>{ 10295 bits<5> Rd; 10296 bits<5> Rn; 10297 bits<5> Rm; 10298 let Inst{31-21} = 0b01011110000; 10299 let Inst{20-16} = Rm; 10300 let Inst{15} = 0; 10301 let Inst{14-12} = opc; 10302 let Inst{11-10} = 0b00; 10303 let Inst{9-5} = Rn; 10304 let Inst{4-0} = Rd; 10305} 10306 10307class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 10308 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10309 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 10310 [(set (v4i32 FPR128:$dst), 10311 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 10312 (v4i32 V128:$Rm)))]>; 10313 10314class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 10315 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 10316 (ins V128:$Rd, V128:$Rn, V128:$Rm), 10317 [(set (v4i32 V128:$dst), 10318 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 10319 (v4i32 V128:$Rm)))]>; 10320 10321class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 10322 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 10323 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 10324 [(set (v4i32 FPR128:$dst), 10325 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 10326 (v4i32 V128:$Rm)))]>; 10327 10328let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 10329class SHA2OpInst<bits<4> opc, string asm, string kind, 10330 string cstr, dag oops, dag iops, 10331 list<dag> pat> 10332 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 10333 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 10334 Sched<[WriteV]>{ 10335 bits<5> Rd; 10336 bits<5> Rn; 10337 let Inst{31-16} = 0b0101111000101000; 10338 let Inst{15-12} = opc; 10339 let Inst{11-10} = 0b10; 10340 let Inst{9-5} = Rn; 10341 let Inst{4-0} = Rd; 10342} 10343 10344class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 10345 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 10346 (ins V128:$Rd, V128:$Rn), 10347 [(set (v4i32 V128:$dst), 10348 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 10349 10350class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 10351 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 10352 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 10353 10354// Armv8.2-A Crypto extensions 10355class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst, 10356 list<dag> pattern> 10357 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> { 10358 bits<5> Vd; 10359 bits<5> Vn; 10360 let Inst{31-25} = 0b1100111; 10361 let Inst{9-5} = Vn; 10362 let Inst{4-0} = Vd; 10363} 10364 10365class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops> 10366 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops, 10367 "$Vm = $Vd", []> { 10368 let Inst{31-25} = 0b1100111; 10369 let Inst{24-21} = 0b0110; 10370 let Inst{20-15} = 0b000001; 10371 let Inst{14} = op0; 10372 let Inst{13-12} = 0b00; 10373 let Inst{11-10} = op1; 10374} 10375class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm> 10376 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d}">; 10377class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm> 10378 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s}">; 10379 10380class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm, 10381 string asmops, string cst> 10382 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> { 10383 bits<5> Vm; 10384 let Inst{24-21} = 0b0011; 10385 let Inst{20-16} = Vm; 10386 let Inst{15} = 0b1; 10387 let Inst{14} = op0; 10388 let Inst{13-12} = 0b00; 10389 let Inst{11-10} = op1; 10390} 10391class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm> 10392 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10393 "{\t$Vd.2d, $Vn.2d, $Vm.2d}", "">; 10394class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm> 10395 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10396 "{\t$Vd.2d, $Vn.2d, $Vm.2d}", "$Vd = $Vdst">; 10397class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm> 10398 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, 10399 "{\t$Vd.4s, $Vn.4s, $Vm.4s}", "">; 10400class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm> 10401 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm, 10402 "{\t$Vd.4s, $Vn.4s, $Vm.4s}", "$Vd = $Vdst">; 10403class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm> 10404 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm), 10405 asm, "{\t$Vd, $Vn, $Vm.2d}", "$Vd = $Vdst">; 10406 10407class CryptoRRRR<bits<2>op0, string asm, string asmops> 10408 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm, 10409 asmops, "", []> { 10410 bits<5> Vm; 10411 bits<5> Va; 10412 let Inst{24-23} = 0b00; 10413 let Inst{22-21} = op0; 10414 let Inst{20-16} = Vm; 10415 let Inst{15} = 0b0; 10416 let Inst{14-10} = Va; 10417} 10418class CryptoRRRR_16B<bits<2>op0, string asm> 10419 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b}"> { 10420} 10421class CryptoRRRR_4S<bits<2>op0, string asm> 10422 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s}"> { 10423} 10424 10425class CryptoRRRi6<string asm> 10426 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm, 10427 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm}", "", []> { 10428 bits<6> imm; 10429 bits<5> Vm; 10430 let Inst{24-21} = 0b0100; 10431 let Inst{20-16} = Vm; 10432 let Inst{15-10} = imm; 10433 let Inst{9-5} = Vn; 10434 let Inst{4-0} = Vd; 10435} 10436 10437class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm> 10438 : BaseCryptoV82<(outs V128:$Vdst), 10439 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm), 10440 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm}", "$Vd = $Vdst", []> { 10441 bits<2> imm; 10442 bits<5> Vm; 10443 let Inst{24-21} = 0b0010; 10444 let Inst{20-16} = Vm; 10445 let Inst{15} = 0b1; 10446 let Inst{14} = op0; 10447 let Inst{13-12} = imm; 10448 let Inst{11-10} = op1; 10449} 10450 10451//---------------------------------------------------------------------------- 10452// v8.1 atomic instructions extension: 10453// * CAS 10454// * CASP 10455// * SWP 10456// * LDOPregister<OP>, and aliases STOPregister<OP> 10457 10458// Instruction encodings: 10459// 10460// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 10461// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 10462// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 10463// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 10464// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 10465// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 10466 10467// Instruction syntax: 10468// 10469// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10470// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 10471// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 10472// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 10473// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10474// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 10475// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 10476// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 10477// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 10478// ST<OP>{<order>} <Xs>, [<Xn|SP>] 10479 10480let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 10481class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 10482 string cstr, list<dag> pattern> 10483 : I<oops, iops, asm, operands, cstr, pattern> { 10484 bits<2> Sz; 10485 bit NP; 10486 bit Acq; 10487 bit Rel; 10488 bits<5> Rs; 10489 bits<5> Rn; 10490 bits<5> Rt; 10491 let Inst{31-30} = Sz; 10492 let Inst{29-24} = 0b001000; 10493 let Inst{23} = NP; 10494 let Inst{22} = Acq; 10495 let Inst{21} = 0b1; 10496 let Inst{20-16} = Rs; 10497 let Inst{15} = Rel; 10498 let Inst{14-10} = 0b11111; 10499 let Inst{9-5} = Rn; 10500 let Inst{4-0} = Rt; 10501 let Predicates = [HasLSE]; 10502} 10503 10504class BaseCAS<string order, string size, RegisterClass RC> 10505 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 10506 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 10507 "$out = $Rs",[]>, 10508 Sched<[WriteAtomic]> { 10509 let NP = 1; 10510} 10511 10512multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 10513 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>; 10514 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>; 10515 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>; 10516 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>; 10517} 10518 10519class BaseCASP<string order, string size, RegisterOperand RC> 10520 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 10521 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 10522 "$out = $Rs",[]>, 10523 Sched<[WriteAtomic]> { 10524 let NP = 0; 10525} 10526 10527multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 10528 let Sz = 0b00, Acq = Acq, Rel = Rel in 10529 def W : BaseCASP<order, "", WSeqPairClassOperand>; 10530 let Sz = 0b01, Acq = Acq, Rel = Rel in 10531 def X : BaseCASP<order, "", XSeqPairClassOperand>; 10532} 10533 10534let Predicates = [HasLSE] in 10535class BaseSWP<string order, string size, RegisterClass RC> 10536 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 10537 "\t$Rs, $Rt, [$Rn]","",[]>, 10538 Sched<[WriteAtomic]> { 10539 bits<2> Sz; 10540 bit Acq; 10541 bit Rel; 10542 bits<5> Rs; 10543 bits<3> opc = 0b000; 10544 bits<5> Rn; 10545 bits<5> Rt; 10546 let Inst{31-30} = Sz; 10547 let Inst{29-24} = 0b111000; 10548 let Inst{23} = Acq; 10549 let Inst{22} = Rel; 10550 let Inst{21} = 0b1; 10551 let Inst{20-16} = Rs; 10552 let Inst{15} = 0b1; 10553 let Inst{14-12} = opc; 10554 let Inst{11-10} = 0b00; 10555 let Inst{9-5} = Rn; 10556 let Inst{4-0} = Rt; 10557 let Predicates = [HasLSE]; 10558} 10559 10560multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 10561 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>; 10562 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>; 10563 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>; 10564 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>; 10565} 10566 10567let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 10568class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 10569 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 10570 "\t$Rs, $Rt, [$Rn]","",[]>, 10571 Sched<[WriteAtomic]> { 10572 bits<2> Sz; 10573 bit Acq; 10574 bit Rel; 10575 bits<5> Rs; 10576 bits<3> opc; 10577 bits<5> Rn; 10578 bits<5> Rt; 10579 let Inst{31-30} = Sz; 10580 let Inst{29-24} = 0b111000; 10581 let Inst{23} = Acq; 10582 let Inst{22} = Rel; 10583 let Inst{21} = 0b1; 10584 let Inst{20-16} = Rs; 10585 let Inst{15} = 0b0; 10586 let Inst{14-12} = opc; 10587 let Inst{11-10} = 0b00; 10588 let Inst{9-5} = Rn; 10589 let Inst{4-0} = Rt; 10590 let Predicates = [HasLSE]; 10591} 10592 10593multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 10594 string order> { 10595 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 10596 def B : BaseLDOPregister<op, order, "b", GPR32>; 10597 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 10598 def H : BaseLDOPregister<op, order, "h", GPR32>; 10599 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 10600 def W : BaseLDOPregister<op, order, "", GPR32>; 10601 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 10602 def X : BaseLDOPregister<op, order, "", GPR64>; 10603} 10604 10605// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more 10606// complex DAG for DstRHS. 10607let Predicates = [HasLSE] in 10608multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op, 10609 string size, dag SrcRHS, dag DstRHS> { 10610 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS), 10611 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>; 10612 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS), 10613 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>; 10614 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS), 10615 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>; 10616 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS), 10617 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 10618 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS), 10619 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>; 10620} 10621 10622multiclass LDOPregister_patterns_ord<string inst, string suffix, string op, 10623 string size, dag RHS> { 10624 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>; 10625} 10626 10627multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op, 10628 string size, dag LHS, dag RHS> { 10629 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>; 10630} 10631 10632multiclass LDOPregister_patterns<string inst, string op> { 10633 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>; 10634 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>; 10635 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>; 10636 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>; 10637} 10638 10639multiclass LDOPregister_patterns_mod<string inst, string op, string mod> { 10640 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64", 10641 (i64 GPR64:$Rm), 10642 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>; 10643 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32", 10644 (i32 GPR32:$Rm), 10645 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 10646 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16", 10647 (i32 GPR32:$Rm), 10648 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 10649 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8", 10650 (i32 GPR32:$Rm), 10651 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>; 10652} 10653 10654let Predicates = [HasLSE] in 10655multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op, 10656 string size, dag OLD, dag NEW> { 10657 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW), 10658 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>; 10659 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW), 10660 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10661 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW), 10662 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10663 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW), 10664 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10665 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW), 10666 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>; 10667} 10668 10669multiclass CASregister_patterns_ord<string inst, string suffix, string op, 10670 string size, dag OLD, dag NEW> { 10671 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>; 10672} 10673 10674multiclass CASregister_patterns<string inst, string op> { 10675 defm : CASregister_patterns_ord<inst, "X", op, "64", 10676 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>; 10677 defm : CASregister_patterns_ord<inst, "W", op, "32", 10678 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 10679 defm : CASregister_patterns_ord<inst, "H", op, "16", 10680 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 10681 defm : CASregister_patterns_ord<inst, "B", op, "8", 10682 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>; 10683} 10684 10685let Predicates = [HasLSE] in 10686class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 10687 Instruction inst> : 10688 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 10689 10690multiclass STOPregister<string asm, string instr> { 10691 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 10692 !cast<Instruction>(instr # "LB")>; 10693 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 10694 !cast<Instruction>(instr # "LH")>; 10695 def : BaseSTOPregister<asm # "l", GPR32, WZR, 10696 !cast<Instruction>(instr # "LW")>; 10697 def : BaseSTOPregister<asm # "l", GPR64, XZR, 10698 !cast<Instruction>(instr # "LX")>; 10699 def : BaseSTOPregister<asm # "b", GPR32, WZR, 10700 !cast<Instruction>(instr # "B")>; 10701 def : BaseSTOPregister<asm # "h", GPR32, WZR, 10702 !cast<Instruction>(instr # "H")>; 10703 def : BaseSTOPregister<asm, GPR32, WZR, 10704 !cast<Instruction>(instr # "W")>; 10705 def : BaseSTOPregister<asm, GPR64, XZR, 10706 !cast<Instruction>(instr # "X")>; 10707} 10708 10709//---------------------------------------------------------------------------- 10710// Allow the size specifier tokens to be upper case, not just lower. 10711def : TokenAlias<".4B", ".4b">; // Add dot product 10712def : TokenAlias<".8B", ".8b">; 10713def : TokenAlias<".4H", ".4h">; 10714def : TokenAlias<".2S", ".2s">; 10715def : TokenAlias<".1D", ".1d">; 10716def : TokenAlias<".16B", ".16b">; 10717def : TokenAlias<".8H", ".8h">; 10718def : TokenAlias<".4S", ".4s">; 10719def : TokenAlias<".2D", ".2d">; 10720def : TokenAlias<".1Q", ".1q">; 10721def : TokenAlias<".2H", ".2h">; 10722def : TokenAlias<".B", ".b">; 10723def : TokenAlias<".H", ".h">; 10724def : TokenAlias<".S", ".s">; 10725def : TokenAlias<".D", ".d">; 10726def : TokenAlias<".Q", ".q">; 10727