1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10//===----------------------------------------------------------------------===// 11// Describe AArch64 instructions format here 12// 13 14// Format specifies the encoding used by the instruction. This is part of the 15// ad-hoc solution used to emit machine instruction encodings by our machine 16// code emitter. 17class Format<bits<2> val> { 18 bits<2> Value = val; 19} 20 21def PseudoFrm : Format<0>; 22def NormalFrm : Format<1>; // Do we need any others? 23 24// AArch64 Instruction Format 25class AArch64Inst<Format f, string cstr> : Instruction { 26 field bits<32> Inst; // Instruction encoding. 27 // Mask of bits that cause an encoding to be UNPREDICTABLE. 28 // If a bit is set, then if the corresponding bit in the 29 // target encoding differs from its value in the "Inst" field, 30 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). 31 field bits<32> Unpredictable = 0; 32 // SoftFail is the generic name for this field, but we alias it so 33 // as to make it more obvious what it means in ARM-land. 34 field bits<32> SoftFail = Unpredictable; 35 let Namespace = "AArch64"; 36 Format F = f; 37 bits<2> Form = F.Value; 38 let Pattern = []; 39 let Constraints = cstr; 40} 41 42// Pseudo instructions (don't have encoding information) 43class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = ""> 44 : AArch64Inst<PseudoFrm, cstr> { 45 dag OutOperandList = oops; 46 dag InOperandList = iops; 47 let Pattern = pattern; 48 let isCodeGenOnly = 1; 49} 50 51// Real instructions (have encoding information) 52class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> { 53 let Pattern = pattern; 54 let Size = 4; 55} 56 57// Normal instructions 58class I<dag oops, dag iops, string asm, string operands, string cstr, 59 list<dag> pattern> 60 : EncodedI<cstr, pattern> { 61 dag OutOperandList = oops; 62 dag InOperandList = iops; 63 let AsmString = !strconcat(asm, operands); 64} 65 66class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>; 67class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 68class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>; 69 70// Helper fragment for an extract of the high portion of a 128-bit vector. 71def extract_high_v16i8 : 72 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>; 73def extract_high_v8i16 : 74 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>; 75def extract_high_v4i32 : 76 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>; 77def extract_high_v2i64 : 78 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>; 79 80//===----------------------------------------------------------------------===// 81// Asm Operand Classes. 82// 83 84// Shifter operand for arithmetic shifted encodings. 85def ShifterOperand : AsmOperandClass { 86 let Name = "Shifter"; 87} 88 89// Shifter operand for mov immediate encodings. 90def MovImm32ShifterOperand : AsmOperandClass { 91 let SuperClasses = [ShifterOperand]; 92 let Name = "MovImm32Shifter"; 93 let RenderMethod = "addShifterOperands"; 94 let DiagnosticType = "InvalidMovImm32Shift"; 95} 96def MovImm64ShifterOperand : AsmOperandClass { 97 let SuperClasses = [ShifterOperand]; 98 let Name = "MovImm64Shifter"; 99 let RenderMethod = "addShifterOperands"; 100 let DiagnosticType = "InvalidMovImm64Shift"; 101} 102 103// Shifter operand for arithmetic register shifted encodings. 104class ArithmeticShifterOperand<int width> : AsmOperandClass { 105 let SuperClasses = [ShifterOperand]; 106 let Name = "ArithmeticShifter" # width; 107 let PredicateMethod = "isArithmeticShifter<" # width # ">"; 108 let RenderMethod = "addShifterOperands"; 109 let DiagnosticType = "AddSubRegShift" # width; 110} 111 112def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>; 113def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>; 114 115// Shifter operand for logical register shifted encodings. 116class LogicalShifterOperand<int width> : AsmOperandClass { 117 let SuperClasses = [ShifterOperand]; 118 let Name = "LogicalShifter" # width; 119 let PredicateMethod = "isLogicalShifter<" # width # ">"; 120 let RenderMethod = "addShifterOperands"; 121 let DiagnosticType = "AddSubRegShift" # width; 122} 123 124def LogicalShifterOperand32 : LogicalShifterOperand<32>; 125def LogicalShifterOperand64 : LogicalShifterOperand<64>; 126 127// Shifter operand for logical vector 128/64-bit shifted encodings. 128def LogicalVecShifterOperand : AsmOperandClass { 129 let SuperClasses = [ShifterOperand]; 130 let Name = "LogicalVecShifter"; 131 let RenderMethod = "addShifterOperands"; 132} 133def LogicalVecHalfWordShifterOperand : AsmOperandClass { 134 let SuperClasses = [LogicalVecShifterOperand]; 135 let Name = "LogicalVecHalfWordShifter"; 136 let RenderMethod = "addShifterOperands"; 137} 138 139// The "MSL" shifter on the vector MOVI instruction. 140def MoveVecShifterOperand : AsmOperandClass { 141 let SuperClasses = [ShifterOperand]; 142 let Name = "MoveVecShifter"; 143 let RenderMethod = "addShifterOperands"; 144} 145 146// Extend operand for arithmetic encodings. 147def ExtendOperand : AsmOperandClass { 148 let Name = "Extend"; 149 let DiagnosticType = "AddSubRegExtendLarge"; 150} 151def ExtendOperand64 : AsmOperandClass { 152 let SuperClasses = [ExtendOperand]; 153 let Name = "Extend64"; 154 let DiagnosticType = "AddSubRegExtendSmall"; 155} 156// 'extend' that's a lsl of a 64-bit register. 157def ExtendOperandLSL64 : AsmOperandClass { 158 let SuperClasses = [ExtendOperand]; 159 let Name = "ExtendLSL64"; 160 let RenderMethod = "addExtend64Operands"; 161 let DiagnosticType = "AddSubRegExtendLarge"; 162} 163 164// 8-bit floating-point immediate encodings. 165def FPImmOperand : AsmOperandClass { 166 let Name = "FPImm"; 167 let ParserMethod = "tryParseFPImm"; 168 let DiagnosticType = "InvalidFPImm"; 169} 170 171def CondCode : AsmOperandClass { 172 let Name = "CondCode"; 173 let DiagnosticType = "InvalidCondCode"; 174} 175 176// A 32-bit register pasrsed as 64-bit 177def GPR32as64Operand : AsmOperandClass { 178 let Name = "GPR32as64"; 179} 180def GPR32as64 : RegisterOperand<GPR32> { 181 let ParserMatchClass = GPR32as64Operand; 182} 183 184// 8-bit immediate for AdvSIMD where 64-bit values of the form: 185// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 186// are encoded as the eight bit value 'abcdefgh'. 187def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; } 188 189 190//===----------------------------------------------------------------------===// 191// Operand Definitions. 192// 193 194// ADR[P] instruction labels. 195def AdrpOperand : AsmOperandClass { 196 let Name = "AdrpLabel"; 197 let ParserMethod = "tryParseAdrpLabel"; 198 let DiagnosticType = "InvalidLabel"; 199} 200def adrplabel : Operand<i64> { 201 let EncoderMethod = "getAdrLabelOpValue"; 202 let PrintMethod = "printAdrpLabel"; 203 let ParserMatchClass = AdrpOperand; 204} 205 206def AdrOperand : AsmOperandClass { 207 let Name = "AdrLabel"; 208 let ParserMethod = "tryParseAdrLabel"; 209 let DiagnosticType = "InvalidLabel"; 210} 211def adrlabel : Operand<i64> { 212 let EncoderMethod = "getAdrLabelOpValue"; 213 let ParserMatchClass = AdrOperand; 214} 215 216// simm9 predicate - True if the immediate is in the range [-256, 255]. 217def SImm9Operand : AsmOperandClass { 218 let Name = "SImm9"; 219 let DiagnosticType = "InvalidMemoryIndexedSImm9"; 220} 221def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> { 222 let ParserMatchClass = SImm9Operand; 223} 224 225// simm7sN predicate - True if the immediate is a multiple of N in the range 226// [-64 * N, 63 * N]. 227class SImm7Scaled<int Scale> : AsmOperandClass { 228 let Name = "SImm7s" # Scale; 229 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7"; 230} 231 232def SImm7s4Operand : SImm7Scaled<4>; 233def SImm7s8Operand : SImm7Scaled<8>; 234def SImm7s16Operand : SImm7Scaled<16>; 235 236def simm7s4 : Operand<i32> { 237 let ParserMatchClass = SImm7s4Operand; 238 let PrintMethod = "printImmScale<4>"; 239} 240 241def simm7s8 : Operand<i32> { 242 let ParserMatchClass = SImm7s8Operand; 243 let PrintMethod = "printImmScale<8>"; 244} 245 246def simm7s16 : Operand<i32> { 247 let ParserMatchClass = SImm7s16Operand; 248 let PrintMethod = "printImmScale<16>"; 249} 250 251def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>; 252def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>; 253def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>; 254def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>; 255def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>; 256 257class AsmImmRange<int Low, int High> : AsmOperandClass { 258 let Name = "Imm" # Low # "_" # High; 259 let DiagnosticType = "InvalidImm" # Low # "_" # High; 260} 261 262def Imm1_8Operand : AsmImmRange<1, 8>; 263def Imm1_16Operand : AsmImmRange<1, 16>; 264def Imm1_32Operand : AsmImmRange<1, 32>; 265def Imm1_64Operand : AsmImmRange<1, 64>; 266 267def MovZSymbolG3AsmOperand : AsmOperandClass { 268 let Name = "MovZSymbolG3"; 269 let RenderMethod = "addImmOperands"; 270} 271 272def movz_symbol_g3 : Operand<i32> { 273 let ParserMatchClass = MovZSymbolG3AsmOperand; 274} 275 276def MovZSymbolG2AsmOperand : AsmOperandClass { 277 let Name = "MovZSymbolG2"; 278 let RenderMethod = "addImmOperands"; 279} 280 281def movz_symbol_g2 : Operand<i32> { 282 let ParserMatchClass = MovZSymbolG2AsmOperand; 283} 284 285def MovZSymbolG1AsmOperand : AsmOperandClass { 286 let Name = "MovZSymbolG1"; 287 let RenderMethod = "addImmOperands"; 288} 289 290def movz_symbol_g1 : Operand<i32> { 291 let ParserMatchClass = MovZSymbolG1AsmOperand; 292} 293 294def MovZSymbolG0AsmOperand : AsmOperandClass { 295 let Name = "MovZSymbolG0"; 296 let RenderMethod = "addImmOperands"; 297} 298 299def movz_symbol_g0 : Operand<i32> { 300 let ParserMatchClass = MovZSymbolG0AsmOperand; 301} 302 303def MovKSymbolG3AsmOperand : AsmOperandClass { 304 let Name = "MovKSymbolG3"; 305 let RenderMethod = "addImmOperands"; 306} 307 308def movk_symbol_g3 : Operand<i32> { 309 let ParserMatchClass = MovKSymbolG3AsmOperand; 310} 311 312def MovKSymbolG2AsmOperand : AsmOperandClass { 313 let Name = "MovKSymbolG2"; 314 let RenderMethod = "addImmOperands"; 315} 316 317def movk_symbol_g2 : Operand<i32> { 318 let ParserMatchClass = MovKSymbolG2AsmOperand; 319} 320 321def MovKSymbolG1AsmOperand : AsmOperandClass { 322 let Name = "MovKSymbolG1"; 323 let RenderMethod = "addImmOperands"; 324} 325 326def movk_symbol_g1 : Operand<i32> { 327 let ParserMatchClass = MovKSymbolG1AsmOperand; 328} 329 330def MovKSymbolG0AsmOperand : AsmOperandClass { 331 let Name = "MovKSymbolG0"; 332 let RenderMethod = "addImmOperands"; 333} 334 335def movk_symbol_g0 : Operand<i32> { 336 let ParserMatchClass = MovKSymbolG0AsmOperand; 337} 338 339class fixedpoint_i32<ValueType FloatVT> 340 : Operand<FloatVT>, 341 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 342 let EncoderMethod = "getFixedPointScaleOpValue"; 343 let DecoderMethod = "DecodeFixedPointScaleImm32"; 344 let ParserMatchClass = Imm1_32Operand; 345} 346 347class fixedpoint_i64<ValueType FloatVT> 348 : Operand<FloatVT>, 349 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 350 let EncoderMethod = "getFixedPointScaleOpValue"; 351 let DecoderMethod = "DecodeFixedPointScaleImm64"; 352 let ParserMatchClass = Imm1_64Operand; 353} 354 355def fixedpoint_f16_i32 : fixedpoint_i32<f16>; 356def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 357def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 358 359def fixedpoint_f16_i64 : fixedpoint_i64<f16>; 360def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 361def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 362 363def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 364 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 365}]> { 366 let EncoderMethod = "getVecShiftR8OpValue"; 367 let DecoderMethod = "DecodeVecShiftR8Imm"; 368 let ParserMatchClass = Imm1_8Operand; 369} 370def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 371 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 372}]> { 373 let EncoderMethod = "getVecShiftR16OpValue"; 374 let DecoderMethod = "DecodeVecShiftR16Imm"; 375 let ParserMatchClass = Imm1_16Operand; 376} 377def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 378 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 379}]> { 380 let EncoderMethod = "getVecShiftR16OpValue"; 381 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 382 let ParserMatchClass = Imm1_8Operand; 383} 384def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 385 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 386}]> { 387 let EncoderMethod = "getVecShiftR32OpValue"; 388 let DecoderMethod = "DecodeVecShiftR32Imm"; 389 let ParserMatchClass = Imm1_32Operand; 390} 391def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 392 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 393}]> { 394 let EncoderMethod = "getVecShiftR32OpValue"; 395 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 396 let ParserMatchClass = Imm1_16Operand; 397} 398def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 399 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 400}]> { 401 let EncoderMethod = "getVecShiftR64OpValue"; 402 let DecoderMethod = "DecodeVecShiftR64Imm"; 403 let ParserMatchClass = Imm1_64Operand; 404} 405def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 406 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 407}]> { 408 let EncoderMethod = "getVecShiftR64OpValue"; 409 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 410 let ParserMatchClass = Imm1_32Operand; 411} 412 413def Imm0_1Operand : AsmImmRange<0, 1>; 414def Imm0_7Operand : AsmImmRange<0, 7>; 415def Imm0_15Operand : AsmImmRange<0, 15>; 416def Imm0_31Operand : AsmImmRange<0, 31>; 417def Imm0_63Operand : AsmImmRange<0, 63>; 418 419def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 420 return (((uint32_t)Imm) < 8); 421}]> { 422 let EncoderMethod = "getVecShiftL8OpValue"; 423 let DecoderMethod = "DecodeVecShiftL8Imm"; 424 let ParserMatchClass = Imm0_7Operand; 425} 426def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 427 return (((uint32_t)Imm) < 16); 428}]> { 429 let EncoderMethod = "getVecShiftL16OpValue"; 430 let DecoderMethod = "DecodeVecShiftL16Imm"; 431 let ParserMatchClass = Imm0_15Operand; 432} 433def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 434 return (((uint32_t)Imm) < 32); 435}]> { 436 let EncoderMethod = "getVecShiftL32OpValue"; 437 let DecoderMethod = "DecodeVecShiftL32Imm"; 438 let ParserMatchClass = Imm0_31Operand; 439} 440def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 441 return (((uint32_t)Imm) < 64); 442}]> { 443 let EncoderMethod = "getVecShiftL64OpValue"; 444 let DecoderMethod = "DecodeVecShiftL64Imm"; 445 let ParserMatchClass = Imm0_63Operand; 446} 447 448 449// Crazy immediate formats used by 32-bit and 64-bit logical immediate 450// instructions for splatting repeating bit patterns across the immediate. 451def logical_imm32_XFORM : SDNodeXForm<imm, [{ 452 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 453 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 454}]>; 455def logical_imm64_XFORM : SDNodeXForm<imm, [{ 456 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 457 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 458}]>; 459 460let DiagnosticType = "LogicalSecondSource" in { 461 def LogicalImm32Operand : AsmOperandClass { 462 let Name = "LogicalImm32"; 463 } 464 def LogicalImm64Operand : AsmOperandClass { 465 let Name = "LogicalImm64"; 466 } 467 def LogicalImm32NotOperand : AsmOperandClass { 468 let Name = "LogicalImm32Not"; 469 } 470 def LogicalImm64NotOperand : AsmOperandClass { 471 let Name = "LogicalImm64Not"; 472 } 473} 474def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{ 475 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32); 476}], logical_imm32_XFORM> { 477 let PrintMethod = "printLogicalImm32"; 478 let ParserMatchClass = LogicalImm32Operand; 479} 480def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{ 481 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64); 482}], logical_imm64_XFORM> { 483 let PrintMethod = "printLogicalImm64"; 484 let ParserMatchClass = LogicalImm64Operand; 485} 486def logical_imm32_not : Operand<i32> { 487 let ParserMatchClass = LogicalImm32NotOperand; 488} 489def logical_imm64_not : Operand<i64> { 490 let ParserMatchClass = LogicalImm64NotOperand; 491} 492 493// imm0_65535 predicate - True if the immediate is in the range [0,65535]. 494def Imm0_65535Operand : AsmImmRange<0, 65535>; 495def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{ 496 return ((uint32_t)Imm) < 65536; 497}]> { 498 let ParserMatchClass = Imm0_65535Operand; 499 let PrintMethod = "printImmHex"; 500} 501 502// imm0_255 predicate - True if the immediate is in the range [0,255]. 503def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; } 504def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 505 return ((uint32_t)Imm) < 256; 506}]> { 507 let ParserMatchClass = Imm0_255Operand; 508 let PrintMethod = "printImm"; 509} 510 511// imm0_127 predicate - True if the immediate is in the range [0,127] 512def Imm0_127Operand : AsmImmRange<0, 127>; 513def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 514 return ((uint32_t)Imm) < 128; 515}]> { 516 let ParserMatchClass = Imm0_127Operand; 517 let PrintMethod = "printImm"; 518} 519 520// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 521// for all shift-amounts. 522 523// imm0_63 predicate - True if the immediate is in the range [0,63] 524def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 525 return ((uint64_t)Imm) < 64; 526}]> { 527 let ParserMatchClass = Imm0_63Operand; 528} 529 530// imm0_31 predicate - True if the immediate is in the range [0,31] 531def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 532 return ((uint64_t)Imm) < 32; 533}]> { 534 let ParserMatchClass = Imm0_31Operand; 535} 536 537// True if the 32-bit immediate is in the range [0,31] 538def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{ 539 return ((uint64_t)Imm) < 32; 540}]> { 541 let ParserMatchClass = Imm0_31Operand; 542} 543 544// imm0_1 predicate - True if the immediate is in the range [0,1] 545def imm0_1 : Operand<i64>, ImmLeaf<i64, [{ 546 return ((uint64_t)Imm) < 2; 547}]> { 548 let ParserMatchClass = Imm0_1Operand; 549} 550 551// imm0_15 predicate - True if the immediate is in the range [0,15] 552def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 553 return ((uint64_t)Imm) < 16; 554}]> { 555 let ParserMatchClass = Imm0_15Operand; 556} 557 558// imm0_7 predicate - True if the immediate is in the range [0,7] 559def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 560 return ((uint64_t)Imm) < 8; 561}]> { 562 let ParserMatchClass = Imm0_7Operand; 563} 564 565// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 566def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 567 return ((uint32_t)Imm) < 16; 568}]> { 569 let ParserMatchClass = Imm0_15Operand; 570} 571 572// An arithmetic shifter operand: 573// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 574// {5-0} - imm6 575class arith_shift<ValueType Ty, int width> : Operand<Ty> { 576 let PrintMethod = "printShifter"; 577 let ParserMatchClass = !cast<AsmOperandClass>( 578 "ArithmeticShifterOperand" # width); 579} 580 581def arith_shift32 : arith_shift<i32, 32>; 582def arith_shift64 : arith_shift<i64, 64>; 583 584class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 585 : Operand<Ty>, 586 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 587 let PrintMethod = "printShiftedRegister"; 588 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 589} 590 591def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 592def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 593 594// An arithmetic shifter operand: 595// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 596// {5-0} - imm6 597class logical_shift<int width> : Operand<i32> { 598 let PrintMethod = "printShifter"; 599 let ParserMatchClass = !cast<AsmOperandClass>( 600 "LogicalShifterOperand" # width); 601} 602 603def logical_shift32 : logical_shift<32>; 604def logical_shift64 : logical_shift<64>; 605 606class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 607 : Operand<Ty>, 608 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 609 let PrintMethod = "printShiftedRegister"; 610 let MIOperandInfo = (ops regclass, shiftop); 611} 612 613def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 614def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 615 616// A logical vector shifter operand: 617// {7-6} - shift type: 00 = lsl 618// {5-0} - imm6: #0, #8, #16, or #24 619def logical_vec_shift : Operand<i32> { 620 let PrintMethod = "printShifter"; 621 let EncoderMethod = "getVecShifterOpValue"; 622 let ParserMatchClass = LogicalVecShifterOperand; 623} 624 625// A logical vector half-word shifter operand: 626// {7-6} - shift type: 00 = lsl 627// {5-0} - imm6: #0 or #8 628def logical_vec_hw_shift : Operand<i32> { 629 let PrintMethod = "printShifter"; 630 let EncoderMethod = "getVecShifterOpValue"; 631 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 632} 633 634// A vector move shifter operand: 635// {0} - imm1: #8 or #16 636def move_vec_shift : Operand<i32> { 637 let PrintMethod = "printShifter"; 638 let EncoderMethod = "getMoveVecShifterOpValue"; 639 let ParserMatchClass = MoveVecShifterOperand; 640} 641 642let DiagnosticType = "AddSubSecondSource" in { 643 def AddSubImmOperand : AsmOperandClass { 644 let Name = "AddSubImm"; 645 let ParserMethod = "tryParseAddSubImm"; 646 } 647 def AddSubImmNegOperand : AsmOperandClass { 648 let Name = "AddSubImmNeg"; 649 let ParserMethod = "tryParseAddSubImm"; 650 } 651} 652// An ADD/SUB immediate shifter operand: 653// second operand: 654// {7-6} - shift type: 00 = lsl 655// {5-0} - imm6: #0 or #12 656class addsub_shifted_imm<ValueType Ty> 657 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 658 let PrintMethod = "printAddSubImm"; 659 let EncoderMethod = "getAddSubImmOpValue"; 660 let ParserMatchClass = AddSubImmOperand; 661 let MIOperandInfo = (ops i32imm, i32imm); 662} 663 664class addsub_shifted_imm_neg<ValueType Ty> 665 : Operand<Ty> { 666 let EncoderMethod = "getAddSubImmOpValue"; 667 let ParserMatchClass = AddSubImmNegOperand; 668 let MIOperandInfo = (ops i32imm, i32imm); 669} 670 671def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 672def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 673def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>; 674def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>; 675 676class neg_addsub_shifted_imm<ValueType Ty> 677 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 678 let PrintMethod = "printAddSubImm"; 679 let EncoderMethod = "getAddSubImmOpValue"; 680 let ParserMatchClass = AddSubImmOperand; 681 let MIOperandInfo = (ops i32imm, i32imm); 682} 683 684def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 685def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 686 687// An extend operand: 688// {5-3} - extend type 689// {2-0} - imm3 690def arith_extend : Operand<i32> { 691 let PrintMethod = "printArithExtend"; 692 let ParserMatchClass = ExtendOperand; 693} 694def arith_extend64 : Operand<i32> { 695 let PrintMethod = "printArithExtend"; 696 let ParserMatchClass = ExtendOperand64; 697} 698 699// 'extend' that's a lsl of a 64-bit register. 700def arith_extendlsl64 : Operand<i32> { 701 let PrintMethod = "printArithExtend"; 702 let ParserMatchClass = ExtendOperandLSL64; 703} 704 705class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 706 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 707 let PrintMethod = "printExtendedRegister"; 708 let MIOperandInfo = (ops GPR32, arith_extend); 709} 710 711class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 712 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 713 let PrintMethod = "printExtendedRegister"; 714 let MIOperandInfo = (ops GPR32, arith_extend64); 715} 716 717// Floating-point immediate. 718def fpimm16 : Operand<f16>, 719 PatLeaf<(f16 fpimm), [{ 720 return AArch64_AM::getFP16Imm(N->getValueAPF()) != -1; 721 }], SDNodeXForm<fpimm, [{ 722 APFloat InVal = N->getValueAPF(); 723 uint32_t enc = AArch64_AM::getFP16Imm(InVal); 724 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 725 }]>> { 726 let ParserMatchClass = FPImmOperand; 727 let PrintMethod = "printFPImmOperand"; 728} 729def fpimm32 : Operand<f32>, 730 PatLeaf<(f32 fpimm), [{ 731 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1; 732 }], SDNodeXForm<fpimm, [{ 733 APFloat InVal = N->getValueAPF(); 734 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 735 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 736 }]>> { 737 let ParserMatchClass = FPImmOperand; 738 let PrintMethod = "printFPImmOperand"; 739} 740def fpimm64 : Operand<f64>, 741 PatLeaf<(f64 fpimm), [{ 742 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1; 743 }], SDNodeXForm<fpimm, [{ 744 APFloat InVal = N->getValueAPF(); 745 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 746 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 747 }]>> { 748 let ParserMatchClass = FPImmOperand; 749 let PrintMethod = "printFPImmOperand"; 750} 751 752def fpimm8 : Operand<i32> { 753 let ParserMatchClass = FPImmOperand; 754 let PrintMethod = "printFPImmOperand"; 755} 756 757def fpimm0 : PatLeaf<(fpimm), [{ 758 return N->isExactlyValue(+0.0); 759}]>; 760 761// Vector lane operands 762class AsmVectorIndex<string Suffix> : AsmOperandClass { 763 let Name = "VectorIndex" # Suffix; 764 let DiagnosticType = "InvalidIndex" # Suffix; 765} 766def VectorIndex1Operand : AsmVectorIndex<"1">; 767def VectorIndexBOperand : AsmVectorIndex<"B">; 768def VectorIndexHOperand : AsmVectorIndex<"H">; 769def VectorIndexSOperand : AsmVectorIndex<"S">; 770def VectorIndexDOperand : AsmVectorIndex<"D">; 771 772def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{ 773 return ((uint64_t)Imm) == 1; 774}]> { 775 let ParserMatchClass = VectorIndex1Operand; 776 let PrintMethod = "printVectorIndex"; 777 let MIOperandInfo = (ops i64imm); 778} 779def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{ 780 return ((uint64_t)Imm) < 16; 781}]> { 782 let ParserMatchClass = VectorIndexBOperand; 783 let PrintMethod = "printVectorIndex"; 784 let MIOperandInfo = (ops i64imm); 785} 786def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{ 787 return ((uint64_t)Imm) < 8; 788}]> { 789 let ParserMatchClass = VectorIndexHOperand; 790 let PrintMethod = "printVectorIndex"; 791 let MIOperandInfo = (ops i64imm); 792} 793def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{ 794 return ((uint64_t)Imm) < 4; 795}]> { 796 let ParserMatchClass = VectorIndexSOperand; 797 let PrintMethod = "printVectorIndex"; 798 let MIOperandInfo = (ops i64imm); 799} 800def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{ 801 return ((uint64_t)Imm) < 2; 802}]> { 803 let ParserMatchClass = VectorIndexDOperand; 804 let PrintMethod = "printVectorIndex"; 805 let MIOperandInfo = (ops i64imm); 806} 807 808// 8-bit immediate for AdvSIMD where 64-bit values of the form: 809// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 810// are encoded as the eight bit value 'abcdefgh'. 811def simdimmtype10 : Operand<i32>, 812 PatLeaf<(f64 fpimm), [{ 813 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF() 814 .bitcastToAPInt() 815 .getZExtValue()); 816 }], SDNodeXForm<fpimm, [{ 817 APFloat InVal = N->getValueAPF(); 818 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 819 .bitcastToAPInt() 820 .getZExtValue()); 821 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 822 }]>> { 823 let ParserMatchClass = SIMDImmType10Operand; 824 let PrintMethod = "printSIMDType10Operand"; 825} 826 827 828//--- 829// System management 830//--- 831 832// Base encoding for system instruction operands. 833let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 834class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 835 list<dag> pattern = []> 836 : I<oops, iops, asm, operands, "", pattern> { 837 let Inst{31-22} = 0b1101010100; 838 let Inst{21} = L; 839} 840 841// System instructions which do not have an Rt register. 842class SimpleSystemI<bit L, dag iops, string asm, string operands, 843 list<dag> pattern = []> 844 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 845 let Inst{4-0} = 0b11111; 846} 847 848// System instructions which have an Rt register. 849class RtSystemI<bit L, dag oops, dag iops, string asm, string operands> 850 : BaseSystemI<L, oops, iops, asm, operands>, 851 Sched<[WriteSys]> { 852 bits<5> Rt; 853 let Inst{4-0} = Rt; 854} 855 856// Hint instructions that take both a CRm and a 3-bit immediate. 857// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 858// model patterns with sufficiently fine granularity 859let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 860 class HintI<string mnemonic> 861 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "", 862 [(int_aarch64_hint imm0_127:$imm)]>, 863 Sched<[WriteHint]> { 864 bits <7> imm; 865 let Inst{20-12} = 0b000110010; 866 let Inst{11-5} = imm; 867 } 868 869// System instructions taking a single literal operand which encodes into 870// CRm. op2 differentiates the opcodes. 871def BarrierAsmOperand : AsmOperandClass { 872 let Name = "Barrier"; 873 let ParserMethod = "tryParseBarrierOperand"; 874} 875def barrier_op : Operand<i32> { 876 let PrintMethod = "printBarrierOption"; 877 let ParserMatchClass = BarrierAsmOperand; 878} 879class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 880 list<dag> pattern = []> 881 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 882 Sched<[WriteBarrier]> { 883 bits<4> CRm; 884 let Inst{20-12} = 0b000110011; 885 let Inst{11-8} = CRm; 886 let Inst{7-5} = opc; 887} 888 889// MRS/MSR system instructions. These have different operand classes because 890// a different subset of registers can be accessed through each instruction. 891def MRSSystemRegisterOperand : AsmOperandClass { 892 let Name = "MRSSystemRegister"; 893 let ParserMethod = "tryParseSysReg"; 894 let DiagnosticType = "MRS"; 895} 896// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 897def mrs_sysreg_op : Operand<i32> { 898 let ParserMatchClass = MRSSystemRegisterOperand; 899 let DecoderMethod = "DecodeMRSSystemRegister"; 900 let PrintMethod = "printMRSSystemRegister"; 901} 902 903def MSRSystemRegisterOperand : AsmOperandClass { 904 let Name = "MSRSystemRegister"; 905 let ParserMethod = "tryParseSysReg"; 906 let DiagnosticType = "MSR"; 907} 908def msr_sysreg_op : Operand<i32> { 909 let ParserMatchClass = MSRSystemRegisterOperand; 910 let DecoderMethod = "DecodeMSRSystemRegister"; 911 let PrintMethod = "printMSRSystemRegister"; 912} 913 914def PSBHintOperand : AsmOperandClass { 915 let Name = "PSBHint"; 916 let ParserMethod = "tryParsePSBHint"; 917} 918def psbhint_op : Operand<i32> { 919 let ParserMatchClass = PSBHintOperand; 920 let PrintMethod = "printPSBHintOp"; 921 let MCOperandPredicate = [{ 922 // Check, if operand is valid, to fix exhaustive aliasing in disassembly. 923 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields. 924 if (!MCOp.isImm()) 925 return false; 926 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr; 927 }]; 928} 929 930class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 931 "mrs", "\t$Rt, $systemreg"> { 932 bits<16> systemreg; 933 let Inst{20-5} = systemreg; 934} 935 936// FIXME: Some of these def NZCV, others don't. Best way to model that? 937// Explicitly modeling each of the system register as a register class 938// would do it, but feels like overkill at this point. 939class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 940 "msr", "\t$systemreg, $Rt"> { 941 bits<16> systemreg; 942 let Inst{20-5} = systemreg; 943} 944 945def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 946 let Name = "SystemPStateFieldWithImm0_15"; 947 let ParserMethod = "tryParseSysReg"; 948} 949def pstatefield4_op : Operand<i32> { 950 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 951 let PrintMethod = "printSystemPStateField"; 952} 953 954let Defs = [NZCV] in 955class MSRpstateImm0_15 956 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm), 957 "msr", "\t$pstatefield, $imm">, 958 Sched<[WriteSys]> { 959 bits<6> pstatefield; 960 bits<4> imm; 961 let Inst{20-19} = 0b00; 962 let Inst{18-16} = pstatefield{5-3}; 963 let Inst{15-12} = 0b0100; 964 let Inst{11-8} = imm; 965 let Inst{7-5} = pstatefield{2-0}; 966 967 let DecoderMethod = "DecodeSystemPStateInstruction"; 968 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 969 // Fail the decoder should attempt to decode the instruction as MSRI. 970 let hasCompleteDecoder = 0; 971} 972 973def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 974 let Name = "SystemPStateFieldWithImm0_1"; 975 let ParserMethod = "tryParseSysReg"; 976} 977def pstatefield1_op : Operand<i32> { 978 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 979 let PrintMethod = "printSystemPStateField"; 980} 981 982let Defs = [NZCV] in 983class MSRpstateImm0_1 984 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm), 985 "msr", "\t$pstatefield, $imm">, 986 Sched<[WriteSys]> { 987 bits<6> pstatefield; 988 bit imm; 989 let Inst{20-19} = 0b00; 990 let Inst{18-16} = pstatefield{5-3}; 991 let Inst{15-9} = 0b0100000; 992 let Inst{8} = imm; 993 let Inst{7-5} = pstatefield{2-0}; 994 995 let DecoderMethod = "DecodeSystemPStateInstruction"; 996 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 997 // Fail the decoder should attempt to decode the instruction as MSRI. 998 let hasCompleteDecoder = 0; 999} 1000 1001// SYS and SYSL generic system instructions. 1002def SysCRAsmOperand : AsmOperandClass { 1003 let Name = "SysCR"; 1004 let ParserMethod = "tryParseSysCROperand"; 1005} 1006 1007def sys_cr_op : Operand<i32> { 1008 let PrintMethod = "printSysCROperand"; 1009 let ParserMatchClass = SysCRAsmOperand; 1010} 1011 1012class SystemXtI<bit L, string asm> 1013 : RtSystemI<L, (outs), 1014 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1015 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1016 bits<3> op1; 1017 bits<4> Cn; 1018 bits<4> Cm; 1019 bits<3> op2; 1020 let Inst{20-19} = 0b01; 1021 let Inst{18-16} = op1; 1022 let Inst{15-12} = Cn; 1023 let Inst{11-8} = Cm; 1024 let Inst{7-5} = op2; 1025} 1026 1027class SystemLXtI<bit L, string asm> 1028 : RtSystemI<L, (outs), 1029 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1030 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1031 bits<3> op1; 1032 bits<4> Cn; 1033 bits<4> Cm; 1034 bits<3> op2; 1035 let Inst{20-19} = 0b01; 1036 let Inst{18-16} = op1; 1037 let Inst{15-12} = Cn; 1038 let Inst{11-8} = Cm; 1039 let Inst{7-5} = op2; 1040} 1041 1042 1043// Branch (register) instructions: 1044// 1045// case opc of 1046// 0001 blr 1047// 0000 br 1048// 0101 dret 1049// 0100 eret 1050// 0010 ret 1051// otherwise UNDEFINED 1052class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1053 string operands, list<dag> pattern> 1054 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1055 let Inst{31-25} = 0b1101011; 1056 let Inst{24-21} = opc; 1057 let Inst{20-16} = 0b11111; 1058 let Inst{15-10} = 0b000000; 1059 let Inst{4-0} = 0b00000; 1060} 1061 1062class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1063 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1064 bits<5> Rn; 1065 let Inst{9-5} = Rn; 1066} 1067 1068let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1069class SpecialReturn<bits<4> opc, string asm> 1070 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1071 let Inst{9-5} = 0b11111; 1072} 1073 1074//--- 1075// Conditional branch instruction. 1076//--- 1077 1078// Condition code. 1079// 4-bit immediate. Pretty-printed as <cc> 1080def ccode : Operand<i32> { 1081 let PrintMethod = "printCondCode"; 1082 let ParserMatchClass = CondCode; 1083} 1084def inv_ccode : Operand<i32> { 1085 // AL and NV are invalid in the aliases which use inv_ccode 1086 let PrintMethod = "printInverseCondCode"; 1087 let ParserMatchClass = CondCode; 1088 let MCOperandPredicate = [{ 1089 return MCOp.isImm() && 1090 MCOp.getImm() != AArch64CC::AL && 1091 MCOp.getImm() != AArch64CC::NV; 1092 }]; 1093} 1094 1095// Conditional branch target. 19-bit immediate. The low two bits of the target 1096// offset are implied zero and so are not part of the immediate. 1097def PCRelLabel19Operand : AsmOperandClass { 1098 let Name = "PCRelLabel19"; 1099 let DiagnosticType = "InvalidLabel"; 1100} 1101def am_brcond : Operand<OtherVT> { 1102 let EncoderMethod = "getCondBranchTargetOpValue"; 1103 let DecoderMethod = "DecodePCRelLabel19"; 1104 let PrintMethod = "printAlignedLabel"; 1105 let ParserMatchClass = PCRelLabel19Operand; 1106} 1107 1108class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1109 "b", ".$cond\t$target", "", 1110 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1111 Sched<[WriteBr]> { 1112 let isBranch = 1; 1113 let isTerminator = 1; 1114 let Uses = [NZCV]; 1115 1116 bits<4> cond; 1117 bits<19> target; 1118 let Inst{31-24} = 0b01010100; 1119 let Inst{23-5} = target; 1120 let Inst{4} = 0; 1121 let Inst{3-0} = cond; 1122} 1123 1124//--- 1125// Compare-and-branch instructions. 1126//--- 1127class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1128 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1129 asm, "\t$Rt, $target", "", 1130 [(node regtype:$Rt, bb:$target)]>, 1131 Sched<[WriteBr]> { 1132 let isBranch = 1; 1133 let isTerminator = 1; 1134 1135 bits<5> Rt; 1136 bits<19> target; 1137 let Inst{30-25} = 0b011010; 1138 let Inst{24} = op; 1139 let Inst{23-5} = target; 1140 let Inst{4-0} = Rt; 1141} 1142 1143multiclass CmpBranch<bit op, string asm, SDNode node> { 1144 def W : BaseCmpBranch<GPR32, op, asm, node> { 1145 let Inst{31} = 0; 1146 } 1147 def X : BaseCmpBranch<GPR64, op, asm, node> { 1148 let Inst{31} = 1; 1149 } 1150} 1151 1152//--- 1153// Test-bit-and-branch instructions. 1154//--- 1155// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1156// the target offset are implied zero and so are not part of the immediate. 1157def BranchTarget14Operand : AsmOperandClass { 1158 let Name = "BranchTarget14"; 1159} 1160def am_tbrcond : Operand<OtherVT> { 1161 let EncoderMethod = "getTestBranchTargetOpValue"; 1162 let PrintMethod = "printAlignedLabel"; 1163 let ParserMatchClass = BranchTarget14Operand; 1164} 1165 1166// AsmOperand classes to emit (or not) special diagnostics 1167def TBZImm0_31Operand : AsmOperandClass { 1168 let Name = "TBZImm0_31"; 1169 let PredicateMethod = "isImm0_31"; 1170 let RenderMethod = "addImm0_31Operands"; 1171} 1172def TBZImm32_63Operand : AsmOperandClass { 1173 let Name = "Imm32_63"; 1174 let DiagnosticType = "InvalidImm0_63"; 1175} 1176 1177class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1178 return (((uint32_t)Imm) < 32); 1179}]> { 1180 let ParserMatchClass = matcher; 1181} 1182 1183def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1184def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1185 1186def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1187 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1188}]> { 1189 let ParserMatchClass = TBZImm32_63Operand; 1190} 1191 1192class BaseTestBranch<RegisterClass regtype, Operand immtype, 1193 bit op, string asm, SDNode node> 1194 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1195 asm, "\t$Rt, $bit_off, $target", "", 1196 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1197 Sched<[WriteBr]> { 1198 let isBranch = 1; 1199 let isTerminator = 1; 1200 1201 bits<5> Rt; 1202 bits<6> bit_off; 1203 bits<14> target; 1204 1205 let Inst{30-25} = 0b011011; 1206 let Inst{24} = op; 1207 let Inst{23-19} = bit_off{4-0}; 1208 let Inst{18-5} = target; 1209 let Inst{4-0} = Rt; 1210 1211 let DecoderMethod = "DecodeTestAndBranch"; 1212} 1213 1214multiclass TestBranch<bit op, string asm, SDNode node> { 1215 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1216 let Inst{31} = 0; 1217 } 1218 1219 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1220 let Inst{31} = 1; 1221 } 1222 1223 // Alias X-reg with 0-31 imm to W-Reg. 1224 def : InstAlias<asm # "\t$Rd, $imm, $target", 1225 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1226 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1227 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1228 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1229 tbz_imm0_31_diag:$imm, bb:$target)>; 1230} 1231 1232//--- 1233// Unconditional branch (immediate) instructions. 1234//--- 1235def BranchTarget26Operand : AsmOperandClass { 1236 let Name = "BranchTarget26"; 1237 let DiagnosticType = "InvalidLabel"; 1238} 1239def am_b_target : Operand<OtherVT> { 1240 let EncoderMethod = "getBranchTargetOpValue"; 1241 let PrintMethod = "printAlignedLabel"; 1242 let ParserMatchClass = BranchTarget26Operand; 1243} 1244def am_bl_target : Operand<i64> { 1245 let EncoderMethod = "getBranchTargetOpValue"; 1246 let PrintMethod = "printAlignedLabel"; 1247 let ParserMatchClass = BranchTarget26Operand; 1248} 1249 1250class BImm<bit op, dag iops, string asm, list<dag> pattern> 1251 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1252 bits<26> addr; 1253 let Inst{31} = op; 1254 let Inst{30-26} = 0b00101; 1255 let Inst{25-0} = addr; 1256 1257 let DecoderMethod = "DecodeUnconditionalBranch"; 1258} 1259 1260class BranchImm<bit op, string asm, list<dag> pattern> 1261 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1262class CallImm<bit op, string asm, list<dag> pattern> 1263 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1264 1265//--- 1266// Basic one-operand data processing instructions. 1267//--- 1268 1269let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1270class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1271 SDPatternOperator node> 1272 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1273 [(set regtype:$Rd, (node regtype:$Rn))]>, 1274 Sched<[WriteI, ReadI]> { 1275 bits<5> Rd; 1276 bits<5> Rn; 1277 1278 let Inst{30-13} = 0b101101011000000000; 1279 let Inst{12-10} = opc; 1280 let Inst{9-5} = Rn; 1281 let Inst{4-0} = Rd; 1282} 1283 1284let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1285multiclass OneOperandData<bits<3> opc, string asm, 1286 SDPatternOperator node = null_frag> { 1287 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1288 let Inst{31} = 0; 1289 } 1290 1291 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1292 let Inst{31} = 1; 1293 } 1294} 1295 1296class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1297 : BaseOneOperandData<opc, GPR32, asm, node> { 1298 let Inst{31} = 0; 1299} 1300 1301class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1302 : BaseOneOperandData<opc, GPR64, asm, node> { 1303 let Inst{31} = 1; 1304} 1305 1306//--- 1307// Basic two-operand data processing instructions. 1308//--- 1309class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1310 list<dag> pattern> 1311 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1312 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1313 Sched<[WriteI, ReadI, ReadI]> { 1314 let Uses = [NZCV]; 1315 bits<5> Rd; 1316 bits<5> Rn; 1317 bits<5> Rm; 1318 let Inst{30} = isSub; 1319 let Inst{28-21} = 0b11010000; 1320 let Inst{20-16} = Rm; 1321 let Inst{15-10} = 0; 1322 let Inst{9-5} = Rn; 1323 let Inst{4-0} = Rd; 1324} 1325 1326class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1327 SDNode OpNode> 1328 : BaseBaseAddSubCarry<isSub, regtype, asm, 1329 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 1330 1331class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 1332 SDNode OpNode> 1333 : BaseBaseAddSubCarry<isSub, regtype, asm, 1334 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 1335 (implicit NZCV)]> { 1336 let Defs = [NZCV]; 1337} 1338 1339multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 1340 SDNode OpNode, SDNode OpNode_setflags> { 1341 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 1342 let Inst{31} = 0; 1343 let Inst{29} = 0; 1344 } 1345 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 1346 let Inst{31} = 1; 1347 let Inst{29} = 0; 1348 } 1349 1350 // Sets flags. 1351 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 1352 OpNode_setflags> { 1353 let Inst{31} = 0; 1354 let Inst{29} = 1; 1355 } 1356 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 1357 OpNode_setflags> { 1358 let Inst{31} = 1; 1359 let Inst{29} = 1; 1360 } 1361} 1362 1363class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 1364 SDPatternOperator OpNode> 1365 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1366 asm, "\t$Rd, $Rn, $Rm", "", 1367 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> { 1368 bits<5> Rd; 1369 bits<5> Rn; 1370 bits<5> Rm; 1371 let Inst{30-21} = 0b0011010110; 1372 let Inst{20-16} = Rm; 1373 let Inst{15-14} = 0b00; 1374 let Inst{13-10} = opc; 1375 let Inst{9-5} = Rn; 1376 let Inst{4-0} = Rd; 1377} 1378 1379class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 1380 SDPatternOperator OpNode> 1381 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 1382 let Inst{10} = isSigned; 1383} 1384 1385multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 1386 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 1387 Sched<[WriteID32, ReadID, ReadID]> { 1388 let Inst{31} = 0; 1389 } 1390 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 1391 Sched<[WriteID64, ReadID, ReadID]> { 1392 let Inst{31} = 1; 1393 } 1394} 1395 1396class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 1397 SDPatternOperator OpNode = null_frag> 1398 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 1399 Sched<[WriteIS, ReadI]> { 1400 let Inst{11-10} = shift_type; 1401} 1402 1403multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 1404 def Wr : BaseShift<shift_type, GPR32, asm> { 1405 let Inst{31} = 0; 1406 } 1407 1408 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 1409 let Inst{31} = 1; 1410 } 1411 1412 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 1413 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 1414 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 1415 1416 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 1417 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1418 1419 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 1420 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1421 1422 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 1423 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1424} 1425 1426class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 1427 : InstAlias<asm#"\t$dst, $src1, $src2", 1428 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 1429 1430class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 1431 RegisterClass addtype, string asm, 1432 list<dag> pattern> 1433 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 1434 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 1435 bits<5> Rd; 1436 bits<5> Rn; 1437 bits<5> Rm; 1438 bits<5> Ra; 1439 let Inst{30-24} = 0b0011011; 1440 let Inst{23-21} = opc; 1441 let Inst{20-16} = Rm; 1442 let Inst{15} = isSub; 1443 let Inst{14-10} = Ra; 1444 let Inst{9-5} = Rn; 1445 let Inst{4-0} = Rd; 1446} 1447 1448multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 1449 // MADD/MSUB generation is decided by MachineCombiner.cpp 1450 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 1451 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 1452 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1453 let Inst{31} = 0; 1454 } 1455 1456 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 1457 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 1458 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 1459 let Inst{31} = 1; 1460 } 1461} 1462 1463class WideMulAccum<bit isSub, bits<3> opc, string asm, 1464 SDNode AccNode, SDNode ExtNode> 1465 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 1466 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 1467 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 1468 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1469 let Inst{31} = 1; 1470} 1471 1472class MulHi<bits<3> opc, string asm, SDNode OpNode> 1473 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 1474 asm, "\t$Rd, $Rn, $Rm", "", 1475 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 1476 Sched<[WriteIM64, ReadIM, ReadIM]> { 1477 bits<5> Rd; 1478 bits<5> Rn; 1479 bits<5> Rm; 1480 let Inst{31-24} = 0b10011011; 1481 let Inst{23-21} = opc; 1482 let Inst{20-16} = Rm; 1483 let Inst{15} = 0; 1484 let Inst{9-5} = Rn; 1485 let Inst{4-0} = Rd; 1486 1487 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 1488 // (i.e. all bits 1) but is ignored by the processor. 1489 let PostEncoderMethod = "fixMulHigh"; 1490} 1491 1492class MulAccumWAlias<string asm, Instruction inst> 1493 : InstAlias<asm#"\t$dst, $src1, $src2", 1494 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 1495class MulAccumXAlias<string asm, Instruction inst> 1496 : InstAlias<asm#"\t$dst, $src1, $src2", 1497 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 1498class WideMulAccumAlias<string asm, Instruction inst> 1499 : InstAlias<asm#"\t$dst, $src1, $src2", 1500 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 1501 1502class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 1503 SDPatternOperator OpNode, string asm> 1504 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 1505 asm, "\t$Rd, $Rn, $Rm", "", 1506 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 1507 Sched<[WriteISReg, ReadI, ReadISReg]> { 1508 bits<5> Rd; 1509 bits<5> Rn; 1510 bits<5> Rm; 1511 1512 let Inst{31} = sf; 1513 let Inst{30-21} = 0b0011010110; 1514 let Inst{20-16} = Rm; 1515 let Inst{15-13} = 0b010; 1516 let Inst{12} = C; 1517 let Inst{11-10} = sz; 1518 let Inst{9-5} = Rn; 1519 let Inst{4-0} = Rd; 1520 let Predicates = [HasCRC]; 1521} 1522 1523//--- 1524// Address generation. 1525//--- 1526 1527class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 1528 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 1529 pattern>, 1530 Sched<[WriteI]> { 1531 bits<5> Xd; 1532 bits<21> label; 1533 let Inst{31} = page; 1534 let Inst{30-29} = label{1-0}; 1535 let Inst{28-24} = 0b10000; 1536 let Inst{23-5} = label{20-2}; 1537 let Inst{4-0} = Xd; 1538 1539 let DecoderMethod = "DecodeAdrInstruction"; 1540} 1541 1542//--- 1543// Move immediate. 1544//--- 1545 1546def movimm32_imm : Operand<i32> { 1547 let ParserMatchClass = Imm0_65535Operand; 1548 let EncoderMethod = "getMoveWideImmOpValue"; 1549 let PrintMethod = "printImm"; 1550} 1551def movimm32_shift : Operand<i32> { 1552 let PrintMethod = "printShifter"; 1553 let ParserMatchClass = MovImm32ShifterOperand; 1554} 1555def movimm64_shift : Operand<i32> { 1556 let PrintMethod = "printShifter"; 1557 let ParserMatchClass = MovImm64ShifterOperand; 1558} 1559 1560let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1561class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 1562 string asm> 1563 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 1564 asm, "\t$Rd, $imm$shift", "", []>, 1565 Sched<[WriteImm]> { 1566 bits<5> Rd; 1567 bits<16> imm; 1568 bits<6> shift; 1569 let Inst{30-29} = opc; 1570 let Inst{28-23} = 0b100101; 1571 let Inst{22-21} = shift{5-4}; 1572 let Inst{20-5} = imm; 1573 let Inst{4-0} = Rd; 1574 1575 let DecoderMethod = "DecodeMoveImmInstruction"; 1576} 1577 1578multiclass MoveImmediate<bits<2> opc, string asm> { 1579 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 1580 let Inst{31} = 0; 1581 } 1582 1583 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 1584 let Inst{31} = 1; 1585 } 1586} 1587 1588let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1589class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 1590 string asm> 1591 : I<(outs regtype:$Rd), 1592 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 1593 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 1594 Sched<[WriteI, ReadI]> { 1595 bits<5> Rd; 1596 bits<16> imm; 1597 bits<6> shift; 1598 let Inst{30-29} = opc; 1599 let Inst{28-23} = 0b100101; 1600 let Inst{22-21} = shift{5-4}; 1601 let Inst{20-5} = imm; 1602 let Inst{4-0} = Rd; 1603 1604 let DecoderMethod = "DecodeMoveImmInstruction"; 1605} 1606 1607multiclass InsertImmediate<bits<2> opc, string asm> { 1608 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 1609 let Inst{31} = 0; 1610 } 1611 1612 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 1613 let Inst{31} = 1; 1614 } 1615} 1616 1617//--- 1618// Add/Subtract 1619//--- 1620 1621class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 1622 RegisterClass srcRegtype, addsub_shifted_imm immtype, 1623 string asm, SDPatternOperator OpNode> 1624 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm), 1625 asm, "\t$Rd, $Rn, $imm", "", 1626 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>, 1627 Sched<[WriteI, ReadI]> { 1628 bits<5> Rd; 1629 bits<5> Rn; 1630 bits<14> imm; 1631 let Inst{30} = isSub; 1632 let Inst{29} = setFlags; 1633 let Inst{28-24} = 0b10001; 1634 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 1635 let Inst{21-10} = imm{11-0}; 1636 let Inst{9-5} = Rn; 1637 let Inst{4-0} = Rd; 1638 let DecoderMethod = "DecodeBaseAddSubImm"; 1639} 1640 1641class BaseAddSubRegPseudo<RegisterClass regtype, 1642 SDPatternOperator OpNode> 1643 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1644 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 1645 Sched<[WriteI, ReadI, ReadI]>; 1646 1647class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 1648 arith_shifted_reg shifted_regtype, string asm, 1649 SDPatternOperator OpNode> 1650 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 1651 asm, "\t$Rd, $Rn, $Rm", "", 1652 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 1653 Sched<[WriteISReg, ReadI, ReadISReg]> { 1654 // The operands are in order to match the 'addr' MI operands, so we 1655 // don't need an encoder method and by-name matching. Just use the default 1656 // in-order handling. Since we're using by-order, make sure the names 1657 // do not match. 1658 bits<5> dst; 1659 bits<5> src1; 1660 bits<5> src2; 1661 bits<8> shift; 1662 let Inst{30} = isSub; 1663 let Inst{29} = setFlags; 1664 let Inst{28-24} = 0b01011; 1665 let Inst{23-22} = shift{7-6}; 1666 let Inst{21} = 0; 1667 let Inst{20-16} = src2; 1668 let Inst{15-10} = shift{5-0}; 1669 let Inst{9-5} = src1; 1670 let Inst{4-0} = dst; 1671 1672 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 1673} 1674 1675class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 1676 RegisterClass src1Regtype, Operand src2Regtype, 1677 string asm, SDPatternOperator OpNode> 1678 : I<(outs dstRegtype:$R1), 1679 (ins src1Regtype:$R2, src2Regtype:$R3), 1680 asm, "\t$R1, $R2, $R3", "", 1681 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 1682 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 1683 bits<5> Rd; 1684 bits<5> Rn; 1685 bits<5> Rm; 1686 bits<6> ext; 1687 let Inst{30} = isSub; 1688 let Inst{29} = setFlags; 1689 let Inst{28-24} = 0b01011; 1690 let Inst{23-21} = 0b001; 1691 let Inst{20-16} = Rm; 1692 let Inst{15-13} = ext{5-3}; 1693 let Inst{12-10} = ext{2-0}; 1694 let Inst{9-5} = Rn; 1695 let Inst{4-0} = Rd; 1696 1697 let DecoderMethod = "DecodeAddSubERegInstruction"; 1698} 1699 1700let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1701class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 1702 RegisterClass src1Regtype, RegisterClass src2Regtype, 1703 Operand ext_op, string asm> 1704 : I<(outs dstRegtype:$Rd), 1705 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 1706 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 1707 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 1708 bits<5> Rd; 1709 bits<5> Rn; 1710 bits<5> Rm; 1711 bits<6> ext; 1712 let Inst{30} = isSub; 1713 let Inst{29} = setFlags; 1714 let Inst{28-24} = 0b01011; 1715 let Inst{23-21} = 0b001; 1716 let Inst{20-16} = Rm; 1717 let Inst{15} = ext{5}; 1718 let Inst{12-10} = ext{2-0}; 1719 let Inst{9-5} = Rn; 1720 let Inst{4-0} = Rd; 1721 1722 let DecoderMethod = "DecodeAddSubERegInstruction"; 1723} 1724 1725// Aliases for register+register add/subtract. 1726class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 1727 RegisterClass src1Regtype, RegisterClass src2Regtype, 1728 int shiftExt> 1729 : InstAlias<asm#"\t$dst, $src1, $src2", 1730 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 1731 shiftExt)>; 1732 1733multiclass AddSub<bit isSub, string mnemonic, string alias, 1734 SDPatternOperator OpNode = null_frag> { 1735 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1736 // Add/Subtract immediate 1737 // Increase the weight of the immediate variant to try to match it before 1738 // the extended register variant. 1739 // We used to match the register variant before the immediate when the 1740 // register argument could be implicitly zero-extended. 1741 let AddedComplexity = 6 in 1742 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 1743 mnemonic, OpNode> { 1744 let Inst{31} = 0; 1745 } 1746 let AddedComplexity = 6 in 1747 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 1748 mnemonic, OpNode> { 1749 let Inst{31} = 1; 1750 } 1751 1752 // Add/Subtract register - Only used for CodeGen 1753 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 1754 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 1755 1756 // Add/Subtract shifted register 1757 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 1758 OpNode> { 1759 let Inst{31} = 0; 1760 } 1761 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 1762 OpNode> { 1763 let Inst{31} = 1; 1764 } 1765 } 1766 1767 // Add/Subtract extended register 1768 let AddedComplexity = 1, hasSideEffects = 0 in { 1769 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 1770 arith_extended_reg32<i32>, mnemonic, OpNode> { 1771 let Inst{31} = 0; 1772 } 1773 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 1774 arith_extended_reg32to64<i64>, mnemonic, OpNode> { 1775 let Inst{31} = 1; 1776 } 1777 } 1778 1779 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 1780 arith_extendlsl64, mnemonic> { 1781 // UXTX and SXTX only. 1782 let Inst{14-13} = 0b11; 1783 let Inst{31} = 1; 1784 } 1785 1786 // add Rd, Rb, -imm -> sub Rd, Rn, imm 1787 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1788 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 1789 addsub_shifted_imm32_neg:$imm), 0>; 1790 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1791 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 1792 addsub_shifted_imm64_neg:$imm), 0>; 1793 1794 // Register/register aliases with no shift when SP is not used. 1795 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 1796 GPR32, GPR32, GPR32, 0>; 1797 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 1798 GPR64, GPR64, GPR64, 0>; 1799 1800 // Register/register aliases with no shift when either the destination or 1801 // first source register is SP. 1802 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1803 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 1804 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1805 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 1806 def : AddSubRegAlias<mnemonic, 1807 !cast<Instruction>(NAME#"Xrx64"), 1808 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 1809 def : AddSubRegAlias<mnemonic, 1810 !cast<Instruction>(NAME#"Xrx64"), 1811 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 1812} 1813 1814multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 1815 string alias, string cmpAlias> { 1816 let isCompare = 1, Defs = [NZCV] in { 1817 // Add/Subtract immediate 1818 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 1819 mnemonic, OpNode> { 1820 let Inst{31} = 0; 1821 } 1822 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 1823 mnemonic, OpNode> { 1824 let Inst{31} = 1; 1825 } 1826 1827 // Add/Subtract register 1828 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 1829 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 1830 1831 // Add/Subtract shifted register 1832 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 1833 OpNode> { 1834 let Inst{31} = 0; 1835 } 1836 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 1837 OpNode> { 1838 let Inst{31} = 1; 1839 } 1840 1841 // Add/Subtract extended register 1842 let AddedComplexity = 1 in { 1843 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 1844 arith_extended_reg32<i32>, mnemonic, OpNode> { 1845 let Inst{31} = 0; 1846 } 1847 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 1848 arith_extended_reg32<i64>, mnemonic, OpNode> { 1849 let Inst{31} = 1; 1850 } 1851 } 1852 1853 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 1854 arith_extendlsl64, mnemonic> { 1855 // UXTX and SXTX only. 1856 let Inst{14-13} = 0b11; 1857 let Inst{31} = 1; 1858 } 1859 } // Defs = [NZCV] 1860 1861 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 1862 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1863 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 1864 addsub_shifted_imm32_neg:$imm), 0>; 1865 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1866 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 1867 addsub_shifted_imm64_neg:$imm), 0>; 1868 1869 // Compare aliases 1870 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 1871 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 1872 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 1873 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 1874 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 1875 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 1876 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 1877 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 1878 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 1879 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 1880 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 1881 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 1882 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 1883 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 1884 1885 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 1886 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 1887 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 1888 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 1889 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 1890 1891 // Compare shorthands 1892 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 1893 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 1894 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 1895 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 1896 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 1897 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 1898 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 1899 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 1900 1901 // Register/register aliases with no shift when SP is not used. 1902 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 1903 GPR32, GPR32, GPR32, 0>; 1904 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 1905 GPR64, GPR64, GPR64, 0>; 1906 1907 // Register/register aliases with no shift when the first source register 1908 // is SP. 1909 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1910 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 1911 def : AddSubRegAlias<mnemonic, 1912 !cast<Instruction>(NAME#"Xrx64"), 1913 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 1914} 1915 1916//--- 1917// Extract 1918//--- 1919def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 1920 SDTCisPtrTy<3>]>; 1921def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 1922 1923class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 1924 list<dag> patterns> 1925 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 1926 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 1927 Sched<[WriteExtr, ReadExtrHi]> { 1928 bits<5> Rd; 1929 bits<5> Rn; 1930 bits<5> Rm; 1931 bits<6> imm; 1932 1933 let Inst{30-23} = 0b00100111; 1934 let Inst{21} = 0; 1935 let Inst{20-16} = Rm; 1936 let Inst{15-10} = imm; 1937 let Inst{9-5} = Rn; 1938 let Inst{4-0} = Rd; 1939} 1940 1941multiclass ExtractImm<string asm> { 1942 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 1943 [(set GPR32:$Rd, 1944 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 1945 let Inst{31} = 0; 1946 let Inst{22} = 0; 1947 // imm<5> must be zero. 1948 let imm{5} = 0; 1949 } 1950 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 1951 [(set GPR64:$Rd, 1952 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 1953 1954 let Inst{31} = 1; 1955 let Inst{22} = 1; 1956 } 1957} 1958 1959//--- 1960// Bitfield 1961//--- 1962 1963let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1964class BaseBitfieldImm<bits<2> opc, 1965 RegisterClass regtype, Operand imm_type, string asm> 1966 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 1967 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 1968 Sched<[WriteIS, ReadI]> { 1969 bits<5> Rd; 1970 bits<5> Rn; 1971 bits<6> immr; 1972 bits<6> imms; 1973 1974 let Inst{30-29} = opc; 1975 let Inst{28-23} = 0b100110; 1976 let Inst{21-16} = immr; 1977 let Inst{15-10} = imms; 1978 let Inst{9-5} = Rn; 1979 let Inst{4-0} = Rd; 1980} 1981 1982multiclass BitfieldImm<bits<2> opc, string asm> { 1983 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 1984 let Inst{31} = 0; 1985 let Inst{22} = 0; 1986 // imms<5> and immr<5> must be zero, else ReservedValue(). 1987 let Inst{21} = 0; 1988 let Inst{15} = 0; 1989 } 1990 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 1991 let Inst{31} = 1; 1992 let Inst{22} = 1; 1993 } 1994} 1995 1996let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1997class BaseBitfieldImmWith2RegArgs<bits<2> opc, 1998 RegisterClass regtype, Operand imm_type, string asm> 1999 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2000 imm_type:$imms), 2001 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2002 Sched<[WriteIS, ReadI]> { 2003 bits<5> Rd; 2004 bits<5> Rn; 2005 bits<6> immr; 2006 bits<6> imms; 2007 2008 let Inst{30-29} = opc; 2009 let Inst{28-23} = 0b100110; 2010 let Inst{21-16} = immr; 2011 let Inst{15-10} = imms; 2012 let Inst{9-5} = Rn; 2013 let Inst{4-0} = Rd; 2014} 2015 2016multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2017 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2018 let Inst{31} = 0; 2019 let Inst{22} = 0; 2020 // imms<5> and immr<5> must be zero, else ReservedValue(). 2021 let Inst{21} = 0; 2022 let Inst{15} = 0; 2023 } 2024 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2025 let Inst{31} = 1; 2026 let Inst{22} = 1; 2027 } 2028} 2029 2030//--- 2031// Logical 2032//--- 2033 2034// Logical (immediate) 2035class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2036 RegisterClass sregtype, Operand imm_type, string asm, 2037 list<dag> pattern> 2038 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2039 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2040 Sched<[WriteI, ReadI]> { 2041 bits<5> Rd; 2042 bits<5> Rn; 2043 bits<13> imm; 2044 let Inst{30-29} = opc; 2045 let Inst{28-23} = 0b100100; 2046 let Inst{22} = imm{12}; 2047 let Inst{21-16} = imm{11-6}; 2048 let Inst{15-10} = imm{5-0}; 2049 let Inst{9-5} = Rn; 2050 let Inst{4-0} = Rd; 2051 2052 let DecoderMethod = "DecodeLogicalImmInstruction"; 2053} 2054 2055// Logical (shifted register) 2056class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2057 logical_shifted_reg shifted_regtype, string asm, 2058 list<dag> pattern> 2059 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2060 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2061 Sched<[WriteISReg, ReadI, ReadISReg]> { 2062 // The operands are in order to match the 'addr' MI operands, so we 2063 // don't need an encoder method and by-name matching. Just use the default 2064 // in-order handling. Since we're using by-order, make sure the names 2065 // do not match. 2066 bits<5> dst; 2067 bits<5> src1; 2068 bits<5> src2; 2069 bits<8> shift; 2070 let Inst{30-29} = opc; 2071 let Inst{28-24} = 0b01010; 2072 let Inst{23-22} = shift{7-6}; 2073 let Inst{21} = N; 2074 let Inst{20-16} = src2; 2075 let Inst{15-10} = shift{5-0}; 2076 let Inst{9-5} = src1; 2077 let Inst{4-0} = dst; 2078 2079 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2080} 2081 2082// Aliases for register+register logical instructions. 2083class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2084 : InstAlias<asm#"\t$dst, $src1, $src2", 2085 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2086 2087multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2088 string Alias> { 2089 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2090 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2091 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2092 logical_imm32:$imm))]> { 2093 let Inst{31} = 0; 2094 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2095 } 2096 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2097 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2098 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2099 logical_imm64:$imm))]> { 2100 let Inst{31} = 1; 2101 } 2102 2103 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2104 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2105 logical_imm32_not:$imm), 0>; 2106 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2107 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2108 logical_imm64_not:$imm), 0>; 2109} 2110 2111multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2112 string Alias> { 2113 let isCompare = 1, Defs = [NZCV] in { 2114 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2115 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2116 let Inst{31} = 0; 2117 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2118 } 2119 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2120 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2121 let Inst{31} = 1; 2122 } 2123 } // end Defs = [NZCV] 2124 2125 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2126 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2127 logical_imm32_not:$imm), 0>; 2128 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2129 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2130 logical_imm64_not:$imm), 0>; 2131} 2132 2133class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2134 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2135 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2136 Sched<[WriteI, ReadI, ReadI]>; 2137 2138// Split from LogicalImm as not all instructions have both. 2139multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2140 SDPatternOperator OpNode> { 2141 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2142 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2143 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2144 } 2145 2146 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2147 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2148 logical_shifted_reg32:$Rm))]> { 2149 let Inst{31} = 0; 2150 } 2151 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2152 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2153 logical_shifted_reg64:$Rm))]> { 2154 let Inst{31} = 1; 2155 } 2156 2157 def : LogicalRegAlias<mnemonic, 2158 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2159 def : LogicalRegAlias<mnemonic, 2160 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2161} 2162 2163// Split from LogicalReg to allow setting NZCV Defs 2164multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2165 SDPatternOperator OpNode = null_frag> { 2166 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2167 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2168 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2169 2170 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2171 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2172 let Inst{31} = 0; 2173 } 2174 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2175 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2176 let Inst{31} = 1; 2177 } 2178 } // Defs = [NZCV] 2179 2180 def : LogicalRegAlias<mnemonic, 2181 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2182 def : LogicalRegAlias<mnemonic, 2183 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2184} 2185 2186//--- 2187// Conditionally set flags 2188//--- 2189 2190let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2191class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2192 string mnemonic, SDNode OpNode> 2193 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2194 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2195 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2196 (i32 imm:$cond), NZCV))]>, 2197 Sched<[WriteI, ReadI]> { 2198 let Uses = [NZCV]; 2199 let Defs = [NZCV]; 2200 2201 bits<5> Rn; 2202 bits<5> imm; 2203 bits<4> nzcv; 2204 bits<4> cond; 2205 2206 let Inst{30} = op; 2207 let Inst{29-21} = 0b111010010; 2208 let Inst{20-16} = imm; 2209 let Inst{15-12} = cond; 2210 let Inst{11-10} = 0b10; 2211 let Inst{9-5} = Rn; 2212 let Inst{4} = 0b0; 2213 let Inst{3-0} = nzcv; 2214} 2215 2216let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2217class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2218 SDNode OpNode> 2219 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2220 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2221 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2222 (i32 imm:$cond), NZCV))]>, 2223 Sched<[WriteI, ReadI, ReadI]> { 2224 let Uses = [NZCV]; 2225 let Defs = [NZCV]; 2226 2227 bits<5> Rn; 2228 bits<5> Rm; 2229 bits<4> nzcv; 2230 bits<4> cond; 2231 2232 let Inst{30} = op; 2233 let Inst{29-21} = 0b111010010; 2234 let Inst{20-16} = Rm; 2235 let Inst{15-12} = cond; 2236 let Inst{11-10} = 0b00; 2237 let Inst{9-5} = Rn; 2238 let Inst{4} = 0b0; 2239 let Inst{3-0} = nzcv; 2240} 2241 2242multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2243 // immediate operand variants 2244 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2245 let Inst{31} = 0; 2246 } 2247 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2248 let Inst{31} = 1; 2249 } 2250 // register operand variants 2251 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2252 let Inst{31} = 0; 2253 } 2254 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2255 let Inst{31} = 1; 2256 } 2257} 2258 2259//--- 2260// Conditional select 2261//--- 2262 2263class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2264 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2265 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2266 [(set regtype:$Rd, 2267 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2268 Sched<[WriteI, ReadI, ReadI]> { 2269 let Uses = [NZCV]; 2270 2271 bits<5> Rd; 2272 bits<5> Rn; 2273 bits<5> Rm; 2274 bits<4> cond; 2275 2276 let Inst{30} = op; 2277 let Inst{29-21} = 0b011010100; 2278 let Inst{20-16} = Rm; 2279 let Inst{15-12} = cond; 2280 let Inst{11-10} = op2; 2281 let Inst{9-5} = Rn; 2282 let Inst{4-0} = Rd; 2283} 2284 2285multiclass CondSelect<bit op, bits<2> op2, string asm> { 2286 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2287 let Inst{31} = 0; 2288 } 2289 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 2290 let Inst{31} = 1; 2291 } 2292} 2293 2294class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 2295 PatFrag frag> 2296 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2297 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2298 [(set regtype:$Rd, 2299 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 2300 (i32 imm:$cond), NZCV))]>, 2301 Sched<[WriteI, ReadI, ReadI]> { 2302 let Uses = [NZCV]; 2303 2304 bits<5> Rd; 2305 bits<5> Rn; 2306 bits<5> Rm; 2307 bits<4> cond; 2308 2309 let Inst{30} = op; 2310 let Inst{29-21} = 0b011010100; 2311 let Inst{20-16} = Rm; 2312 let Inst{15-12} = cond; 2313 let Inst{11-10} = op2; 2314 let Inst{9-5} = Rn; 2315 let Inst{4-0} = Rd; 2316} 2317 2318def inv_cond_XFORM : SDNodeXForm<imm, [{ 2319 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 2320 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 2321 MVT::i32); 2322}]>; 2323 2324multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 2325 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 2326 let Inst{31} = 0; 2327 } 2328 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 2329 let Inst{31} = 1; 2330 } 2331 2332 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 2333 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 2334 (inv_cond_XFORM imm:$cond))>; 2335 2336 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 2337 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 2338 (inv_cond_XFORM imm:$cond))>; 2339} 2340 2341//--- 2342// Special Mask Value 2343//--- 2344def maski8_or_more : Operand<i32>, 2345 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 2346} 2347def maski16_or_more : Operand<i32>, 2348 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 2349} 2350 2351 2352//--- 2353// Load/store 2354//--- 2355 2356// (unsigned immediate) 2357// Indexed for 8-bit registers. offset is in range [0,4095]. 2358def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 2359def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 2360def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 2361def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 2362def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 2363 2364class UImm12OffsetOperand<int Scale> : AsmOperandClass { 2365 let Name = "UImm12Offset" # Scale; 2366 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 2367 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 2368 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 2369} 2370 2371def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 2372def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 2373def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 2374def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 2375def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 2376 2377class uimm12_scaled<int Scale> : Operand<i64> { 2378 let ParserMatchClass 2379 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 2380 let EncoderMethod 2381 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 2382 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 2383} 2384 2385def uimm12s1 : uimm12_scaled<1>; 2386def uimm12s2 : uimm12_scaled<2>; 2387def uimm12s4 : uimm12_scaled<4>; 2388def uimm12s8 : uimm12_scaled<8>; 2389def uimm12s16 : uimm12_scaled<16>; 2390 2391class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2392 string asm, list<dag> pattern> 2393 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 2394 bits<5> Rt; 2395 2396 bits<5> Rn; 2397 bits<12> offset; 2398 2399 let Inst{31-30} = sz; 2400 let Inst{29-27} = 0b111; 2401 let Inst{26} = V; 2402 let Inst{25-24} = 0b01; 2403 let Inst{23-22} = opc; 2404 let Inst{21-10} = offset; 2405 let Inst{9-5} = Rn; 2406 let Inst{4-0} = Rt; 2407 2408 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 2409} 2410 2411multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2412 Operand indextype, string asm, list<dag> pattern> { 2413 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2414 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 2415 (ins GPR64sp:$Rn, indextype:$offset), 2416 asm, pattern>, 2417 Sched<[WriteLD]>; 2418 2419 def : InstAlias<asm # "\t$Rt, [$Rn]", 2420 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2421} 2422 2423multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2424 Operand indextype, string asm, list<dag> pattern> { 2425 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2426 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 2427 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 2428 asm, pattern>, 2429 Sched<[WriteST]>; 2430 2431 def : InstAlias<asm # "\t$Rt, [$Rn]", 2432 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2433} 2434 2435def PrefetchOperand : AsmOperandClass { 2436 let Name = "Prefetch"; 2437 let ParserMethod = "tryParsePrefetch"; 2438} 2439def prfop : Operand<i32> { 2440 let PrintMethod = "printPrefetchOp"; 2441 let ParserMatchClass = PrefetchOperand; 2442} 2443 2444let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2445class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 2446 : BaseLoadStoreUI<sz, V, opc, 2447 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 2448 asm, pat>, 2449 Sched<[WriteLD]>; 2450 2451//--- 2452// Load literal 2453//--- 2454 2455// Load literal address: 19-bit immediate. The low two bits of the target 2456// offset are implied zero and so are not part of the immediate. 2457def am_ldrlit : Operand<OtherVT> { 2458 let EncoderMethod = "getLoadLiteralOpValue"; 2459 let DecoderMethod = "DecodePCRelLabel19"; 2460 let PrintMethod = "printAlignedLabel"; 2461 let ParserMatchClass = PCRelLabel19Operand; 2462} 2463 2464let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2465class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm> 2466 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 2467 asm, "\t$Rt, $label", "", []>, 2468 Sched<[WriteLD]> { 2469 bits<5> Rt; 2470 bits<19> label; 2471 let Inst{31-30} = opc; 2472 let Inst{29-27} = 0b011; 2473 let Inst{26} = V; 2474 let Inst{25-24} = 0b00; 2475 let Inst{23-5} = label; 2476 let Inst{4-0} = Rt; 2477} 2478 2479let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2480class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 2481 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 2482 asm, "\t$Rt, $label", "", pat>, 2483 Sched<[WriteLD]> { 2484 bits<5> Rt; 2485 bits<19> label; 2486 let Inst{31-30} = opc; 2487 let Inst{29-27} = 0b011; 2488 let Inst{26} = V; 2489 let Inst{25-24} = 0b00; 2490 let Inst{23-5} = label; 2491 let Inst{4-0} = Rt; 2492} 2493 2494//--- 2495// Load/store register offset 2496//--- 2497 2498def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 2499def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 2500def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 2501def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 2502def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 2503 2504def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 2505def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 2506def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 2507def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 2508def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 2509 2510class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 2511 let Name = "Mem" # Reg # "Extend" # Width; 2512 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 2513 let RenderMethod = "addMemExtendOperands"; 2514 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 2515} 2516 2517def MemWExtend8Operand : MemExtendOperand<"W", 8> { 2518 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 2519 // the trivial shift. 2520 let RenderMethod = "addMemExtend8Operands"; 2521} 2522def MemWExtend16Operand : MemExtendOperand<"W", 16>; 2523def MemWExtend32Operand : MemExtendOperand<"W", 32>; 2524def MemWExtend64Operand : MemExtendOperand<"W", 64>; 2525def MemWExtend128Operand : MemExtendOperand<"W", 128>; 2526 2527def MemXExtend8Operand : MemExtendOperand<"X", 8> { 2528 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 2529 // the trivial shift. 2530 let RenderMethod = "addMemExtend8Operands"; 2531} 2532def MemXExtend16Operand : MemExtendOperand<"X", 16>; 2533def MemXExtend32Operand : MemExtendOperand<"X", 32>; 2534def MemXExtend64Operand : MemExtendOperand<"X", 64>; 2535def MemXExtend128Operand : MemExtendOperand<"X", 128>; 2536 2537class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 2538 : Operand<i32> { 2539 let ParserMatchClass = ParserClass; 2540 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 2541 let DecoderMethod = "DecodeMemExtend"; 2542 let EncoderMethod = "getMemExtendOpValue"; 2543 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 2544} 2545 2546def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 2547def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 2548def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 2549def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 2550def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 2551 2552def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 2553def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 2554def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 2555def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 2556def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 2557 2558class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 2559 Operand wextend, Operand xextend> { 2560 // CodeGen-level pattern covering the entire addressing mode. 2561 ComplexPattern Wpat = windex; 2562 ComplexPattern Xpat = xindex; 2563 2564 // Asm-level Operand covering the valid "uxtw #3" style syntax. 2565 Operand Wext = wextend; 2566 Operand Xext = xextend; 2567} 2568 2569def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 2570def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 2571def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 2572def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 2573def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 2574 ro_Xextend128>; 2575 2576class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2577 string asm, dag ins, dag outs, list<dag> pat> 2578 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2579 bits<5> Rt; 2580 bits<5> Rn; 2581 bits<5> Rm; 2582 bits<2> extend; 2583 let Inst{31-30} = sz; 2584 let Inst{29-27} = 0b111; 2585 let Inst{26} = V; 2586 let Inst{25-24} = 0b00; 2587 let Inst{23-22} = opc; 2588 let Inst{21} = 1; 2589 let Inst{20-16} = Rm; 2590 let Inst{15} = extend{1}; // sign extend Rm? 2591 let Inst{14} = 1; 2592 let Inst{12} = extend{0}; // do shift? 2593 let Inst{11-10} = 0b10; 2594 let Inst{9-5} = Rn; 2595 let Inst{4-0} = Rt; 2596} 2597 2598class ROInstAlias<string asm, RegisterClass regtype, Instruction INST> 2599 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 2600 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 2601 2602multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2603 string asm, ValueType Ty, SDPatternOperator loadop> { 2604 let AddedComplexity = 10 in 2605 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 2606 (outs regtype:$Rt), 2607 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 2608 [(set (Ty regtype:$Rt), 2609 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 2610 ro_Wextend8:$extend)))]>, 2611 Sched<[WriteLDIdx, ReadAdrBase]> { 2612 let Inst{13} = 0b0; 2613 } 2614 2615 let AddedComplexity = 10 in 2616 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 2617 (outs regtype:$Rt), 2618 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 2619 [(set (Ty regtype:$Rt), 2620 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 2621 ro_Xextend8:$extend)))]>, 2622 Sched<[WriteLDIdx, ReadAdrBase]> { 2623 let Inst{13} = 0b1; 2624 } 2625 2626 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2627} 2628 2629multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2630 string asm, ValueType Ty, SDPatternOperator storeop> { 2631 let AddedComplexity = 10 in 2632 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 2633 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 2634 [(storeop (Ty regtype:$Rt), 2635 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 2636 ro_Wextend8:$extend))]>, 2637 Sched<[WriteSTIdx, ReadAdrBase]> { 2638 let Inst{13} = 0b0; 2639 } 2640 2641 let AddedComplexity = 10 in 2642 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 2643 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 2644 [(storeop (Ty regtype:$Rt), 2645 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 2646 ro_Xextend8:$extend))]>, 2647 Sched<[WriteSTIdx, ReadAdrBase]> { 2648 let Inst{13} = 0b1; 2649 } 2650 2651 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2652} 2653 2654class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2655 string asm, dag ins, dag outs, list<dag> pat> 2656 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2657 bits<5> Rt; 2658 bits<5> Rn; 2659 bits<5> Rm; 2660 bits<2> extend; 2661 let Inst{31-30} = sz; 2662 let Inst{29-27} = 0b111; 2663 let Inst{26} = V; 2664 let Inst{25-24} = 0b00; 2665 let Inst{23-22} = opc; 2666 let Inst{21} = 1; 2667 let Inst{20-16} = Rm; 2668 let Inst{15} = extend{1}; // sign extend Rm? 2669 let Inst{14} = 1; 2670 let Inst{12} = extend{0}; // do shift? 2671 let Inst{11-10} = 0b10; 2672 let Inst{9-5} = Rn; 2673 let Inst{4-0} = Rt; 2674} 2675 2676multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2677 string asm, ValueType Ty, SDPatternOperator loadop> { 2678 let AddedComplexity = 10 in 2679 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2680 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 2681 [(set (Ty regtype:$Rt), 2682 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 2683 ro_Wextend16:$extend)))]>, 2684 Sched<[WriteLDIdx, ReadAdrBase]> { 2685 let Inst{13} = 0b0; 2686 } 2687 2688 let AddedComplexity = 10 in 2689 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2690 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 2691 [(set (Ty regtype:$Rt), 2692 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 2693 ro_Xextend16:$extend)))]>, 2694 Sched<[WriteLDIdx, ReadAdrBase]> { 2695 let Inst{13} = 0b1; 2696 } 2697 2698 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2699} 2700 2701multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2702 string asm, ValueType Ty, SDPatternOperator storeop> { 2703 let AddedComplexity = 10 in 2704 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 2705 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 2706 [(storeop (Ty regtype:$Rt), 2707 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 2708 ro_Wextend16:$extend))]>, 2709 Sched<[WriteSTIdx, ReadAdrBase]> { 2710 let Inst{13} = 0b0; 2711 } 2712 2713 let AddedComplexity = 10 in 2714 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 2715 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 2716 [(storeop (Ty regtype:$Rt), 2717 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 2718 ro_Xextend16:$extend))]>, 2719 Sched<[WriteSTIdx, ReadAdrBase]> { 2720 let Inst{13} = 0b1; 2721 } 2722 2723 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2724} 2725 2726class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2727 string asm, dag ins, dag outs, list<dag> pat> 2728 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2729 bits<5> Rt; 2730 bits<5> Rn; 2731 bits<5> Rm; 2732 bits<2> extend; 2733 let Inst{31-30} = sz; 2734 let Inst{29-27} = 0b111; 2735 let Inst{26} = V; 2736 let Inst{25-24} = 0b00; 2737 let Inst{23-22} = opc; 2738 let Inst{21} = 1; 2739 let Inst{20-16} = Rm; 2740 let Inst{15} = extend{1}; // sign extend Rm? 2741 let Inst{14} = 1; 2742 let Inst{12} = extend{0}; // do shift? 2743 let Inst{11-10} = 0b10; 2744 let Inst{9-5} = Rn; 2745 let Inst{4-0} = Rt; 2746} 2747 2748multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2749 string asm, ValueType Ty, SDPatternOperator loadop> { 2750 let AddedComplexity = 10 in 2751 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2752 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 2753 [(set (Ty regtype:$Rt), 2754 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 2755 ro_Wextend32:$extend)))]>, 2756 Sched<[WriteLDIdx, ReadAdrBase]> { 2757 let Inst{13} = 0b0; 2758 } 2759 2760 let AddedComplexity = 10 in 2761 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2762 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 2763 [(set (Ty regtype:$Rt), 2764 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 2765 ro_Xextend32:$extend)))]>, 2766 Sched<[WriteLDIdx, ReadAdrBase]> { 2767 let Inst{13} = 0b1; 2768 } 2769 2770 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2771} 2772 2773multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2774 string asm, ValueType Ty, SDPatternOperator storeop> { 2775 let AddedComplexity = 10 in 2776 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 2777 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 2778 [(storeop (Ty regtype:$Rt), 2779 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 2780 ro_Wextend32:$extend))]>, 2781 Sched<[WriteSTIdx, ReadAdrBase]> { 2782 let Inst{13} = 0b0; 2783 } 2784 2785 let AddedComplexity = 10 in 2786 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 2787 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 2788 [(storeop (Ty regtype:$Rt), 2789 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 2790 ro_Xextend32:$extend))]>, 2791 Sched<[WriteSTIdx, ReadAdrBase]> { 2792 let Inst{13} = 0b1; 2793 } 2794 2795 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2796} 2797 2798class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2799 string asm, dag ins, dag outs, list<dag> pat> 2800 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2801 bits<5> Rt; 2802 bits<5> Rn; 2803 bits<5> Rm; 2804 bits<2> extend; 2805 let Inst{31-30} = sz; 2806 let Inst{29-27} = 0b111; 2807 let Inst{26} = V; 2808 let Inst{25-24} = 0b00; 2809 let Inst{23-22} = opc; 2810 let Inst{21} = 1; 2811 let Inst{20-16} = Rm; 2812 let Inst{15} = extend{1}; // sign extend Rm? 2813 let Inst{14} = 1; 2814 let Inst{12} = extend{0}; // do shift? 2815 let Inst{11-10} = 0b10; 2816 let Inst{9-5} = Rn; 2817 let Inst{4-0} = Rt; 2818} 2819 2820multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2821 string asm, ValueType Ty, SDPatternOperator loadop> { 2822 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2823 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2824 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2825 [(set (Ty regtype:$Rt), 2826 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2827 ro_Wextend64:$extend)))]>, 2828 Sched<[WriteLDIdx, ReadAdrBase]> { 2829 let Inst{13} = 0b0; 2830 } 2831 2832 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2833 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2834 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2835 [(set (Ty regtype:$Rt), 2836 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2837 ro_Xextend64:$extend)))]>, 2838 Sched<[WriteLDIdx, ReadAdrBase]> { 2839 let Inst{13} = 0b1; 2840 } 2841 2842 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2843} 2844 2845multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2846 string asm, ValueType Ty, SDPatternOperator storeop> { 2847 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2848 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 2849 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2850 [(storeop (Ty regtype:$Rt), 2851 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2852 ro_Wextend64:$extend))]>, 2853 Sched<[WriteSTIdx, ReadAdrBase]> { 2854 let Inst{13} = 0b0; 2855 } 2856 2857 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2858 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 2859 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2860 [(storeop (Ty regtype:$Rt), 2861 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2862 ro_Xextend64:$extend))]>, 2863 Sched<[WriteSTIdx, ReadAdrBase]> { 2864 let Inst{13} = 0b1; 2865 } 2866 2867 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2868} 2869 2870class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2871 string asm, dag ins, dag outs, list<dag> pat> 2872 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2873 bits<5> Rt; 2874 bits<5> Rn; 2875 bits<5> Rm; 2876 bits<2> extend; 2877 let Inst{31-30} = sz; 2878 let Inst{29-27} = 0b111; 2879 let Inst{26} = V; 2880 let Inst{25-24} = 0b00; 2881 let Inst{23-22} = opc; 2882 let Inst{21} = 1; 2883 let Inst{20-16} = Rm; 2884 let Inst{15} = extend{1}; // sign extend Rm? 2885 let Inst{14} = 1; 2886 let Inst{12} = extend{0}; // do shift? 2887 let Inst{11-10} = 0b10; 2888 let Inst{9-5} = Rn; 2889 let Inst{4-0} = Rt; 2890} 2891 2892multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2893 string asm, ValueType Ty, SDPatternOperator loadop> { 2894 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2895 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2896 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 2897 [(set (Ty regtype:$Rt), 2898 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 2899 ro_Wextend128:$extend)))]>, 2900 Sched<[WriteLDIdx, ReadAdrBase]> { 2901 let Inst{13} = 0b0; 2902 } 2903 2904 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2905 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2906 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 2907 [(set (Ty regtype:$Rt), 2908 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 2909 ro_Xextend128:$extend)))]>, 2910 Sched<[WriteLDIdx, ReadAdrBase]> { 2911 let Inst{13} = 0b1; 2912 } 2913 2914 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2915} 2916 2917multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2918 string asm, ValueType Ty, SDPatternOperator storeop> { 2919 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2920 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 2921 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 2922 [(storeop (Ty regtype:$Rt), 2923 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 2924 ro_Wextend128:$extend))]>, 2925 Sched<[WriteSTIdx, ReadAdrBase]> { 2926 let Inst{13} = 0b0; 2927 } 2928 2929 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2930 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 2931 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 2932 [(storeop (Ty regtype:$Rt), 2933 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 2934 ro_Xextend128:$extend))]>, 2935 Sched<[WriteSTIdx, ReadAdrBase]> { 2936 let Inst{13} = 0b1; 2937 } 2938 2939 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2940} 2941 2942let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2943class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 2944 string asm, list<dag> pat> 2945 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 2946 Sched<[WriteLD]> { 2947 bits<5> Rt; 2948 bits<5> Rn; 2949 bits<5> Rm; 2950 bits<2> extend; 2951 let Inst{31-30} = sz; 2952 let Inst{29-27} = 0b111; 2953 let Inst{26} = V; 2954 let Inst{25-24} = 0b00; 2955 let Inst{23-22} = opc; 2956 let Inst{21} = 1; 2957 let Inst{20-16} = Rm; 2958 let Inst{15} = extend{1}; // sign extend Rm? 2959 let Inst{14} = 1; 2960 let Inst{12} = extend{0}; // do shift? 2961 let Inst{11-10} = 0b10; 2962 let Inst{9-5} = Rn; 2963 let Inst{4-0} = Rt; 2964} 2965 2966multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 2967 def roW : BasePrefetchRO<sz, V, opc, (outs), 2968 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2969 asm, [(AArch64Prefetch imm:$Rt, 2970 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2971 ro_Wextend64:$extend))]> { 2972 let Inst{13} = 0b0; 2973 } 2974 2975 def roX : BasePrefetchRO<sz, V, opc, (outs), 2976 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2977 asm, [(AArch64Prefetch imm:$Rt, 2978 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2979 ro_Xextend64:$extend))]> { 2980 let Inst{13} = 0b1; 2981 } 2982 2983 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 2984 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 2985 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 2986} 2987 2988//--- 2989// Load/store unscaled immediate 2990//--- 2991 2992def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 2993def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 2994def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 2995def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 2996def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 2997 2998class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2999 string asm, list<dag> pattern> 3000 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3001 bits<5> Rt; 3002 bits<5> Rn; 3003 bits<9> offset; 3004 let Inst{31-30} = sz; 3005 let Inst{29-27} = 0b111; 3006 let Inst{26} = V; 3007 let Inst{25-24} = 0b00; 3008 let Inst{23-22} = opc; 3009 let Inst{21} = 0; 3010 let Inst{20-12} = offset; 3011 let Inst{11-10} = 0b00; 3012 let Inst{9-5} = Rn; 3013 let Inst{4-0} = Rt; 3014 3015 let DecoderMethod = "DecodeSignedLdStInstruction"; 3016} 3017 3018multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3019 string asm, list<dag> pattern> { 3020 let AddedComplexity = 1 in // try this before LoadUI 3021 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3022 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3023 Sched<[WriteLD]>; 3024 3025 def : InstAlias<asm # "\t$Rt, [$Rn]", 3026 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3027} 3028 3029multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3030 string asm, list<dag> pattern> { 3031 let AddedComplexity = 1 in // try this before StoreUI 3032 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3033 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3034 asm, pattern>, 3035 Sched<[WriteST]>; 3036 3037 def : InstAlias<asm # "\t$Rt, [$Rn]", 3038 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3039} 3040 3041multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3042 list<dag> pat> { 3043 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3044 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3045 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3046 asm, pat>, 3047 Sched<[WriteLD]>; 3048 3049 def : InstAlias<asm # "\t$Rt, [$Rn]", 3050 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3051} 3052 3053//--- 3054// Load/store unscaled immediate, unprivileged 3055//--- 3056 3057class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3058 dag oops, dag iops, string asm> 3059 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3060 bits<5> Rt; 3061 bits<5> Rn; 3062 bits<9> offset; 3063 let Inst{31-30} = sz; 3064 let Inst{29-27} = 0b111; 3065 let Inst{26} = V; 3066 let Inst{25-24} = 0b00; 3067 let Inst{23-22} = opc; 3068 let Inst{21} = 0; 3069 let Inst{20-12} = offset; 3070 let Inst{11-10} = 0b10; 3071 let Inst{9-5} = Rn; 3072 let Inst{4-0} = Rt; 3073 3074 let DecoderMethod = "DecodeSignedLdStInstruction"; 3075} 3076 3077multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3078 RegisterClass regtype, string asm> { 3079 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3080 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3081 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3082 Sched<[WriteLD]>; 3083 3084 def : InstAlias<asm # "\t$Rt, [$Rn]", 3085 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3086} 3087 3088multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3089 RegisterClass regtype, string asm> { 3090 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3091 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3092 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3093 asm>, 3094 Sched<[WriteST]>; 3095 3096 def : InstAlias<asm # "\t$Rt, [$Rn]", 3097 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3098} 3099 3100//--- 3101// Load/store pre-indexed 3102//--- 3103 3104class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3105 string asm, string cstr, list<dag> pat> 3106 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3107 bits<5> Rt; 3108 bits<5> Rn; 3109 bits<9> offset; 3110 let Inst{31-30} = sz; 3111 let Inst{29-27} = 0b111; 3112 let Inst{26} = V; 3113 let Inst{25-24} = 0; 3114 let Inst{23-22} = opc; 3115 let Inst{21} = 0; 3116 let Inst{20-12} = offset; 3117 let Inst{11-10} = 0b11; 3118 let Inst{9-5} = Rn; 3119 let Inst{4-0} = Rt; 3120 3121 let DecoderMethod = "DecodeSignedLdStInstruction"; 3122} 3123 3124let hasSideEffects = 0 in { 3125let mayStore = 0, mayLoad = 1 in 3126class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3127 string asm> 3128 : BaseLoadStorePreIdx<sz, V, opc, 3129 (outs GPR64sp:$wback, regtype:$Rt), 3130 (ins GPR64sp:$Rn, simm9:$offset), asm, 3131 "$Rn = $wback,@earlyclobber $wback", []>, 3132 Sched<[WriteLD, WriteAdr]>; 3133 3134let mayStore = 1, mayLoad = 0 in 3135class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3136 string asm, SDPatternOperator storeop, ValueType Ty> 3137 : BaseLoadStorePreIdx<sz, V, opc, 3138 (outs GPR64sp:$wback), 3139 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3140 asm, "$Rn = $wback,@earlyclobber $wback", 3141 [(set GPR64sp:$wback, 3142 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3143 Sched<[WriteAdr, WriteST]>; 3144} // hasSideEffects = 0 3145 3146//--- 3147// Load/store post-indexed 3148//--- 3149 3150class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3151 string asm, string cstr, list<dag> pat> 3152 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3153 bits<5> Rt; 3154 bits<5> Rn; 3155 bits<9> offset; 3156 let Inst{31-30} = sz; 3157 let Inst{29-27} = 0b111; 3158 let Inst{26} = V; 3159 let Inst{25-24} = 0b00; 3160 let Inst{23-22} = opc; 3161 let Inst{21} = 0b0; 3162 let Inst{20-12} = offset; 3163 let Inst{11-10} = 0b01; 3164 let Inst{9-5} = Rn; 3165 let Inst{4-0} = Rt; 3166 3167 let DecoderMethod = "DecodeSignedLdStInstruction"; 3168} 3169 3170let hasSideEffects = 0 in { 3171let mayStore = 0, mayLoad = 1 in 3172class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3173 string asm> 3174 : BaseLoadStorePostIdx<sz, V, opc, 3175 (outs GPR64sp:$wback, regtype:$Rt), 3176 (ins GPR64sp:$Rn, simm9:$offset), 3177 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3178 Sched<[WriteLD, WriteI]>; 3179 3180let mayStore = 1, mayLoad = 0 in 3181class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3182 string asm, SDPatternOperator storeop, ValueType Ty> 3183 : BaseLoadStorePostIdx<sz, V, opc, 3184 (outs GPR64sp:$wback), 3185 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3186 asm, "$Rn = $wback,@earlyclobber $wback", 3187 [(set GPR64sp:$wback, 3188 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3189 Sched<[WriteAdr, WriteST, ReadAdrBase]>; 3190} // hasSideEffects = 0 3191 3192 3193//--- 3194// Load/store pair 3195//--- 3196 3197// (indexed, offset) 3198 3199class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 3200 string asm> 3201 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3202 bits<5> Rt; 3203 bits<5> Rt2; 3204 bits<5> Rn; 3205 bits<7> offset; 3206 let Inst{31-30} = opc; 3207 let Inst{29-27} = 0b101; 3208 let Inst{26} = V; 3209 let Inst{25-23} = 0b010; 3210 let Inst{22} = L; 3211 let Inst{21-15} = offset; 3212 let Inst{14-10} = Rt2; 3213 let Inst{9-5} = Rn; 3214 let Inst{4-0} = Rt; 3215 3216 let DecoderMethod = "DecodePairLdStInstruction"; 3217} 3218 3219multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype, 3220 Operand indextype, string asm> { 3221 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3222 def i : BaseLoadStorePairOffset<opc, V, 1, 3223 (outs regtype:$Rt, regtype:$Rt2), 3224 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3225 Sched<[WriteLD, WriteLDHi]>; 3226 3227 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3228 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3229 GPR64sp:$Rn, 0)>; 3230} 3231 3232 3233multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype, 3234 Operand indextype, string asm> { 3235 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 3236 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 3237 (ins regtype:$Rt, regtype:$Rt2, 3238 GPR64sp:$Rn, indextype:$offset), 3239 asm>, 3240 Sched<[WriteSTP]>; 3241 3242 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3243 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3244 GPR64sp:$Rn, 0)>; 3245} 3246 3247// (pre-indexed) 3248class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3249 string asm> 3250 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 3251 bits<5> Rt; 3252 bits<5> Rt2; 3253 bits<5> Rn; 3254 bits<7> offset; 3255 let Inst{31-30} = opc; 3256 let Inst{29-27} = 0b101; 3257 let Inst{26} = V; 3258 let Inst{25-23} = 0b011; 3259 let Inst{22} = L; 3260 let Inst{21-15} = offset; 3261 let Inst{14-10} = Rt2; 3262 let Inst{9-5} = Rn; 3263 let Inst{4-0} = Rt; 3264 3265 let DecoderMethod = "DecodePairLdStInstruction"; 3266} 3267 3268let hasSideEffects = 0 in { 3269let mayStore = 0, mayLoad = 1 in 3270class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype, 3271 Operand indextype, string asm> 3272 : BaseLoadStorePairPreIdx<opc, V, 1, 3273 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3274 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3275 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3276 3277let mayStore = 1, mayLoad = 0 in 3278class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype, 3279 Operand indextype, string asm> 3280 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 3281 (ins regtype:$Rt, regtype:$Rt2, 3282 GPR64sp:$Rn, indextype:$offset), 3283 asm>, 3284 Sched<[WriteAdr, WriteSTP]>; 3285} // hasSideEffects = 0 3286 3287// (post-indexed) 3288 3289class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3290 string asm> 3291 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 3292 bits<5> Rt; 3293 bits<5> Rt2; 3294 bits<5> Rn; 3295 bits<7> offset; 3296 let Inst{31-30} = opc; 3297 let Inst{29-27} = 0b101; 3298 let Inst{26} = V; 3299 let Inst{25-23} = 0b001; 3300 let Inst{22} = L; 3301 let Inst{21-15} = offset; 3302 let Inst{14-10} = Rt2; 3303 let Inst{9-5} = Rn; 3304 let Inst{4-0} = Rt; 3305 3306 let DecoderMethod = "DecodePairLdStInstruction"; 3307} 3308 3309let hasSideEffects = 0 in { 3310let mayStore = 0, mayLoad = 1 in 3311class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype, 3312 Operand idxtype, string asm> 3313 : BaseLoadStorePairPostIdx<opc, V, 1, 3314 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3315 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 3316 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3317 3318let mayStore = 1, mayLoad = 0 in 3319class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype, 3320 Operand idxtype, string asm> 3321 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 3322 (ins regtype:$Rt, regtype:$Rt2, 3323 GPR64sp:$Rn, idxtype:$offset), 3324 asm>, 3325 Sched<[WriteAdr, WriteSTP]>; 3326} // hasSideEffects = 0 3327 3328// (no-allocate) 3329 3330class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 3331 string asm> 3332 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3333 bits<5> Rt; 3334 bits<5> Rt2; 3335 bits<5> Rn; 3336 bits<7> offset; 3337 let Inst{31-30} = opc; 3338 let Inst{29-27} = 0b101; 3339 let Inst{26} = V; 3340 let Inst{25-23} = 0b000; 3341 let Inst{22} = L; 3342 let Inst{21-15} = offset; 3343 let Inst{14-10} = Rt2; 3344 let Inst{9-5} = Rn; 3345 let Inst{4-0} = Rt; 3346 3347 let DecoderMethod = "DecodePairLdStInstruction"; 3348} 3349 3350multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3351 Operand indextype, string asm> { 3352 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3353 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 3354 (outs regtype:$Rt, regtype:$Rt2), 3355 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3356 Sched<[WriteLD, WriteLDHi]>; 3357 3358 3359 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3360 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3361 GPR64sp:$Rn, 0)>; 3362} 3363 3364multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3365 Operand indextype, string asm> { 3366 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 3367 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 3368 (ins regtype:$Rt, regtype:$Rt2, 3369 GPR64sp:$Rn, indextype:$offset), 3370 asm>, 3371 Sched<[WriteSTP]>; 3372 3373 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3374 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3375 GPR64sp:$Rn, 0)>; 3376} 3377 3378//--- 3379// Load/store exclusive 3380//--- 3381 3382// True exclusive operations write to and/or read from the system's exclusive 3383// monitors, which as far as a compiler is concerned can be modelled as a 3384// random shared memory address. Hence LoadExclusive mayStore. 3385// 3386// Since these instructions have the undefined register bits set to 1 in 3387// their canonical form, we need a post encoder method to set those bits 3388// to 1 when encoding these instructions. We do this using the 3389// fixLoadStoreExclusive function. This function has template parameters: 3390// 3391// fixLoadStoreExclusive<int hasRs, int hasRt2> 3392// 3393// hasRs indicates that the instruction uses the Rs field, so we won't set 3394// it to 1 (and the same for Rt2). We don't need template parameters for 3395// the other register fields since Rt and Rn are always used. 3396// 3397let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 3398class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3399 dag oops, dag iops, string asm, string operands> 3400 : I<oops, iops, asm, operands, "", []> { 3401 let Inst{31-30} = sz; 3402 let Inst{29-24} = 0b001000; 3403 let Inst{23} = o2; 3404 let Inst{22} = L; 3405 let Inst{21} = o1; 3406 let Inst{15} = o0; 3407 3408 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 3409} 3410 3411// Neither Rs nor Rt2 operands. 3412class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3413 dag oops, dag iops, string asm, string operands> 3414 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 3415 bits<5> Rt; 3416 bits<5> Rn; 3417 let Inst{20-16} = 0b11111; 3418 let Unpredictable{20-16} = 0b11111; 3419 let Inst{14-10} = 0b11111; 3420 let Unpredictable{14-10} = 0b11111; 3421 let Inst{9-5} = Rn; 3422 let Inst{4-0} = Rt; 3423 3424 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 3425} 3426 3427// Simple load acquires don't set the exclusive monitor 3428let mayLoad = 1, mayStore = 0 in 3429class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3430 RegisterClass regtype, string asm> 3431 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 3432 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 3433 Sched<[WriteLD]>; 3434 3435class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3436 RegisterClass regtype, string asm> 3437 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 3438 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 3439 Sched<[WriteLD]>; 3440 3441class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3442 RegisterClass regtype, string asm> 3443 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 3444 (outs regtype:$Rt, regtype:$Rt2), 3445 (ins GPR64sp0:$Rn), asm, 3446 "\t$Rt, $Rt2, [$Rn]">, 3447 Sched<[WriteLD, WriteLDHi]> { 3448 bits<5> Rt; 3449 bits<5> Rt2; 3450 bits<5> Rn; 3451 let Inst{14-10} = Rt2; 3452 let Inst{9-5} = Rn; 3453 let Inst{4-0} = Rt; 3454 3455 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 3456} 3457 3458// Simple store release operations do not check the exclusive monitor. 3459let mayLoad = 0, mayStore = 1 in 3460class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3461 RegisterClass regtype, string asm> 3462 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 3463 (ins regtype:$Rt, GPR64sp0:$Rn), 3464 asm, "\t$Rt, [$Rn]">, 3465 Sched<[WriteST]>; 3466 3467let mayLoad = 1, mayStore = 1 in 3468class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3469 RegisterClass regtype, string asm> 3470 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 3471 (ins regtype:$Rt, GPR64sp0:$Rn), 3472 asm, "\t$Ws, $Rt, [$Rn]">, 3473 Sched<[WriteSTX]> { 3474 bits<5> Ws; 3475 bits<5> Rt; 3476 bits<5> Rn; 3477 let Inst{20-16} = Ws; 3478 let Inst{9-5} = Rn; 3479 let Inst{4-0} = Rt; 3480 3481 let Constraints = "@earlyclobber $Ws"; 3482 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 3483} 3484 3485class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3486 RegisterClass regtype, string asm> 3487 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 3488 (outs GPR32:$Ws), 3489 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 3490 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 3491 Sched<[WriteSTX]> { 3492 bits<5> Ws; 3493 bits<5> Rt; 3494 bits<5> Rt2; 3495 bits<5> Rn; 3496 let Inst{20-16} = Ws; 3497 let Inst{14-10} = Rt2; 3498 let Inst{9-5} = Rn; 3499 let Inst{4-0} = Rt; 3500 3501 let Constraints = "@earlyclobber $Ws"; 3502} 3503 3504//--- 3505// Exception generation 3506//--- 3507 3508let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3509class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 3510 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>, 3511 Sched<[WriteSys]> { 3512 bits<16> imm; 3513 let Inst{31-24} = 0b11010100; 3514 let Inst{23-21} = op1; 3515 let Inst{20-5} = imm; 3516 let Inst{4-2} = 0b000; 3517 let Inst{1-0} = ll; 3518} 3519 3520let Predicates = [HasFPARMv8] in { 3521 3522//--- 3523// Floating point to integer conversion 3524//--- 3525 3526class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 3527 RegisterClass srcType, RegisterClass dstType, 3528 string asm, list<dag> pattern> 3529 : I<(outs dstType:$Rd), (ins srcType:$Rn), 3530 asm, "\t$Rd, $Rn", "", pattern>, 3531 Sched<[WriteFCvt]> { 3532 bits<5> Rd; 3533 bits<5> Rn; 3534 let Inst{30-29} = 0b00; 3535 let Inst{28-24} = 0b11110; 3536 let Inst{23-22} = type; 3537 let Inst{21} = 1; 3538 let Inst{20-19} = rmode; 3539 let Inst{18-16} = opcode; 3540 let Inst{15-10} = 0; 3541 let Inst{9-5} = Rn; 3542 let Inst{4-0} = Rd; 3543} 3544 3545let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3546class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 3547 RegisterClass srcType, RegisterClass dstType, 3548 Operand immType, string asm, list<dag> pattern> 3549 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 3550 asm, "\t$Rd, $Rn, $scale", "", pattern>, 3551 Sched<[WriteFCvt]> { 3552 bits<5> Rd; 3553 bits<5> Rn; 3554 bits<6> scale; 3555 let Inst{30-29} = 0b00; 3556 let Inst{28-24} = 0b11110; 3557 let Inst{23-22} = type; 3558 let Inst{21} = 0; 3559 let Inst{20-19} = rmode; 3560 let Inst{18-16} = opcode; 3561 let Inst{15-10} = scale; 3562 let Inst{9-5} = Rn; 3563 let Inst{4-0} = Rd; 3564} 3565 3566multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 3567 SDPatternOperator OpN> { 3568 // Unscaled half-precision to 32-bit 3569 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 3570 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> { 3571 let Inst{31} = 0; // 32-bit GPR flag 3572 let Predicates = [HasFullFP16]; 3573 } 3574 3575 // Unscaled half-precision to 64-bit 3576 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 3577 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> { 3578 let Inst{31} = 1; // 64-bit GPR flag 3579 let Predicates = [HasFullFP16]; 3580 } 3581 3582 // Unscaled single-precision to 32-bit 3583 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 3584 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 3585 let Inst{31} = 0; // 32-bit GPR flag 3586 } 3587 3588 // Unscaled single-precision to 64-bit 3589 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 3590 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 3591 let Inst{31} = 1; // 64-bit GPR flag 3592 } 3593 3594 // Unscaled double-precision to 32-bit 3595 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 3596 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 3597 let Inst{31} = 0; // 32-bit GPR flag 3598 } 3599 3600 // Unscaled double-precision to 64-bit 3601 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 3602 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 3603 let Inst{31} = 1; // 64-bit GPR flag 3604 } 3605} 3606 3607multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 3608 SDPatternOperator OpN> { 3609 // Scaled half-precision to 32-bit 3610 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 3611 fixedpoint_f16_i32, asm, 3612 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn, 3613 fixedpoint_f16_i32:$scale)))]> { 3614 let Inst{31} = 0; // 32-bit GPR flag 3615 let scale{5} = 1; 3616 let Predicates = [HasFullFP16]; 3617 } 3618 3619 // Scaled half-precision to 64-bit 3620 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 3621 fixedpoint_f16_i64, asm, 3622 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn, 3623 fixedpoint_f16_i64:$scale)))]> { 3624 let Inst{31} = 1; // 64-bit GPR flag 3625 let Predicates = [HasFullFP16]; 3626 } 3627 3628 // Scaled single-precision to 32-bit 3629 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 3630 fixedpoint_f32_i32, asm, 3631 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 3632 fixedpoint_f32_i32:$scale)))]> { 3633 let Inst{31} = 0; // 32-bit GPR flag 3634 let scale{5} = 1; 3635 } 3636 3637 // Scaled single-precision to 64-bit 3638 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 3639 fixedpoint_f32_i64, asm, 3640 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 3641 fixedpoint_f32_i64:$scale)))]> { 3642 let Inst{31} = 1; // 64-bit GPR flag 3643 } 3644 3645 // Scaled double-precision to 32-bit 3646 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 3647 fixedpoint_f64_i32, asm, 3648 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 3649 fixedpoint_f64_i32:$scale)))]> { 3650 let Inst{31} = 0; // 32-bit GPR flag 3651 let scale{5} = 1; 3652 } 3653 3654 // Scaled double-precision to 64-bit 3655 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 3656 fixedpoint_f64_i64, asm, 3657 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 3658 fixedpoint_f64_i64:$scale)))]> { 3659 let Inst{31} = 1; // 64-bit GPR flag 3660 } 3661} 3662 3663//--- 3664// Integer to floating point conversion 3665//--- 3666 3667let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 3668class BaseIntegerToFP<bit isUnsigned, 3669 RegisterClass srcType, RegisterClass dstType, 3670 Operand immType, string asm, list<dag> pattern> 3671 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 3672 asm, "\t$Rd, $Rn, $scale", "", pattern>, 3673 Sched<[WriteFCvt]> { 3674 bits<5> Rd; 3675 bits<5> Rn; 3676 bits<6> scale; 3677 let Inst{30-24} = 0b0011110; 3678 let Inst{21-17} = 0b00001; 3679 let Inst{16} = isUnsigned; 3680 let Inst{15-10} = scale; 3681 let Inst{9-5} = Rn; 3682 let Inst{4-0} = Rd; 3683} 3684 3685class BaseIntegerToFPUnscaled<bit isUnsigned, 3686 RegisterClass srcType, RegisterClass dstType, 3687 ValueType dvt, string asm, SDNode node> 3688 : I<(outs dstType:$Rd), (ins srcType:$Rn), 3689 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 3690 Sched<[WriteFCvt]> { 3691 bits<5> Rd; 3692 bits<5> Rn; 3693 bits<6> scale; 3694 let Inst{30-24} = 0b0011110; 3695 let Inst{21-17} = 0b10001; 3696 let Inst{16} = isUnsigned; 3697 let Inst{15-10} = 0b000000; 3698 let Inst{9-5} = Rn; 3699 let Inst{4-0} = Rd; 3700} 3701 3702multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 3703 // Unscaled 3704 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 3705 let Inst{31} = 0; // 32-bit GPR flag 3706 let Inst{23-22} = 0b11; // 16-bit FPR flag 3707 let Predicates = [HasFullFP16]; 3708 } 3709 3710 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 3711 let Inst{31} = 0; // 32-bit GPR flag 3712 let Inst{23-22} = 0b00; // 32-bit FPR flag 3713 } 3714 3715 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 3716 let Inst{31} = 0; // 32-bit GPR flag 3717 let Inst{23-22} = 0b01; // 64-bit FPR flag 3718 } 3719 3720 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 3721 let Inst{31} = 1; // 64-bit GPR flag 3722 let Inst{23-22} = 0b11; // 16-bit FPR flag 3723 let Predicates = [HasFullFP16]; 3724 } 3725 3726 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 3727 let Inst{31} = 1; // 64-bit GPR flag 3728 let Inst{23-22} = 0b00; // 32-bit FPR flag 3729 } 3730 3731 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 3732 let Inst{31} = 1; // 64-bit GPR flag 3733 let Inst{23-22} = 0b01; // 64-bit FPR flag 3734 } 3735 3736 // Scaled 3737 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 3738 [(set FPR16:$Rd, 3739 (fdiv (node GPR32:$Rn), 3740 fixedpoint_f16_i32:$scale))]> { 3741 let Inst{31} = 0; // 32-bit GPR flag 3742 let Inst{23-22} = 0b11; // 16-bit FPR flag 3743 let scale{5} = 1; 3744 let Predicates = [HasFullFP16]; 3745 } 3746 3747 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 3748 [(set FPR32:$Rd, 3749 (fdiv (node GPR32:$Rn), 3750 fixedpoint_f32_i32:$scale))]> { 3751 let Inst{31} = 0; // 32-bit GPR flag 3752 let Inst{23-22} = 0b00; // 32-bit FPR flag 3753 let scale{5} = 1; 3754 } 3755 3756 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 3757 [(set FPR64:$Rd, 3758 (fdiv (node GPR32:$Rn), 3759 fixedpoint_f64_i32:$scale))]> { 3760 let Inst{31} = 0; // 32-bit GPR flag 3761 let Inst{23-22} = 0b01; // 64-bit FPR flag 3762 let scale{5} = 1; 3763 } 3764 3765 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 3766 [(set FPR16:$Rd, 3767 (fdiv (node GPR64:$Rn), 3768 fixedpoint_f16_i64:$scale))]> { 3769 let Inst{31} = 1; // 64-bit GPR flag 3770 let Inst{23-22} = 0b11; // 16-bit FPR flag 3771 let Predicates = [HasFullFP16]; 3772 } 3773 3774 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 3775 [(set FPR32:$Rd, 3776 (fdiv (node GPR64:$Rn), 3777 fixedpoint_f32_i64:$scale))]> { 3778 let Inst{31} = 1; // 64-bit GPR flag 3779 let Inst{23-22} = 0b00; // 32-bit FPR flag 3780 } 3781 3782 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 3783 [(set FPR64:$Rd, 3784 (fdiv (node GPR64:$Rn), 3785 fixedpoint_f64_i64:$scale))]> { 3786 let Inst{31} = 1; // 64-bit GPR flag 3787 let Inst{23-22} = 0b01; // 64-bit FPR flag 3788 } 3789} 3790 3791//--- 3792// Unscaled integer <-> floating point conversion (i.e. FMOV) 3793//--- 3794 3795let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3796class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 3797 RegisterClass srcType, RegisterClass dstType, 3798 string asm> 3799 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 3800 // We use COPY_TO_REGCLASS for these bitconvert operations. 3801 // copyPhysReg() expands the resultant COPY instructions after 3802 // regalloc is done. This gives greater freedom for the allocator 3803 // and related passes (coalescing, copy propagation, et. al.) to 3804 // be more effective. 3805 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 3806 Sched<[WriteFCopy]> { 3807 bits<5> Rd; 3808 bits<5> Rn; 3809 let Inst{30-24} = 0b0011110; 3810 let Inst{21} = 1; 3811 let Inst{20-19} = rmode; 3812 let Inst{18-16} = opcode; 3813 let Inst{15-10} = 0b000000; 3814 let Inst{9-5} = Rn; 3815 let Inst{4-0} = Rd; 3816} 3817 3818let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3819class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 3820 RegisterClass srcType, RegisterOperand dstType, string asm, 3821 string kind> 3822 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 3823 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 3824 Sched<[WriteFCopy]> { 3825 bits<5> Rd; 3826 bits<5> Rn; 3827 let Inst{30-23} = 0b00111101; 3828 let Inst{21} = 1; 3829 let Inst{20-19} = rmode; 3830 let Inst{18-16} = opcode; 3831 let Inst{15-10} = 0b000000; 3832 let Inst{9-5} = Rn; 3833 let Inst{4-0} = Rd; 3834 3835 let DecoderMethod = "DecodeFMOVLaneInstruction"; 3836} 3837 3838let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3839class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 3840 RegisterOperand srcType, RegisterClass dstType, string asm, 3841 string kind> 3842 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 3843 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 3844 Sched<[WriteFCopy]> { 3845 bits<5> Rd; 3846 bits<5> Rn; 3847 let Inst{30-23} = 0b00111101; 3848 let Inst{21} = 1; 3849 let Inst{20-19} = rmode; 3850 let Inst{18-16} = opcode; 3851 let Inst{15-10} = 0b000000; 3852 let Inst{9-5} = Rn; 3853 let Inst{4-0} = Rd; 3854 3855 let DecoderMethod = "DecodeFMOVLaneInstruction"; 3856} 3857 3858 3859multiclass UnscaledConversion<string asm> { 3860 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 3861 let Inst{31} = 0; // 32-bit GPR flag 3862 let Inst{23-22} = 0b11; // 16-bit FPR flag 3863 let Predicates = [HasFullFP16]; 3864 } 3865 3866 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 3867 let Inst{31} = 1; // 64-bit GPR flag 3868 let Inst{23-22} = 0b11; // 16-bit FPR flag 3869 let Predicates = [HasFullFP16]; 3870 } 3871 3872 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 3873 let Inst{31} = 0; // 32-bit GPR flag 3874 let Inst{23-22} = 0b00; // 32-bit FPR flag 3875 } 3876 3877 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 3878 let Inst{31} = 1; // 64-bit GPR flag 3879 let Inst{23-22} = 0b01; // 64-bit FPR flag 3880 } 3881 3882 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 3883 let Inst{31} = 0; // 32-bit GPR flag 3884 let Inst{23-22} = 0b11; // 16-bit FPR flag 3885 let Predicates = [HasFullFP16]; 3886 } 3887 3888 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 3889 let Inst{31} = 1; // 64-bit GPR flag 3890 let Inst{23-22} = 0b11; // 16-bit FPR flag 3891 let Predicates = [HasFullFP16]; 3892 } 3893 3894 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 3895 let Inst{31} = 0; // 32-bit GPR flag 3896 let Inst{23-22} = 0b00; // 32-bit FPR flag 3897 } 3898 3899 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 3900 let Inst{31} = 1; // 64-bit GPR flag 3901 let Inst{23-22} = 0b01; // 64-bit FPR flag 3902 } 3903 3904 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 3905 asm, ".d"> { 3906 let Inst{31} = 1; 3907 let Inst{22} = 0; 3908 } 3909 3910 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 3911 asm, ".d"> { 3912 let Inst{31} = 1; 3913 let Inst{22} = 0; 3914 } 3915} 3916 3917//--- 3918// Floating point conversion 3919//--- 3920 3921class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 3922 RegisterClass srcType, string asm, list<dag> pattern> 3923 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 3924 Sched<[WriteFCvt]> { 3925 bits<5> Rd; 3926 bits<5> Rn; 3927 let Inst{31-24} = 0b00011110; 3928 let Inst{23-22} = type; 3929 let Inst{21-17} = 0b10001; 3930 let Inst{16-15} = opcode; 3931 let Inst{14-10} = 0b10000; 3932 let Inst{9-5} = Rn; 3933 let Inst{4-0} = Rd; 3934} 3935 3936multiclass FPConversion<string asm> { 3937 // Double-precision to Half-precision 3938 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 3939 [(set FPR16:$Rd, (fround FPR64:$Rn))]>; 3940 3941 // Double-precision to Single-precision 3942 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 3943 [(set FPR32:$Rd, (fround FPR64:$Rn))]>; 3944 3945 // Half-precision to Double-precision 3946 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 3947 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>; 3948 3949 // Half-precision to Single-precision 3950 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 3951 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>; 3952 3953 // Single-precision to Double-precision 3954 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 3955 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>; 3956 3957 // Single-precision to Half-precision 3958 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 3959 [(set FPR16:$Rd, (fround FPR32:$Rn))]>; 3960} 3961 3962//--- 3963// Single operand floating point data processing 3964//--- 3965 3966let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3967class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype, 3968 ValueType vt, string asm, SDPatternOperator node> 3969 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 3970 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 3971 Sched<[WriteF]> { 3972 bits<5> Rd; 3973 bits<5> Rn; 3974 let Inst{31-24} = 0b00011110; 3975 let Inst{21-19} = 0b100; 3976 let Inst{18-15} = opcode; 3977 let Inst{14-10} = 0b10000; 3978 let Inst{9-5} = Rn; 3979 let Inst{4-0} = Rd; 3980} 3981 3982multiclass SingleOperandFPData<bits<4> opcode, string asm, 3983 SDPatternOperator node = null_frag> { 3984 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> { 3985 let Inst{23-22} = 0b11; // 16-bit size flag 3986 let Predicates = [HasFullFP16]; 3987 } 3988 3989 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 3990 let Inst{23-22} = 0b00; // 32-bit size flag 3991 } 3992 3993 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 3994 let Inst{23-22} = 0b01; // 64-bit size flag 3995 } 3996} 3997 3998//--- 3999// Two operand floating point data processing 4000//--- 4001 4002let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4003class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4004 string asm, list<dag> pat> 4005 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4006 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4007 Sched<[WriteF]> { 4008 bits<5> Rd; 4009 bits<5> Rn; 4010 bits<5> Rm; 4011 let Inst{31-24} = 0b00011110; 4012 let Inst{21} = 1; 4013 let Inst{20-16} = Rm; 4014 let Inst{15-12} = opcode; 4015 let Inst{11-10} = 0b10; 4016 let Inst{9-5} = Rn; 4017 let Inst{4-0} = Rd; 4018} 4019 4020multiclass TwoOperandFPData<bits<4> opcode, string asm, 4021 SDPatternOperator node = null_frag> { 4022 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4023 [(set (f16 FPR16:$Rd), 4024 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4025 let Inst{23-22} = 0b11; // 16-bit size flag 4026 let Predicates = [HasFullFP16]; 4027 } 4028 4029 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4030 [(set (f32 FPR32:$Rd), 4031 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4032 let Inst{23-22} = 0b00; // 32-bit size flag 4033 } 4034 4035 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4036 [(set (f64 FPR64:$Rd), 4037 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4038 let Inst{23-22} = 0b01; // 64-bit size flag 4039 } 4040} 4041 4042multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4043 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4044 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> { 4045 let Inst{23-22} = 0b11; // 16-bit size flag 4046 let Predicates = [HasFullFP16]; 4047 } 4048 4049 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4050 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4051 let Inst{23-22} = 0b00; // 32-bit size flag 4052 } 4053 4054 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4055 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 4056 let Inst{23-22} = 0b01; // 64-bit size flag 4057 } 4058} 4059 4060 4061//--- 4062// Three operand floating point data processing 4063//--- 4064 4065class BaseThreeOperandFPData<bit isNegated, bit isSub, 4066 RegisterClass regtype, string asm, list<dag> pat> 4067 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 4068 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 4069 Sched<[WriteFMul]> { 4070 bits<5> Rd; 4071 bits<5> Rn; 4072 bits<5> Rm; 4073 bits<5> Ra; 4074 let Inst{31-24} = 0b00011111; 4075 let Inst{21} = isNegated; 4076 let Inst{20-16} = Rm; 4077 let Inst{15} = isSub; 4078 let Inst{14-10} = Ra; 4079 let Inst{9-5} = Rn; 4080 let Inst{4-0} = Rd; 4081} 4082 4083multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 4084 SDPatternOperator node> { 4085 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 4086 [(set FPR16:$Rd, 4087 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 4088 let Inst{23-22} = 0b11; // 16-bit size flag 4089 let Predicates = [HasFullFP16]; 4090 } 4091 4092 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 4093 [(set FPR32:$Rd, 4094 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 4095 let Inst{23-22} = 0b00; // 32-bit size flag 4096 } 4097 4098 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 4099 [(set FPR64:$Rd, 4100 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 4101 let Inst{23-22} = 0b01; // 64-bit size flag 4102 } 4103} 4104 4105//--- 4106// Floating point data comparisons 4107//--- 4108 4109let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4110class BaseOneOperandFPComparison<bit signalAllNans, 4111 RegisterClass regtype, string asm, 4112 list<dag> pat> 4113 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 4114 Sched<[WriteFCmp]> { 4115 bits<5> Rn; 4116 let Inst{31-24} = 0b00011110; 4117 let Inst{21} = 1; 4118 4119 let Inst{15-10} = 0b001000; 4120 let Inst{9-5} = Rn; 4121 let Inst{4} = signalAllNans; 4122 let Inst{3-0} = 0b1000; 4123 4124 // Rm should be 0b00000 canonically, but we need to accept any value. 4125 let PostEncoderMethod = "fixOneOperandFPComparison"; 4126} 4127 4128let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4129class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 4130 string asm, list<dag> pat> 4131 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 4132 Sched<[WriteFCmp]> { 4133 bits<5> Rm; 4134 bits<5> Rn; 4135 let Inst{31-24} = 0b00011110; 4136 let Inst{21} = 1; 4137 let Inst{20-16} = Rm; 4138 let Inst{15-10} = 0b001000; 4139 let Inst{9-5} = Rn; 4140 let Inst{4} = signalAllNans; 4141 let Inst{3-0} = 0b0000; 4142} 4143 4144multiclass FPComparison<bit signalAllNans, string asm, 4145 SDPatternOperator OpNode = null_frag> { 4146 let Defs = [NZCV] in { 4147 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 4148 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> { 4149 let Inst{23-22} = 0b11; 4150 let Predicates = [HasFullFP16]; 4151 } 4152 4153 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 4154 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 4155 let Inst{23-22} = 0b11; 4156 let Predicates = [HasFullFP16]; 4157 } 4158 4159 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 4160 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 4161 let Inst{23-22} = 0b00; 4162 } 4163 4164 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 4165 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 4166 let Inst{23-22} = 0b00; 4167 } 4168 4169 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 4170 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 4171 let Inst{23-22} = 0b01; 4172 } 4173 4174 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 4175 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 4176 let Inst{23-22} = 0b01; 4177 } 4178 } // Defs = [NZCV] 4179} 4180 4181//--- 4182// Floating point conditional comparisons 4183//--- 4184 4185let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4186class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 4187 string mnemonic, list<dag> pat> 4188 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 4189 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 4190 Sched<[WriteFCmp]> { 4191 let Uses = [NZCV]; 4192 let Defs = [NZCV]; 4193 4194 bits<5> Rn; 4195 bits<5> Rm; 4196 bits<4> nzcv; 4197 bits<4> cond; 4198 4199 let Inst{31-24} = 0b00011110; 4200 let Inst{21} = 1; 4201 let Inst{20-16} = Rm; 4202 let Inst{15-12} = cond; 4203 let Inst{11-10} = 0b01; 4204 let Inst{9-5} = Rn; 4205 let Inst{4} = signalAllNans; 4206 let Inst{3-0} = nzcv; 4207} 4208 4209multiclass FPCondComparison<bit signalAllNans, string mnemonic, 4210 SDPatternOperator OpNode = null_frag> { 4211 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> { 4212 let Inst{23-22} = 0b11; 4213 let Predicates = [HasFullFP16]; 4214 } 4215 4216 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 4217 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 4218 (i32 imm:$cond), NZCV))]> { 4219 let Inst{23-22} = 0b00; 4220 } 4221 4222 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 4223 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 4224 (i32 imm:$cond), NZCV))]> { 4225 let Inst{23-22} = 0b01; 4226 } 4227} 4228 4229//--- 4230// Floating point conditional select 4231//--- 4232 4233class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 4234 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 4235 asm, "\t$Rd, $Rn, $Rm, $cond", "", 4236 [(set regtype:$Rd, 4237 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 4238 (i32 imm:$cond), NZCV))]>, 4239 Sched<[WriteF]> { 4240 bits<5> Rd; 4241 bits<5> Rn; 4242 bits<5> Rm; 4243 bits<4> cond; 4244 4245 let Inst{31-24} = 0b00011110; 4246 let Inst{21} = 1; 4247 let Inst{20-16} = Rm; 4248 let Inst{15-12} = cond; 4249 let Inst{11-10} = 0b11; 4250 let Inst{9-5} = Rn; 4251 let Inst{4-0} = Rd; 4252} 4253 4254multiclass FPCondSelect<string asm> { 4255 let Uses = [NZCV] in { 4256 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 4257 let Inst{23-22} = 0b11; 4258 let Predicates = [HasFullFP16]; 4259 } 4260 4261 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 4262 let Inst{23-22} = 0b00; 4263 } 4264 4265 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 4266 let Inst{23-22} = 0b01; 4267 } 4268 } // Uses = [NZCV] 4269} 4270 4271//--- 4272// Floating move immediate 4273//--- 4274 4275class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 4276 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 4277 [(set regtype:$Rd, fpimmtype:$imm)]>, 4278 Sched<[WriteFImm]> { 4279 bits<5> Rd; 4280 bits<8> imm; 4281 let Inst{31-24} = 0b00011110; 4282 let Inst{21} = 1; 4283 let Inst{20-13} = imm; 4284 let Inst{12-5} = 0b10000000; 4285 let Inst{4-0} = Rd; 4286} 4287 4288multiclass FPMoveImmediate<string asm> { 4289 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 4290 let Inst{23-22} = 0b11; 4291 let Predicates = [HasFullFP16]; 4292 } 4293 4294 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 4295 let Inst{23-22} = 0b00; 4296 } 4297 4298 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 4299 let Inst{23-22} = 0b01; 4300 } 4301} 4302} // end of 'let Predicates = [HasFPARMv8]' 4303 4304//---------------------------------------------------------------------------- 4305// AdvSIMD 4306//---------------------------------------------------------------------------- 4307 4308let Predicates = [HasNEON] in { 4309 4310//---------------------------------------------------------------------------- 4311// AdvSIMD three register vector instructions 4312//---------------------------------------------------------------------------- 4313 4314let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4315class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 4316 RegisterOperand regtype, string asm, string kind, 4317 list<dag> pattern> 4318 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 4319 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 4320 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 4321 Sched<[WriteV]> { 4322 bits<5> Rd; 4323 bits<5> Rn; 4324 bits<5> Rm; 4325 let Inst{31} = 0; 4326 let Inst{30} = Q; 4327 let Inst{29} = U; 4328 let Inst{28-24} = 0b01110; 4329 let Inst{23-21} = size; 4330 let Inst{20-16} = Rm; 4331 let Inst{15-11} = opcode; 4332 let Inst{10} = 1; 4333 let Inst{9-5} = Rn; 4334 let Inst{4-0} = Rd; 4335} 4336 4337let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4338class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 4339 RegisterOperand regtype, string asm, string kind, 4340 list<dag> pattern> 4341 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 4342 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 4343 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 4344 Sched<[WriteV]> { 4345 bits<5> Rd; 4346 bits<5> Rn; 4347 bits<5> Rm; 4348 let Inst{31} = 0; 4349 let Inst{30} = Q; 4350 let Inst{29} = U; 4351 let Inst{28-24} = 0b01110; 4352 let Inst{23-21} = size; 4353 let Inst{20-16} = Rm; 4354 let Inst{15-11} = opcode; 4355 let Inst{10} = 1; 4356 let Inst{9-5} = Rn; 4357 let Inst{4-0} = Rd; 4358} 4359 4360// All operand sizes distinguished in the encoding. 4361multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 4362 SDPatternOperator OpNode> { 4363 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 4364 asm, ".8b", 4365 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4366 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 4367 asm, ".16b", 4368 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4369 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 4370 asm, ".4h", 4371 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4372 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 4373 asm, ".8h", 4374 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4375 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 4376 asm, ".2s", 4377 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4378 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 4379 asm, ".4s", 4380 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4381 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 4382 asm, ".2d", 4383 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 4384} 4385 4386// As above, but D sized elements unsupported. 4387multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 4388 SDPatternOperator OpNode> { 4389 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 4390 asm, ".8b", 4391 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 4392 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 4393 asm, ".16b", 4394 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 4395 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 4396 asm, ".4h", 4397 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 4398 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 4399 asm, ".8h", 4400 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 4401 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 4402 asm, ".2s", 4403 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 4404 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 4405 asm, ".4s", 4406 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 4407} 4408 4409multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 4410 SDPatternOperator OpNode> { 4411 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 4412 asm, ".8b", 4413 [(set (v8i8 V64:$dst), 4414 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4415 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 4416 asm, ".16b", 4417 [(set (v16i8 V128:$dst), 4418 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4419 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 4420 asm, ".4h", 4421 [(set (v4i16 V64:$dst), 4422 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4423 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 4424 asm, ".8h", 4425 [(set (v8i16 V128:$dst), 4426 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4427 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 4428 asm, ".2s", 4429 [(set (v2i32 V64:$dst), 4430 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4431 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 4432 asm, ".4s", 4433 [(set (v4i32 V128:$dst), 4434 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4435} 4436 4437// As above, but only B sized elements supported. 4438multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 4439 SDPatternOperator OpNode> { 4440 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 4441 asm, ".8b", 4442 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4443 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 4444 asm, ".16b", 4445 [(set (v16i8 V128:$Rd), 4446 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4447} 4448 4449// As above, but only floating point elements supported. 4450multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 4451 string asm, SDPatternOperator OpNode> { 4452 let Predicates = [HasNEON, HasFullFP16] in { 4453 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 4454 asm, ".4h", 4455 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 4456 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 4457 asm, ".8h", 4458 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 4459 } // Predicates = [HasNEON, HasFullFP16] 4460 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 4461 asm, ".2s", 4462 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4463 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 4464 asm, ".4s", 4465 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4466 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 4467 asm, ".2d", 4468 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4469} 4470 4471multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 4472 string asm, 4473 SDPatternOperator OpNode> { 4474 let Predicates = [HasNEON, HasFullFP16] in { 4475 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 4476 asm, ".4h", 4477 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 4478 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 4479 asm, ".8h", 4480 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 4481 } // Predicates = [HasNEON, HasFullFP16] 4482 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 4483 asm, ".2s", 4484 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4485 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 4486 asm, ".4s", 4487 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4488 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 4489 asm, ".2d", 4490 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4491} 4492 4493multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 4494 string asm, SDPatternOperator OpNode> { 4495 let Predicates = [HasNEON, HasFullFP16] in { 4496 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 4497 asm, ".4h", 4498 [(set (v4f16 V64:$dst), 4499 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 4500 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 4501 asm, ".8h", 4502 [(set (v8f16 V128:$dst), 4503 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 4504 } // Predicates = [HasNEON, HasFullFP16] 4505 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 4506 asm, ".2s", 4507 [(set (v2f32 V64:$dst), 4508 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4509 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 4510 asm, ".4s", 4511 [(set (v4f32 V128:$dst), 4512 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4513 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 4514 asm, ".2d", 4515 [(set (v2f64 V128:$dst), 4516 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4517} 4518 4519// As above, but D and B sized elements unsupported. 4520multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 4521 SDPatternOperator OpNode> { 4522 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 4523 asm, ".4h", 4524 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4525 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 4526 asm, ".8h", 4527 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4528 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 4529 asm, ".2s", 4530 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4531 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 4532 asm, ".4s", 4533 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4534} 4535 4536// Logical three vector ops share opcode bits, and only use B sized elements. 4537multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 4538 SDPatternOperator OpNode = null_frag> { 4539 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 4540 asm, ".8b", 4541 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 4542 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 4543 asm, ".16b", 4544 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 4545 4546 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 4547 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4548 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 4549 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4550 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 4551 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4552 4553 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 4554 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4555 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 4556 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4557 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 4558 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4559} 4560 4561multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 4562 string asm, SDPatternOperator OpNode> { 4563 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 4564 asm, ".8b", 4565 [(set (v8i8 V64:$dst), 4566 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4567 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 4568 asm, ".16b", 4569 [(set (v16i8 V128:$dst), 4570 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 4571 (v16i8 V128:$Rm)))]>; 4572 4573 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 4574 (v4i16 V64:$RHS))), 4575 (!cast<Instruction>(NAME#"v8i8") 4576 V64:$LHS, V64:$MHS, V64:$RHS)>; 4577 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 4578 (v2i32 V64:$RHS))), 4579 (!cast<Instruction>(NAME#"v8i8") 4580 V64:$LHS, V64:$MHS, V64:$RHS)>; 4581 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 4582 (v1i64 V64:$RHS))), 4583 (!cast<Instruction>(NAME#"v8i8") 4584 V64:$LHS, V64:$MHS, V64:$RHS)>; 4585 4586 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 4587 (v8i16 V128:$RHS))), 4588 (!cast<Instruction>(NAME#"v16i8") 4589 V128:$LHS, V128:$MHS, V128:$RHS)>; 4590 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 4591 (v4i32 V128:$RHS))), 4592 (!cast<Instruction>(NAME#"v16i8") 4593 V128:$LHS, V128:$MHS, V128:$RHS)>; 4594 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 4595 (v2i64 V128:$RHS))), 4596 (!cast<Instruction>(NAME#"v16i8") 4597 V128:$LHS, V128:$MHS, V128:$RHS)>; 4598} 4599 4600 4601//---------------------------------------------------------------------------- 4602// AdvSIMD two register vector instructions. 4603//---------------------------------------------------------------------------- 4604 4605let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4606class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4607 bits<2> size2, RegisterOperand regtype, string asm, 4608 string dstkind, string srckind, list<dag> pattern> 4609 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 4610 "{\t$Rd" # dstkind # ", $Rn" # srckind # 4611 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 4612 Sched<[WriteV]> { 4613 bits<5> Rd; 4614 bits<5> Rn; 4615 let Inst{31} = 0; 4616 let Inst{30} = Q; 4617 let Inst{29} = U; 4618 let Inst{28-24} = 0b01110; 4619 let Inst{23-22} = size; 4620 let Inst{21} = 0b1; 4621 let Inst{20-19} = size2; 4622 let Inst{18-17} = 0b00; 4623 let Inst{16-12} = opcode; 4624 let Inst{11-10} = 0b10; 4625 let Inst{9-5} = Rn; 4626 let Inst{4-0} = Rd; 4627} 4628 4629let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4630class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4631 bits<2> size2, RegisterOperand regtype, 4632 string asm, string dstkind, string srckind, 4633 list<dag> pattern> 4634 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 4635 "{\t$Rd" # dstkind # ", $Rn" # srckind # 4636 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 4637 Sched<[WriteV]> { 4638 bits<5> Rd; 4639 bits<5> Rn; 4640 let Inst{31} = 0; 4641 let Inst{30} = Q; 4642 let Inst{29} = U; 4643 let Inst{28-24} = 0b01110; 4644 let Inst{23-22} = size; 4645 let Inst{21} = 0b1; 4646 let Inst{20-19} = size2; 4647 let Inst{18-17} = 0b00; 4648 let Inst{16-12} = opcode; 4649 let Inst{11-10} = 0b10; 4650 let Inst{9-5} = Rn; 4651 let Inst{4-0} = Rd; 4652} 4653 4654// Supports B, H, and S element sizes. 4655multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 4656 SDPatternOperator OpNode> { 4657 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4658 asm, ".8b", ".8b", 4659 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4660 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4661 asm, ".16b", ".16b", 4662 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4663 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4664 asm, ".4h", ".4h", 4665 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4666 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4667 asm, ".8h", ".8h", 4668 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4669 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 4670 asm, ".2s", ".2s", 4671 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4672 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 4673 asm, ".4s", ".4s", 4674 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4675} 4676 4677class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 4678 RegisterOperand regtype, string asm, string dstkind, 4679 string srckind, string amount> 4680 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 4681 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 4682 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 4683 Sched<[WriteV]> { 4684 bits<5> Rd; 4685 bits<5> Rn; 4686 let Inst{31} = 0; 4687 let Inst{30} = Q; 4688 let Inst{29-24} = 0b101110; 4689 let Inst{23-22} = size; 4690 let Inst{21-10} = 0b100001001110; 4691 let Inst{9-5} = Rn; 4692 let Inst{4-0} = Rd; 4693} 4694 4695multiclass SIMDVectorLShiftLongBySizeBHS { 4696 let hasSideEffects = 0 in { 4697 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 4698 "shll", ".8h", ".8b", "8">; 4699 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 4700 "shll2", ".8h", ".16b", "8">; 4701 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 4702 "shll", ".4s", ".4h", "16">; 4703 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 4704 "shll2", ".4s", ".8h", "16">; 4705 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 4706 "shll", ".2d", ".2s", "32">; 4707 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 4708 "shll2", ".2d", ".4s", "32">; 4709 } 4710} 4711 4712// Supports all element sizes. 4713multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 4714 SDPatternOperator OpNode> { 4715 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4716 asm, ".4h", ".8b", 4717 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4718 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4719 asm, ".8h", ".16b", 4720 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4721 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4722 asm, ".2s", ".4h", 4723 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4724 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4725 asm, ".4s", ".8h", 4726 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4727 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 4728 asm, ".1d", ".2s", 4729 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4730 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 4731 asm, ".2d", ".4s", 4732 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4733} 4734 4735multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 4736 SDPatternOperator OpNode> { 4737 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 4738 asm, ".4h", ".8b", 4739 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 4740 (v8i8 V64:$Rn)))]>; 4741 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 4742 asm, ".8h", ".16b", 4743 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 4744 (v16i8 V128:$Rn)))]>; 4745 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 4746 asm, ".2s", ".4h", 4747 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 4748 (v4i16 V64:$Rn)))]>; 4749 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 4750 asm, ".4s", ".8h", 4751 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 4752 (v8i16 V128:$Rn)))]>; 4753 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 4754 asm, ".1d", ".2s", 4755 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 4756 (v2i32 V64:$Rn)))]>; 4757 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 4758 asm, ".2d", ".4s", 4759 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 4760 (v4i32 V128:$Rn)))]>; 4761} 4762 4763// Supports all element sizes, except 1xD. 4764multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 4765 SDPatternOperator OpNode> { 4766 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 4767 asm, ".8b", ".8b", 4768 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 4769 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 4770 asm, ".16b", ".16b", 4771 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 4772 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 4773 asm, ".4h", ".4h", 4774 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 4775 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 4776 asm, ".8h", ".8h", 4777 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 4778 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 4779 asm, ".2s", ".2s", 4780 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 4781 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 4782 asm, ".4s", ".4s", 4783 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 4784 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 4785 asm, ".2d", ".2d", 4786 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 4787} 4788 4789multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 4790 SDPatternOperator OpNode = null_frag> { 4791 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4792 asm, ".8b", ".8b", 4793 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4794 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4795 asm, ".16b", ".16b", 4796 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4797 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4798 asm, ".4h", ".4h", 4799 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4800 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4801 asm, ".8h", ".8h", 4802 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4803 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 4804 asm, ".2s", ".2s", 4805 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4806 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 4807 asm, ".4s", ".4s", 4808 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4809 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 4810 asm, ".2d", ".2d", 4811 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4812} 4813 4814 4815// Supports only B element sizes. 4816multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 4817 SDPatternOperator OpNode> { 4818 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 4819 asm, ".8b", ".8b", 4820 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4821 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 4822 asm, ".16b", ".16b", 4823 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4824 4825} 4826 4827// Supports only B and H element sizes. 4828multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 4829 SDPatternOperator OpNode> { 4830 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4831 asm, ".8b", ".8b", 4832 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 4833 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4834 asm, ".16b", ".16b", 4835 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 4836 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4837 asm, ".4h", ".4h", 4838 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 4839 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4840 asm, ".8h", ".8h", 4841 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 4842} 4843 4844// Supports only S and D element sizes, uses high bit of the size field 4845// as an extra opcode bit. 4846multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 4847 SDPatternOperator OpNode> { 4848 let Predicates = [HasNEON, HasFullFP16] in { 4849 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 4850 asm, ".4h", ".4h", 4851 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 4852 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 4853 asm, ".8h", ".8h", 4854 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 4855 } // Predicates = [HasNEON, HasFullFP16] 4856 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4857 asm, ".2s", ".2s", 4858 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 4859 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4860 asm, ".4s", ".4s", 4861 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 4862 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 4863 asm, ".2d", ".2d", 4864 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4865} 4866 4867// Supports only S element size. 4868multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 4869 SDPatternOperator OpNode> { 4870 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4871 asm, ".2s", ".2s", 4872 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4873 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4874 asm, ".4s", ".4s", 4875 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4876} 4877 4878 4879multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 4880 SDPatternOperator OpNode> { 4881 let Predicates = [HasNEON, HasFullFP16] in { 4882 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 4883 asm, ".4h", ".4h", 4884 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 4885 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 4886 asm, ".8h", ".8h", 4887 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 4888 } // Predicates = [HasNEON, HasFullFP16] 4889 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4890 asm, ".2s", ".2s", 4891 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 4892 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4893 asm, ".4s", ".4s", 4894 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 4895 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 4896 asm, ".2d", ".2d", 4897 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4898} 4899 4900multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 4901 SDPatternOperator OpNode> { 4902 let Predicates = [HasNEON, HasFullFP16] in { 4903 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 4904 asm, ".4h", ".4h", 4905 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4906 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 4907 asm, ".8h", ".8h", 4908 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4909 } // Predicates = [HasNEON, HasFullFP16] 4910 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4911 asm, ".2s", ".2s", 4912 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4913 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4914 asm, ".4s", ".4s", 4915 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4916 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 4917 asm, ".2d", ".2d", 4918 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4919} 4920 4921 4922class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4923 RegisterOperand inreg, RegisterOperand outreg, 4924 string asm, string outkind, string inkind, 4925 list<dag> pattern> 4926 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 4927 "{\t$Rd" # outkind # ", $Rn" # inkind # 4928 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 4929 Sched<[WriteV]> { 4930 bits<5> Rd; 4931 bits<5> Rn; 4932 let Inst{31} = 0; 4933 let Inst{30} = Q; 4934 let Inst{29} = U; 4935 let Inst{28-24} = 0b01110; 4936 let Inst{23-22} = size; 4937 let Inst{21-17} = 0b10000; 4938 let Inst{16-12} = opcode; 4939 let Inst{11-10} = 0b10; 4940 let Inst{9-5} = Rn; 4941 let Inst{4-0} = Rd; 4942} 4943 4944class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4945 RegisterOperand inreg, RegisterOperand outreg, 4946 string asm, string outkind, string inkind, 4947 list<dag> pattern> 4948 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 4949 "{\t$Rd" # outkind # ", $Rn" # inkind # 4950 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 4951 Sched<[WriteV]> { 4952 bits<5> Rd; 4953 bits<5> Rn; 4954 let Inst{31} = 0; 4955 let Inst{30} = Q; 4956 let Inst{29} = U; 4957 let Inst{28-24} = 0b01110; 4958 let Inst{23-22} = size; 4959 let Inst{21-17} = 0b10000; 4960 let Inst{16-12} = opcode; 4961 let Inst{11-10} = 0b10; 4962 let Inst{9-5} = Rn; 4963 let Inst{4-0} = Rd; 4964} 4965 4966multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 4967 SDPatternOperator OpNode> { 4968 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 4969 asm, ".8b", ".8h", 4970 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4971 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 4972 asm#"2", ".16b", ".8h", []>; 4973 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 4974 asm, ".4h", ".4s", 4975 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4976 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 4977 asm#"2", ".8h", ".4s", []>; 4978 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 4979 asm, ".2s", ".2d", 4980 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4981 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 4982 asm#"2", ".4s", ".2d", []>; 4983 4984 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 4985 (!cast<Instruction>(NAME # "v16i8") 4986 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4987 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 4988 (!cast<Instruction>(NAME # "v8i16") 4989 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4990 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 4991 (!cast<Instruction>(NAME # "v4i32") 4992 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4993} 4994 4995class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 4996 bits<5> opcode, RegisterOperand regtype, string asm, 4997 string kind, string zero, ValueType dty, 4998 ValueType sty, SDNode OpNode> 4999 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5000 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 5001 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 5002 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 5003 Sched<[WriteV]> { 5004 bits<5> Rd; 5005 bits<5> Rn; 5006 let Inst{31} = 0; 5007 let Inst{30} = Q; 5008 let Inst{29} = U; 5009 let Inst{28-24} = 0b01110; 5010 let Inst{23-22} = size; 5011 let Inst{21} = 0b1; 5012 let Inst{20-19} = size2; 5013 let Inst{18-17} = 0b00; 5014 let Inst{16-12} = opcode; 5015 let Inst{11-10} = 0b10; 5016 let Inst{9-5} = Rn; 5017 let Inst{4-0} = Rd; 5018} 5019 5020// Comparisons support all element sizes, except 1xD. 5021multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 5022 SDNode OpNode> { 5023 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 5024 asm, ".8b", "0", 5025 v8i8, v8i8, OpNode>; 5026 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 5027 asm, ".16b", "0", 5028 v16i8, v16i8, OpNode>; 5029 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 5030 asm, ".4h", "0", 5031 v4i16, v4i16, OpNode>; 5032 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 5033 asm, ".8h", "0", 5034 v8i16, v8i16, OpNode>; 5035 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 5036 asm, ".2s", "0", 5037 v2i32, v2i32, OpNode>; 5038 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 5039 asm, ".4s", "0", 5040 v4i32, v4i32, OpNode>; 5041 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 5042 asm, ".2d", "0", 5043 v2i64, v2i64, OpNode>; 5044} 5045 5046// FP Comparisons support only S and D element sizes (and H for v8.2a). 5047multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 5048 string asm, SDNode OpNode> { 5049 5050 let Predicates = [HasNEON, HasFullFP16] in { 5051 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 5052 asm, ".4h", "0.0", 5053 v4i16, v4f16, OpNode>; 5054 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 5055 asm, ".8h", "0.0", 5056 v8i16, v8f16, OpNode>; 5057 } // Predicates = [HasNEON, HasFullFP16] 5058 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 5059 asm, ".2s", "0.0", 5060 v2i32, v2f32, OpNode>; 5061 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 5062 asm, ".4s", "0.0", 5063 v4i32, v4f32, OpNode>; 5064 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 5065 asm, ".2d", "0.0", 5066 v2i64, v2f64, OpNode>; 5067 5068 let Predicates = [HasNEON, HasFullFP16] in { 5069 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 5070 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5071 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 5072 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5073 } 5074 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 5075 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5076 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 5077 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5078 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 5079 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5080 let Predicates = [HasNEON, HasFullFP16] in { 5081 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 5082 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5083 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 5084 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5085 } 5086 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 5087 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5088 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 5089 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5090 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 5091 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5092} 5093 5094let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5095class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5096 RegisterOperand outtype, RegisterOperand intype, 5097 string asm, string VdTy, string VnTy, 5098 list<dag> pattern> 5099 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 5100 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 5101 Sched<[WriteV]> { 5102 bits<5> Rd; 5103 bits<5> Rn; 5104 let Inst{31} = 0; 5105 let Inst{30} = Q; 5106 let Inst{29} = U; 5107 let Inst{28-24} = 0b01110; 5108 let Inst{23-22} = size; 5109 let Inst{21-17} = 0b10000; 5110 let Inst{16-12} = opcode; 5111 let Inst{11-10} = 0b10; 5112 let Inst{9-5} = Rn; 5113 let Inst{4-0} = Rd; 5114} 5115 5116class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5117 RegisterOperand outtype, RegisterOperand intype, 5118 string asm, string VdTy, string VnTy, 5119 list<dag> pattern> 5120 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 5121 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 5122 Sched<[WriteV]> { 5123 bits<5> Rd; 5124 bits<5> Rn; 5125 let Inst{31} = 0; 5126 let Inst{30} = Q; 5127 let Inst{29} = U; 5128 let Inst{28-24} = 0b01110; 5129 let Inst{23-22} = size; 5130 let Inst{21-17} = 0b10000; 5131 let Inst{16-12} = opcode; 5132 let Inst{11-10} = 0b10; 5133 let Inst{9-5} = Rn; 5134 let Inst{4-0} = Rd; 5135} 5136 5137multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 5138 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 5139 asm, ".4s", ".4h", []>; 5140 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 5141 asm#"2", ".4s", ".8h", []>; 5142 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 5143 asm, ".2d", ".2s", []>; 5144 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 5145 asm#"2", ".2d", ".4s", []>; 5146} 5147 5148multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 5149 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 5150 asm, ".4h", ".4s", []>; 5151 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 5152 asm#"2", ".8h", ".4s", []>; 5153 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 5154 asm, ".2s", ".2d", []>; 5155 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 5156 asm#"2", ".4s", ".2d", []>; 5157} 5158 5159multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 5160 Intrinsic OpNode> { 5161 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 5162 asm, ".2s", ".2d", 5163 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5164 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 5165 asm#"2", ".4s", ".2d", []>; 5166 5167 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 5168 (!cast<Instruction>(NAME # "v4f32") 5169 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5170} 5171 5172//---------------------------------------------------------------------------- 5173// AdvSIMD three register different-size vector instructions. 5174//---------------------------------------------------------------------------- 5175 5176let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5177class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 5178 RegisterOperand outtype, RegisterOperand intype1, 5179 RegisterOperand intype2, string asm, 5180 string outkind, string inkind1, string inkind2, 5181 list<dag> pattern> 5182 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 5183 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 5184 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 5185 Sched<[WriteV]> { 5186 bits<5> Rd; 5187 bits<5> Rn; 5188 bits<5> Rm; 5189 let Inst{31} = 0; 5190 let Inst{30} = size{0}; 5191 let Inst{29} = U; 5192 let Inst{28-24} = 0b01110; 5193 let Inst{23-22} = size{2-1}; 5194 let Inst{21} = 1; 5195 let Inst{20-16} = Rm; 5196 let Inst{15-12} = opcode; 5197 let Inst{11-10} = 0b00; 5198 let Inst{9-5} = Rn; 5199 let Inst{4-0} = Rd; 5200} 5201 5202let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5203class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 5204 RegisterOperand outtype, RegisterOperand intype1, 5205 RegisterOperand intype2, string asm, 5206 string outkind, string inkind1, string inkind2, 5207 list<dag> pattern> 5208 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 5209 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 5210 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5211 Sched<[WriteV]> { 5212 bits<5> Rd; 5213 bits<5> Rn; 5214 bits<5> Rm; 5215 let Inst{31} = 0; 5216 let Inst{30} = size{0}; 5217 let Inst{29} = U; 5218 let Inst{28-24} = 0b01110; 5219 let Inst{23-22} = size{2-1}; 5220 let Inst{21} = 1; 5221 let Inst{20-16} = Rm; 5222 let Inst{15-12} = opcode; 5223 let Inst{11-10} = 0b00; 5224 let Inst{9-5} = Rn; 5225 let Inst{4-0} = Rd; 5226} 5227 5228// FIXME: TableGen doesn't know how to deal with expanded types that also 5229// change the element count (in this case, placing the results in 5230// the high elements of the result register rather than the low 5231// elements). Until that's fixed, we can't code-gen those. 5232multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 5233 Intrinsic IntOp> { 5234 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5235 V64, V128, V128, 5236 asm, ".8b", ".8h", ".8h", 5237 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5238 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5239 V128, V128, V128, 5240 asm#"2", ".16b", ".8h", ".8h", 5241 []>; 5242 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5243 V64, V128, V128, 5244 asm, ".4h", ".4s", ".4s", 5245 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5246 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5247 V128, V128, V128, 5248 asm#"2", ".8h", ".4s", ".4s", 5249 []>; 5250 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5251 V64, V128, V128, 5252 asm, ".2s", ".2d", ".2d", 5253 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5254 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5255 V128, V128, V128, 5256 asm#"2", ".4s", ".2d", ".2d", 5257 []>; 5258 5259 5260 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 5261 // a version attached to an instruction. 5262 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 5263 (v8i16 V128:$Rm))), 5264 (!cast<Instruction>(NAME # "v8i16_v16i8") 5265 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 5266 V128:$Rn, V128:$Rm)>; 5267 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 5268 (v4i32 V128:$Rm))), 5269 (!cast<Instruction>(NAME # "v4i32_v8i16") 5270 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 5271 V128:$Rn, V128:$Rm)>; 5272 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 5273 (v2i64 V128:$Rm))), 5274 (!cast<Instruction>(NAME # "v2i64_v4i32") 5275 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 5276 V128:$Rn, V128:$Rm)>; 5277} 5278 5279multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 5280 Intrinsic IntOp> { 5281 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5282 V128, V64, V64, 5283 asm, ".8h", ".8b", ".8b", 5284 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5285 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5286 V128, V128, V128, 5287 asm#"2", ".8h", ".16b", ".16b", []>; 5288 let Predicates = [HasCrypto] in { 5289 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 5290 V128, V64, V64, 5291 asm, ".1q", ".1d", ".1d", []>; 5292 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 5293 V128, V128, V128, 5294 asm#"2", ".1q", ".2d", ".2d", []>; 5295 } 5296 5297 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 5298 (v8i8 (extract_high_v16i8 V128:$Rm)))), 5299 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 5300} 5301 5302multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 5303 SDPatternOperator OpNode> { 5304 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5305 V128, V64, V64, 5306 asm, ".4s", ".4h", ".4h", 5307 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5308 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5309 V128, V128, V128, 5310 asm#"2", ".4s", ".8h", ".8h", 5311 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 5312 (extract_high_v8i16 V128:$Rm)))]>; 5313 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5314 V128, V64, V64, 5315 asm, ".2d", ".2s", ".2s", 5316 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5317 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5318 V128, V128, V128, 5319 asm#"2", ".2d", ".4s", ".4s", 5320 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 5321 (extract_high_v4i32 V128:$Rm)))]>; 5322} 5323 5324multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 5325 SDPatternOperator OpNode = null_frag> { 5326 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5327 V128, V64, V64, 5328 asm, ".8h", ".8b", ".8b", 5329 [(set (v8i16 V128:$Rd), 5330 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 5331 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5332 V128, V128, V128, 5333 asm#"2", ".8h", ".16b", ".16b", 5334 [(set (v8i16 V128:$Rd), 5335 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 5336 (extract_high_v16i8 V128:$Rm)))))]>; 5337 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5338 V128, V64, V64, 5339 asm, ".4s", ".4h", ".4h", 5340 [(set (v4i32 V128:$Rd), 5341 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 5342 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5343 V128, V128, V128, 5344 asm#"2", ".4s", ".8h", ".8h", 5345 [(set (v4i32 V128:$Rd), 5346 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 5347 (extract_high_v8i16 V128:$Rm)))))]>; 5348 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5349 V128, V64, V64, 5350 asm, ".2d", ".2s", ".2s", 5351 [(set (v2i64 V128:$Rd), 5352 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 5353 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5354 V128, V128, V128, 5355 asm#"2", ".2d", ".4s", ".4s", 5356 [(set (v2i64 V128:$Rd), 5357 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 5358 (extract_high_v4i32 V128:$Rm)))))]>; 5359} 5360 5361multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 5362 string asm, 5363 SDPatternOperator OpNode> { 5364 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 5365 V128, V64, V64, 5366 asm, ".8h", ".8b", ".8b", 5367 [(set (v8i16 V128:$dst), 5368 (add (v8i16 V128:$Rd), 5369 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 5370 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5371 V128, V128, V128, 5372 asm#"2", ".8h", ".16b", ".16b", 5373 [(set (v8i16 V128:$dst), 5374 (add (v8i16 V128:$Rd), 5375 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 5376 (extract_high_v16i8 V128:$Rm))))))]>; 5377 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5378 V128, V64, V64, 5379 asm, ".4s", ".4h", ".4h", 5380 [(set (v4i32 V128:$dst), 5381 (add (v4i32 V128:$Rd), 5382 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 5383 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5384 V128, V128, V128, 5385 asm#"2", ".4s", ".8h", ".8h", 5386 [(set (v4i32 V128:$dst), 5387 (add (v4i32 V128:$Rd), 5388 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 5389 (extract_high_v8i16 V128:$Rm))))))]>; 5390 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5391 V128, V64, V64, 5392 asm, ".2d", ".2s", ".2s", 5393 [(set (v2i64 V128:$dst), 5394 (add (v2i64 V128:$Rd), 5395 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 5396 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5397 V128, V128, V128, 5398 asm#"2", ".2d", ".4s", ".4s", 5399 [(set (v2i64 V128:$dst), 5400 (add (v2i64 V128:$Rd), 5401 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 5402 (extract_high_v4i32 V128:$Rm))))))]>; 5403} 5404 5405multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 5406 SDPatternOperator OpNode = null_frag> { 5407 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5408 V128, V64, V64, 5409 asm, ".8h", ".8b", ".8b", 5410 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5411 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5412 V128, V128, V128, 5413 asm#"2", ".8h", ".16b", ".16b", 5414 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 5415 (extract_high_v16i8 V128:$Rm)))]>; 5416 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5417 V128, V64, V64, 5418 asm, ".4s", ".4h", ".4h", 5419 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5420 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5421 V128, V128, V128, 5422 asm#"2", ".4s", ".8h", ".8h", 5423 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 5424 (extract_high_v8i16 V128:$Rm)))]>; 5425 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5426 V128, V64, V64, 5427 asm, ".2d", ".2s", ".2s", 5428 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5429 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5430 V128, V128, V128, 5431 asm#"2", ".2d", ".4s", ".4s", 5432 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 5433 (extract_high_v4i32 V128:$Rm)))]>; 5434} 5435 5436multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 5437 string asm, 5438 SDPatternOperator OpNode> { 5439 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 5440 V128, V64, V64, 5441 asm, ".8h", ".8b", ".8b", 5442 [(set (v8i16 V128:$dst), 5443 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5444 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5445 V128, V128, V128, 5446 asm#"2", ".8h", ".16b", ".16b", 5447 [(set (v8i16 V128:$dst), 5448 (OpNode (v8i16 V128:$Rd), 5449 (extract_high_v16i8 V128:$Rn), 5450 (extract_high_v16i8 V128:$Rm)))]>; 5451 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5452 V128, V64, V64, 5453 asm, ".4s", ".4h", ".4h", 5454 [(set (v4i32 V128:$dst), 5455 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5456 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5457 V128, V128, V128, 5458 asm#"2", ".4s", ".8h", ".8h", 5459 [(set (v4i32 V128:$dst), 5460 (OpNode (v4i32 V128:$Rd), 5461 (extract_high_v8i16 V128:$Rn), 5462 (extract_high_v8i16 V128:$Rm)))]>; 5463 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5464 V128, V64, V64, 5465 asm, ".2d", ".2s", ".2s", 5466 [(set (v2i64 V128:$dst), 5467 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5468 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5469 V128, V128, V128, 5470 asm#"2", ".2d", ".4s", ".4s", 5471 [(set (v2i64 V128:$dst), 5472 (OpNode (v2i64 V128:$Rd), 5473 (extract_high_v4i32 V128:$Rn), 5474 (extract_high_v4i32 V128:$Rm)))]>; 5475} 5476 5477multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 5478 SDPatternOperator Accum> { 5479 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5480 V128, V64, V64, 5481 asm, ".4s", ".4h", ".4h", 5482 [(set (v4i32 V128:$dst), 5483 (Accum (v4i32 V128:$Rd), 5484 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 5485 (v4i16 V64:$Rm)))))]>; 5486 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5487 V128, V128, V128, 5488 asm#"2", ".4s", ".8h", ".8h", 5489 [(set (v4i32 V128:$dst), 5490 (Accum (v4i32 V128:$Rd), 5491 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 5492 (extract_high_v8i16 V128:$Rm)))))]>; 5493 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5494 V128, V64, V64, 5495 asm, ".2d", ".2s", ".2s", 5496 [(set (v2i64 V128:$dst), 5497 (Accum (v2i64 V128:$Rd), 5498 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 5499 (v2i32 V64:$Rm)))))]>; 5500 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5501 V128, V128, V128, 5502 asm#"2", ".2d", ".4s", ".4s", 5503 [(set (v2i64 V128:$dst), 5504 (Accum (v2i64 V128:$Rd), 5505 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 5506 (extract_high_v4i32 V128:$Rm)))))]>; 5507} 5508 5509multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 5510 SDPatternOperator OpNode> { 5511 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5512 V128, V128, V64, 5513 asm, ".8h", ".8h", ".8b", 5514 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 5515 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5516 V128, V128, V128, 5517 asm#"2", ".8h", ".8h", ".16b", 5518 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 5519 (extract_high_v16i8 V128:$Rm)))]>; 5520 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5521 V128, V128, V64, 5522 asm, ".4s", ".4s", ".4h", 5523 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 5524 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5525 V128, V128, V128, 5526 asm#"2", ".4s", ".4s", ".8h", 5527 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 5528 (extract_high_v8i16 V128:$Rm)))]>; 5529 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5530 V128, V128, V64, 5531 asm, ".2d", ".2d", ".2s", 5532 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 5533 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5534 V128, V128, V128, 5535 asm#"2", ".2d", ".2d", ".4s", 5536 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 5537 (extract_high_v4i32 V128:$Rm)))]>; 5538} 5539 5540//---------------------------------------------------------------------------- 5541// AdvSIMD bitwise extract from vector 5542//---------------------------------------------------------------------------- 5543 5544class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 5545 string asm, string kind> 5546 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 5547 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 5548 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 5549 [(set (vty regtype:$Rd), 5550 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 5551 Sched<[WriteV]> { 5552 bits<5> Rd; 5553 bits<5> Rn; 5554 bits<5> Rm; 5555 bits<4> imm; 5556 let Inst{31} = 0; 5557 let Inst{30} = size; 5558 let Inst{29-21} = 0b101110000; 5559 let Inst{20-16} = Rm; 5560 let Inst{15} = 0; 5561 let Inst{14-11} = imm; 5562 let Inst{10} = 0; 5563 let Inst{9-5} = Rn; 5564 let Inst{4-0} = Rd; 5565} 5566 5567 5568multiclass SIMDBitwiseExtract<string asm> { 5569 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 5570 let imm{3} = 0; 5571 } 5572 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 5573} 5574 5575//---------------------------------------------------------------------------- 5576// AdvSIMD zip vector 5577//---------------------------------------------------------------------------- 5578 5579class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 5580 string asm, string kind, SDNode OpNode, ValueType valty> 5581 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5582 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5583 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 5584 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 5585 Sched<[WriteV]> { 5586 bits<5> Rd; 5587 bits<5> Rn; 5588 bits<5> Rm; 5589 let Inst{31} = 0; 5590 let Inst{30} = size{0}; 5591 let Inst{29-24} = 0b001110; 5592 let Inst{23-22} = size{2-1}; 5593 let Inst{21} = 0; 5594 let Inst{20-16} = Rm; 5595 let Inst{15} = 0; 5596 let Inst{14-12} = opc; 5597 let Inst{11-10} = 0b10; 5598 let Inst{9-5} = Rn; 5599 let Inst{4-0} = Rd; 5600} 5601 5602multiclass SIMDZipVector<bits<3>opc, string asm, 5603 SDNode OpNode> { 5604 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 5605 asm, ".8b", OpNode, v8i8>; 5606 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 5607 asm, ".16b", OpNode, v16i8>; 5608 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 5609 asm, ".4h", OpNode, v4i16>; 5610 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 5611 asm, ".8h", OpNode, v8i16>; 5612 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 5613 asm, ".2s", OpNode, v2i32>; 5614 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 5615 asm, ".4s", OpNode, v4i32>; 5616 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 5617 asm, ".2d", OpNode, v2i64>; 5618 5619 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 5620 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 5621 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 5622 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 5623 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 5624 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 5625 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 5626 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 5627 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 5628 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 5629} 5630 5631//---------------------------------------------------------------------------- 5632// AdvSIMD three register scalar instructions 5633//---------------------------------------------------------------------------- 5634 5635let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5636class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 5637 RegisterClass regtype, string asm, 5638 list<dag> pattern> 5639 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5640 "\t$Rd, $Rn, $Rm", "", pattern>, 5641 Sched<[WriteV]> { 5642 bits<5> Rd; 5643 bits<5> Rn; 5644 bits<5> Rm; 5645 let Inst{31-30} = 0b01; 5646 let Inst{29} = U; 5647 let Inst{28-24} = 0b11110; 5648 let Inst{23-21} = size; 5649 let Inst{20-16} = Rm; 5650 let Inst{15-11} = opcode; 5651 let Inst{10} = 1; 5652 let Inst{9-5} = Rn; 5653 let Inst{4-0} = Rd; 5654} 5655 5656let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5657class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 5658 dag oops, dag iops, string asm, 5659 list<dag> pattern> 5660 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 5661 Sched<[WriteV]> { 5662 bits<5> Rd; 5663 bits<5> Rn; 5664 bits<5> Rm; 5665 let Inst{31-30} = 0b01; 5666 let Inst{29} = U; 5667 let Inst{28-24} = 0b11110; 5668 let Inst{23-22} = size; 5669 let Inst{21} = R; 5670 let Inst{20-16} = Rm; 5671 let Inst{15-11} = opcode; 5672 let Inst{10} = 1; 5673 let Inst{9-5} = Rn; 5674 let Inst{4-0} = Rd; 5675} 5676 5677multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 5678 SDPatternOperator OpNode> { 5679 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 5680 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 5681} 5682 5683multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 5684 SDPatternOperator OpNode> { 5685 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 5686 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 5687 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 5688 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 5689 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 5690 5691 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 5692 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 5693 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 5694 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 5695} 5696 5697multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 5698 SDPatternOperator OpNode> { 5699 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 5700 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 5701 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 5702} 5703 5704multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 5705 SDPatternOperator OpNode = null_frag> { 5706 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 5707 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 5708 asm, []>; 5709 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 5710 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 5711 asm, []>; 5712} 5713 5714multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 5715 SDPatternOperator OpNode = null_frag> { 5716 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5717 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 5718 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 5719 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 5720 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 5721 let Predicates = [HasNEON, HasFullFP16] in { 5722 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 5723 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>; 5724 } // Predicates = [HasNEON, HasFullFP16] 5725 } 5726 5727 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5728 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 5729} 5730 5731multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 5732 SDPatternOperator OpNode = null_frag> { 5733 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5734 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 5735 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 5736 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 5737 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 5738 let Predicates = [HasNEON, HasFullFP16] in { 5739 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 5740 []>; 5741 } // Predicates = [HasNEON, HasFullFP16] 5742 } 5743 5744 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5745 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 5746} 5747 5748class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 5749 dag oops, dag iops, string asm, string cstr, list<dag> pat> 5750 : I<oops, iops, asm, 5751 "\t$Rd, $Rn, $Rm", cstr, pat>, 5752 Sched<[WriteV]> { 5753 bits<5> Rd; 5754 bits<5> Rn; 5755 bits<5> Rm; 5756 let Inst{31-30} = 0b01; 5757 let Inst{29} = U; 5758 let Inst{28-24} = 0b11110; 5759 let Inst{23-22} = size; 5760 let Inst{21} = 1; 5761 let Inst{20-16} = Rm; 5762 let Inst{15-11} = opcode; 5763 let Inst{10} = 0; 5764 let Inst{9-5} = Rn; 5765 let Inst{4-0} = Rd; 5766} 5767 5768let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5769multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 5770 SDPatternOperator OpNode = null_frag> { 5771 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 5772 (outs FPR32:$Rd), 5773 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 5774 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 5775 (outs FPR64:$Rd), 5776 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 5777 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 5778} 5779 5780let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5781multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 5782 SDPatternOperator OpNode = null_frag> { 5783 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 5784 (outs FPR32:$dst), 5785 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 5786 asm, "$Rd = $dst", []>; 5787 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 5788 (outs FPR64:$dst), 5789 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 5790 asm, "$Rd = $dst", 5791 [(set (i64 FPR64:$dst), 5792 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 5793} 5794 5795//---------------------------------------------------------------------------- 5796// AdvSIMD two register scalar instructions 5797//---------------------------------------------------------------------------- 5798 5799let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5800class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 5801 RegisterClass regtype, RegisterClass regtype2, 5802 string asm, list<dag> pat> 5803 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 5804 "\t$Rd, $Rn", "", pat>, 5805 Sched<[WriteV]> { 5806 bits<5> Rd; 5807 bits<5> Rn; 5808 let Inst{31-30} = 0b01; 5809 let Inst{29} = U; 5810 let Inst{28-24} = 0b11110; 5811 let Inst{23-22} = size; 5812 let Inst{21} = 0b1; 5813 let Inst{20-19} = size2; 5814 let Inst{18-17} = 0b00; 5815 let Inst{16-12} = opcode; 5816 let Inst{11-10} = 0b10; 5817 let Inst{9-5} = Rn; 5818 let Inst{4-0} = Rd; 5819} 5820 5821let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5822class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 5823 RegisterClass regtype, RegisterClass regtype2, 5824 string asm, list<dag> pat> 5825 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 5826 "\t$Rd, $Rn", "$Rd = $dst", pat>, 5827 Sched<[WriteV]> { 5828 bits<5> Rd; 5829 bits<5> Rn; 5830 let Inst{31-30} = 0b01; 5831 let Inst{29} = U; 5832 let Inst{28-24} = 0b11110; 5833 let Inst{23-22} = size; 5834 let Inst{21-17} = 0b10000; 5835 let Inst{16-12} = opcode; 5836 let Inst{11-10} = 0b10; 5837 let Inst{9-5} = Rn; 5838 let Inst{4-0} = Rd; 5839} 5840 5841 5842let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5843class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 5844 RegisterClass regtype, string asm, string zero> 5845 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5846 "\t$Rd, $Rn, #" # zero, "", []>, 5847 Sched<[WriteV]> { 5848 bits<5> Rd; 5849 bits<5> Rn; 5850 let Inst{31-30} = 0b01; 5851 let Inst{29} = U; 5852 let Inst{28-24} = 0b11110; 5853 let Inst{23-22} = size; 5854 let Inst{21} = 0b1; 5855 let Inst{20-19} = size2; 5856 let Inst{18-17} = 0b00; 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 SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 5864 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 5865 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 5866 Sched<[WriteV]> { 5867 bits<5> Rd; 5868 bits<5> Rn; 5869 let Inst{31-17} = 0b011111100110000; 5870 let Inst{16-12} = opcode; 5871 let Inst{11-10} = 0b10; 5872 let Inst{9-5} = Rn; 5873 let Inst{4-0} = Rd; 5874} 5875 5876multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 5877 SDPatternOperator OpNode> { 5878 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 5879 5880 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 5881 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 5882} 5883 5884multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 5885 SDPatternOperator OpNode> { 5886 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 5887 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 5888 let Predicates = [HasNEON, HasFullFP16] in { 5889 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 5890 } 5891 5892 def : InstAlias<asm # "\t$Rd, $Rn, #0", 5893 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 5894 def : InstAlias<asm # "\t$Rd, $Rn, #0", 5895 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 5896 let Predicates = [HasNEON, HasFullFP16] in { 5897 def : InstAlias<asm # "\t$Rd, $Rn, #0", 5898 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 5899 } 5900 5901 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 5902 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 5903} 5904 5905multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 5906 SDPatternOperator OpNode = null_frag> { 5907 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 5908 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 5909 5910 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 5911 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 5912} 5913 5914multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 5915 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 5916 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 5917 let Predicates = [HasNEON, HasFullFP16] in { 5918 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 5919 } 5920} 5921 5922multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 5923 SDPatternOperator OpNode> { 5924 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 5925 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 5926 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 5927 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 5928 let Predicates = [HasNEON, HasFullFP16] in { 5929 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 5930 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>; 5931 } 5932} 5933 5934multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 5935 SDPatternOperator OpNode = null_frag> { 5936 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5937 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 5938 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 5939 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 5940 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 5941 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 5942 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 5943 } 5944 5945 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 5946 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 5947} 5948 5949multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 5950 Intrinsic OpNode> { 5951 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5952 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 5953 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 5954 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 5955 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 5956 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 5957 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 5958 } 5959 5960 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 5961 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 5962} 5963 5964 5965 5966let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5967multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 5968 SDPatternOperator OpNode = null_frag> { 5969 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 5970 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 5971 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 5972 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 5973} 5974 5975//---------------------------------------------------------------------------- 5976// AdvSIMD scalar pairwise instructions 5977//---------------------------------------------------------------------------- 5978 5979let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5980class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 5981 RegisterOperand regtype, RegisterOperand vectype, 5982 string asm, string kind> 5983 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 5984 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 5985 Sched<[WriteV]> { 5986 bits<5> Rd; 5987 bits<5> Rn; 5988 let Inst{31-30} = 0b01; 5989 let Inst{29} = U; 5990 let Inst{28-24} = 0b11110; 5991 let Inst{23-22} = size; 5992 let Inst{21-17} = 0b11000; 5993 let Inst{16-12} = opcode; 5994 let Inst{11-10} = 0b10; 5995 let Inst{9-5} = Rn; 5996 let Inst{4-0} = Rd; 5997} 5998 5999multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 6000 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 6001 asm, ".2d">; 6002} 6003 6004multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 6005 let Predicates = [HasNEON, HasFullFP16] in { 6006 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 6007 asm, ".2h">; 6008 } 6009 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 6010 asm, ".2s">; 6011 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 6012 asm, ".2d">; 6013} 6014 6015//---------------------------------------------------------------------------- 6016// AdvSIMD across lanes instructions 6017//---------------------------------------------------------------------------- 6018 6019let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6020class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 6021 RegisterClass regtype, RegisterOperand vectype, 6022 string asm, string kind, list<dag> pattern> 6023 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 6024 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 6025 Sched<[WriteV]> { 6026 bits<5> Rd; 6027 bits<5> Rn; 6028 let Inst{31} = 0; 6029 let Inst{30} = Q; 6030 let Inst{29} = U; 6031 let Inst{28-24} = 0b01110; 6032 let Inst{23-22} = size; 6033 let Inst{21-17} = 0b11000; 6034 let Inst{16-12} = opcode; 6035 let Inst{11-10} = 0b10; 6036 let Inst{9-5} = Rn; 6037 let Inst{4-0} = Rd; 6038} 6039 6040multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 6041 string asm> { 6042 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 6043 asm, ".8b", []>; 6044 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 6045 asm, ".16b", []>; 6046 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 6047 asm, ".4h", []>; 6048 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 6049 asm, ".8h", []>; 6050 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 6051 asm, ".4s", []>; 6052} 6053 6054multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 6055 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 6056 asm, ".8b", []>; 6057 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 6058 asm, ".16b", []>; 6059 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 6060 asm, ".4h", []>; 6061 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 6062 asm, ".8h", []>; 6063 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 6064 asm, ".4s", []>; 6065} 6066 6067multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 6068 Intrinsic intOp> { 6069 let Predicates = [HasNEON, HasFullFP16] in { 6070 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 6071 asm, ".4h", 6072 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>; 6073 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 6074 asm, ".8h", 6075 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>; 6076 } // Predicates = [HasNEON, HasFullFP16] 6077 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 6078 asm, ".4s", 6079 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 6080} 6081 6082//---------------------------------------------------------------------------- 6083// AdvSIMD INS/DUP instructions 6084//---------------------------------------------------------------------------- 6085 6086// FIXME: There has got to be a better way to factor these. ugh. 6087 6088class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 6089 string operands, string constraints, list<dag> pattern> 6090 : I<outs, ins, asm, operands, constraints, pattern>, 6091 Sched<[WriteV]> { 6092 bits<5> Rd; 6093 bits<5> Rn; 6094 let Inst{31} = 0; 6095 let Inst{30} = Q; 6096 let Inst{29} = op; 6097 let Inst{28-21} = 0b01110000; 6098 let Inst{15} = 0; 6099 let Inst{10} = 1; 6100 let Inst{9-5} = Rn; 6101 let Inst{4-0} = Rd; 6102} 6103 6104class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 6105 RegisterOperand vecreg, RegisterClass regtype> 6106 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 6107 "{\t$Rd" # size # ", $Rn" # 6108 "|" # size # "\t$Rd, $Rn}", "", 6109 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 6110 let Inst{20-16} = imm5; 6111 let Inst{14-11} = 0b0001; 6112} 6113 6114class SIMDDupFromElement<bit Q, string dstkind, string srckind, 6115 ValueType vectype, ValueType insreg, 6116 RegisterOperand vecreg, Operand idxtype, 6117 ValueType elttype, SDNode OpNode> 6118 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 6119 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 6120 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 6121 [(set (vectype vecreg:$Rd), 6122 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 6123 let Inst{14-11} = 0b0000; 6124} 6125 6126class SIMDDup64FromElement 6127 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 6128 VectorIndexD, i64, AArch64duplane64> { 6129 bits<1> idx; 6130 let Inst{20} = idx; 6131 let Inst{19-16} = 0b1000; 6132} 6133 6134class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 6135 RegisterOperand vecreg> 6136 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 6137 VectorIndexS, i64, AArch64duplane32> { 6138 bits<2> idx; 6139 let Inst{20-19} = idx; 6140 let Inst{18-16} = 0b100; 6141} 6142 6143class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 6144 RegisterOperand vecreg> 6145 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 6146 VectorIndexH, i64, AArch64duplane16> { 6147 bits<3> idx; 6148 let Inst{20-18} = idx; 6149 let Inst{17-16} = 0b10; 6150} 6151 6152class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 6153 RegisterOperand vecreg> 6154 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 6155 VectorIndexB, i64, AArch64duplane8> { 6156 bits<4> idx; 6157 let Inst{20-17} = idx; 6158 let Inst{16} = 1; 6159} 6160 6161class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 6162 Operand idxtype, string asm, list<dag> pattern> 6163 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 6164 "{\t$Rd, $Rn" # size # "$idx" # 6165 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 6166 let Inst{14-11} = imm4; 6167} 6168 6169class SIMDSMov<bit Q, string size, RegisterClass regtype, 6170 Operand idxtype> 6171 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 6172class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 6173 Operand idxtype> 6174 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 6175 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 6176 6177class SIMDMovAlias<string asm, string size, Instruction inst, 6178 RegisterClass regtype, Operand idxtype> 6179 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 6180 "|" # size # "\t$dst, $src$idx}", 6181 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 6182 6183multiclass SMov { 6184 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 6185 bits<4> idx; 6186 let Inst{20-17} = idx; 6187 let Inst{16} = 1; 6188 } 6189 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 6190 bits<4> idx; 6191 let Inst{20-17} = idx; 6192 let Inst{16} = 1; 6193 } 6194 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 6195 bits<3> idx; 6196 let Inst{20-18} = idx; 6197 let Inst{17-16} = 0b10; 6198 } 6199 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 6200 bits<3> idx; 6201 let Inst{20-18} = idx; 6202 let Inst{17-16} = 0b10; 6203 } 6204 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 6205 bits<2> idx; 6206 let Inst{20-19} = idx; 6207 let Inst{18-16} = 0b100; 6208 } 6209} 6210 6211multiclass UMov { 6212 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 6213 bits<4> idx; 6214 let Inst{20-17} = idx; 6215 let Inst{16} = 1; 6216 } 6217 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 6218 bits<3> idx; 6219 let Inst{20-18} = idx; 6220 let Inst{17-16} = 0b10; 6221 } 6222 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 6223 bits<2> idx; 6224 let Inst{20-19} = idx; 6225 let Inst{18-16} = 0b100; 6226 } 6227 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 6228 bits<1> idx; 6229 let Inst{20} = idx; 6230 let Inst{19-16} = 0b1000; 6231 } 6232 def : SIMDMovAlias<"mov", ".s", 6233 !cast<Instruction>(NAME#"vi32"), 6234 GPR32, VectorIndexS>; 6235 def : SIMDMovAlias<"mov", ".d", 6236 !cast<Instruction>(NAME#"vi64"), 6237 GPR64, VectorIndexD>; 6238} 6239 6240class SIMDInsFromMain<string size, ValueType vectype, 6241 RegisterClass regtype, Operand idxtype> 6242 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 6243 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 6244 "{\t$Rd" # size # "$idx, $Rn" # 6245 "|" # size # "\t$Rd$idx, $Rn}", 6246 "$Rd = $dst", 6247 [(set V128:$dst, 6248 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 6249 let Inst{14-11} = 0b0011; 6250} 6251 6252class SIMDInsFromElement<string size, ValueType vectype, 6253 ValueType elttype, Operand idxtype> 6254 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 6255 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 6256 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 6257 "|" # size # "\t$Rd$idx, $Rn$idx2}", 6258 "$Rd = $dst", 6259 [(set V128:$dst, 6260 (vector_insert 6261 (vectype V128:$Rd), 6262 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 6263 idxtype:$idx))]>; 6264 6265class SIMDInsMainMovAlias<string size, Instruction inst, 6266 RegisterClass regtype, Operand idxtype> 6267 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 6268 "|" # size #"\t$dst$idx, $src}", 6269 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 6270class SIMDInsElementMovAlias<string size, Instruction inst, 6271 Operand idxtype> 6272 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" # 6273 # "|" # size #"\t$dst$idx, $src$idx2}", 6274 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 6275 6276 6277multiclass SIMDIns { 6278 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 6279 bits<4> idx; 6280 let Inst{20-17} = idx; 6281 let Inst{16} = 1; 6282 } 6283 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 6284 bits<3> idx; 6285 let Inst{20-18} = idx; 6286 let Inst{17-16} = 0b10; 6287 } 6288 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 6289 bits<2> idx; 6290 let Inst{20-19} = idx; 6291 let Inst{18-16} = 0b100; 6292 } 6293 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 6294 bits<1> idx; 6295 let Inst{20} = idx; 6296 let Inst{19-16} = 0b1000; 6297 } 6298 6299 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 6300 bits<4> idx; 6301 bits<4> idx2; 6302 let Inst{20-17} = idx; 6303 let Inst{16} = 1; 6304 let Inst{14-11} = idx2; 6305 } 6306 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 6307 bits<3> idx; 6308 bits<3> idx2; 6309 let Inst{20-18} = idx; 6310 let Inst{17-16} = 0b10; 6311 let Inst{14-12} = idx2; 6312 let Inst{11} = {?}; 6313 } 6314 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 6315 bits<2> idx; 6316 bits<2> idx2; 6317 let Inst{20-19} = idx; 6318 let Inst{18-16} = 0b100; 6319 let Inst{14-13} = idx2; 6320 let Inst{12-11} = {?,?}; 6321 } 6322 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 6323 bits<1> idx; 6324 bits<1> idx2; 6325 let Inst{20} = idx; 6326 let Inst{19-16} = 0b1000; 6327 let Inst{14} = idx2; 6328 let Inst{13-11} = {?,?,?}; 6329 } 6330 6331 // For all forms of the INS instruction, the "mov" mnemonic is the 6332 // preferred alias. Why they didn't just call the instruction "mov" in 6333 // the first place is a very good question indeed... 6334 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 6335 GPR32, VectorIndexB>; 6336 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 6337 GPR32, VectorIndexH>; 6338 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 6339 GPR32, VectorIndexS>; 6340 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 6341 GPR64, VectorIndexD>; 6342 6343 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 6344 VectorIndexB>; 6345 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 6346 VectorIndexH>; 6347 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 6348 VectorIndexS>; 6349 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 6350 VectorIndexD>; 6351} 6352 6353//---------------------------------------------------------------------------- 6354// AdvSIMD TBL/TBX 6355//---------------------------------------------------------------------------- 6356 6357let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6358class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 6359 RegisterOperand listtype, string asm, string kind> 6360 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 6361 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 6362 Sched<[WriteV]> { 6363 bits<5> Vd; 6364 bits<5> Vn; 6365 bits<5> Vm; 6366 let Inst{31} = 0; 6367 let Inst{30} = Q; 6368 let Inst{29-21} = 0b001110000; 6369 let Inst{20-16} = Vm; 6370 let Inst{15} = 0; 6371 let Inst{14-13} = len; 6372 let Inst{12} = op; 6373 let Inst{11-10} = 0b00; 6374 let Inst{9-5} = Vn; 6375 let Inst{4-0} = Vd; 6376} 6377 6378let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6379class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 6380 RegisterOperand listtype, string asm, string kind> 6381 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 6382 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 6383 Sched<[WriteV]> { 6384 bits<5> Vd; 6385 bits<5> Vn; 6386 bits<5> Vm; 6387 let Inst{31} = 0; 6388 let Inst{30} = Q; 6389 let Inst{29-21} = 0b001110000; 6390 let Inst{20-16} = Vm; 6391 let Inst{15} = 0; 6392 let Inst{14-13} = len; 6393 let Inst{12} = op; 6394 let Inst{11-10} = 0b00; 6395 let Inst{9-5} = Vn; 6396 let Inst{4-0} = Vd; 6397} 6398 6399class SIMDTableLookupAlias<string asm, Instruction inst, 6400 RegisterOperand vectype, RegisterOperand listtype> 6401 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 6402 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 6403 6404multiclass SIMDTableLookup<bit op, string asm> { 6405 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 6406 asm, ".8b">; 6407 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 6408 asm, ".8b">; 6409 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 6410 asm, ".8b">; 6411 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 6412 asm, ".8b">; 6413 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 6414 asm, ".16b">; 6415 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 6416 asm, ".16b">; 6417 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 6418 asm, ".16b">; 6419 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 6420 asm, ".16b">; 6421 6422 def : SIMDTableLookupAlias<asm # ".8b", 6423 !cast<Instruction>(NAME#"v8i8One"), 6424 V64, VecListOne128>; 6425 def : SIMDTableLookupAlias<asm # ".8b", 6426 !cast<Instruction>(NAME#"v8i8Two"), 6427 V64, VecListTwo128>; 6428 def : SIMDTableLookupAlias<asm # ".8b", 6429 !cast<Instruction>(NAME#"v8i8Three"), 6430 V64, VecListThree128>; 6431 def : SIMDTableLookupAlias<asm # ".8b", 6432 !cast<Instruction>(NAME#"v8i8Four"), 6433 V64, VecListFour128>; 6434 def : SIMDTableLookupAlias<asm # ".16b", 6435 !cast<Instruction>(NAME#"v16i8One"), 6436 V128, VecListOne128>; 6437 def : SIMDTableLookupAlias<asm # ".16b", 6438 !cast<Instruction>(NAME#"v16i8Two"), 6439 V128, VecListTwo128>; 6440 def : SIMDTableLookupAlias<asm # ".16b", 6441 !cast<Instruction>(NAME#"v16i8Three"), 6442 V128, VecListThree128>; 6443 def : SIMDTableLookupAlias<asm # ".16b", 6444 !cast<Instruction>(NAME#"v16i8Four"), 6445 V128, VecListFour128>; 6446} 6447 6448multiclass SIMDTableLookupTied<bit op, string asm> { 6449 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 6450 asm, ".8b">; 6451 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 6452 asm, ".8b">; 6453 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 6454 asm, ".8b">; 6455 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 6456 asm, ".8b">; 6457 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 6458 asm, ".16b">; 6459 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 6460 asm, ".16b">; 6461 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 6462 asm, ".16b">; 6463 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 6464 asm, ".16b">; 6465 6466 def : SIMDTableLookupAlias<asm # ".8b", 6467 !cast<Instruction>(NAME#"v8i8One"), 6468 V64, VecListOne128>; 6469 def : SIMDTableLookupAlias<asm # ".8b", 6470 !cast<Instruction>(NAME#"v8i8Two"), 6471 V64, VecListTwo128>; 6472 def : SIMDTableLookupAlias<asm # ".8b", 6473 !cast<Instruction>(NAME#"v8i8Three"), 6474 V64, VecListThree128>; 6475 def : SIMDTableLookupAlias<asm # ".8b", 6476 !cast<Instruction>(NAME#"v8i8Four"), 6477 V64, VecListFour128>; 6478 def : SIMDTableLookupAlias<asm # ".16b", 6479 !cast<Instruction>(NAME#"v16i8One"), 6480 V128, VecListOne128>; 6481 def : SIMDTableLookupAlias<asm # ".16b", 6482 !cast<Instruction>(NAME#"v16i8Two"), 6483 V128, VecListTwo128>; 6484 def : SIMDTableLookupAlias<asm # ".16b", 6485 !cast<Instruction>(NAME#"v16i8Three"), 6486 V128, VecListThree128>; 6487 def : SIMDTableLookupAlias<asm # ".16b", 6488 !cast<Instruction>(NAME#"v16i8Four"), 6489 V128, VecListFour128>; 6490} 6491 6492 6493//---------------------------------------------------------------------------- 6494// AdvSIMD scalar CPY 6495//---------------------------------------------------------------------------- 6496let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6497class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 6498 string kind, Operand idxtype> 6499 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 6500 "{\t$dst, $src" # kind # "$idx" # 6501 "|\t$dst, $src$idx}", "", []>, 6502 Sched<[WriteV]> { 6503 bits<5> dst; 6504 bits<5> src; 6505 let Inst{31-21} = 0b01011110000; 6506 let Inst{15-10} = 0b000001; 6507 let Inst{9-5} = src; 6508 let Inst{4-0} = dst; 6509} 6510 6511class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 6512 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 6513 : InstAlias<asm # "{\t$dst, $src" # size # "$index" # 6514 # "|\t$dst, $src$index}", 6515 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 6516 6517 6518multiclass SIMDScalarCPY<string asm> { 6519 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 6520 bits<4> idx; 6521 let Inst{20-17} = idx; 6522 let Inst{16} = 1; 6523 } 6524 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 6525 bits<3> idx; 6526 let Inst{20-18} = idx; 6527 let Inst{17-16} = 0b10; 6528 } 6529 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 6530 bits<2> idx; 6531 let Inst{20-19} = idx; 6532 let Inst{18-16} = 0b100; 6533 } 6534 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 6535 bits<1> idx; 6536 let Inst{20} = idx; 6537 let Inst{19-16} = 0b1000; 6538 } 6539 6540 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 6541 VectorIndexD:$idx)))), 6542 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 6543 6544 // 'DUP' mnemonic aliases. 6545 def : SIMDScalarCPYAlias<"dup", ".b", 6546 !cast<Instruction>(NAME#"i8"), 6547 FPR8, V128, VectorIndexB>; 6548 def : SIMDScalarCPYAlias<"dup", ".h", 6549 !cast<Instruction>(NAME#"i16"), 6550 FPR16, V128, VectorIndexH>; 6551 def : SIMDScalarCPYAlias<"dup", ".s", 6552 !cast<Instruction>(NAME#"i32"), 6553 FPR32, V128, VectorIndexS>; 6554 def : SIMDScalarCPYAlias<"dup", ".d", 6555 !cast<Instruction>(NAME#"i64"), 6556 FPR64, V128, VectorIndexD>; 6557} 6558 6559//---------------------------------------------------------------------------- 6560// AdvSIMD modified immediate instructions 6561//---------------------------------------------------------------------------- 6562 6563class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 6564 string asm, string op_string, 6565 string cstr, list<dag> pattern> 6566 : I<oops, iops, asm, op_string, cstr, pattern>, 6567 Sched<[WriteV]> { 6568 bits<5> Rd; 6569 bits<8> imm8; 6570 let Inst{31} = 0; 6571 let Inst{30} = Q; 6572 let Inst{29} = op; 6573 let Inst{28-19} = 0b0111100000; 6574 let Inst{18-16} = imm8{7-5}; 6575 let Inst{11} = op2; 6576 let Inst{10} = 1; 6577 let Inst{9-5} = imm8{4-0}; 6578 let Inst{4-0} = Rd; 6579} 6580 6581class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 6582 Operand immtype, dag opt_shift_iop, 6583 string opt_shift, string asm, string kind, 6584 list<dag> pattern> 6585 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 6586 !con((ins immtype:$imm8), opt_shift_iop), asm, 6587 "{\t$Rd" # kind # ", $imm8" # opt_shift # 6588 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 6589 "", pattern> { 6590 let DecoderMethod = "DecodeModImmInstruction"; 6591} 6592 6593class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 6594 Operand immtype, dag opt_shift_iop, 6595 string opt_shift, string asm, string kind, 6596 list<dag> pattern> 6597 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 6598 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 6599 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 6600 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 6601 "$Rd = $dst", pattern> { 6602 let DecoderMethod = "DecodeModImmTiedInstruction"; 6603} 6604 6605class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 6606 RegisterOperand vectype, string asm, 6607 string kind, list<dag> pattern> 6608 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 6609 (ins logical_vec_shift:$shift), 6610 "$shift", asm, kind, pattern> { 6611 bits<2> shift; 6612 let Inst{15} = b15_b12{1}; 6613 let Inst{14-13} = shift; 6614 let Inst{12} = b15_b12{0}; 6615} 6616 6617class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 6618 RegisterOperand vectype, string asm, 6619 string kind, list<dag> pattern> 6620 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 6621 (ins logical_vec_shift:$shift), 6622 "$shift", asm, kind, pattern> { 6623 bits<2> shift; 6624 let Inst{15} = b15_b12{1}; 6625 let Inst{14-13} = shift; 6626 let Inst{12} = b15_b12{0}; 6627} 6628 6629 6630class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 6631 RegisterOperand vectype, string asm, 6632 string kind, list<dag> pattern> 6633 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 6634 (ins logical_vec_hw_shift:$shift), 6635 "$shift", asm, kind, pattern> { 6636 bits<2> shift; 6637 let Inst{15} = b15_b12{1}; 6638 let Inst{14} = 0; 6639 let Inst{13} = shift{0}; 6640 let Inst{12} = b15_b12{0}; 6641} 6642 6643class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 6644 RegisterOperand vectype, string asm, 6645 string kind, list<dag> pattern> 6646 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 6647 (ins logical_vec_hw_shift:$shift), 6648 "$shift", asm, kind, pattern> { 6649 bits<2> shift; 6650 let Inst{15} = b15_b12{1}; 6651 let Inst{14} = 0; 6652 let Inst{13} = shift{0}; 6653 let Inst{12} = b15_b12{0}; 6654} 6655 6656multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 6657 string asm> { 6658 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 6659 asm, ".4h", []>; 6660 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 6661 asm, ".8h", []>; 6662 6663 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 6664 asm, ".2s", []>; 6665 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 6666 asm, ".4s", []>; 6667} 6668 6669multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 6670 bits<2> w_cmode, string asm, 6671 SDNode OpNode> { 6672 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 6673 asm, ".4h", 6674 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 6675 imm0_255:$imm8, 6676 (i32 imm:$shift)))]>; 6677 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 6678 asm, ".8h", 6679 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 6680 imm0_255:$imm8, 6681 (i32 imm:$shift)))]>; 6682 6683 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 6684 asm, ".2s", 6685 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 6686 imm0_255:$imm8, 6687 (i32 imm:$shift)))]>; 6688 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 6689 asm, ".4s", 6690 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 6691 imm0_255:$imm8, 6692 (i32 imm:$shift)))]>; 6693} 6694 6695class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 6696 RegisterOperand vectype, string asm, 6697 string kind, list<dag> pattern> 6698 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 6699 (ins move_vec_shift:$shift), 6700 "$shift", asm, kind, pattern> { 6701 bits<1> shift; 6702 let Inst{15-13} = cmode{3-1}; 6703 let Inst{12} = shift; 6704} 6705 6706class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 6707 RegisterOperand vectype, 6708 Operand imm_type, string asm, 6709 string kind, list<dag> pattern> 6710 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 6711 asm, kind, pattern> { 6712 let Inst{15-12} = cmode; 6713} 6714 6715class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 6716 list<dag> pattern> 6717 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 6718 "\t$Rd, $imm8", "", pattern> { 6719 let Inst{15-12} = cmode; 6720 let DecoderMethod = "DecodeModImmInstruction"; 6721} 6722 6723//---------------------------------------------------------------------------- 6724// AdvSIMD indexed element 6725//---------------------------------------------------------------------------- 6726 6727let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6728class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 6729 RegisterOperand dst_reg, RegisterOperand lhs_reg, 6730 RegisterOperand rhs_reg, Operand vec_idx, string asm, 6731 string apple_kind, string dst_kind, string lhs_kind, 6732 string rhs_kind, list<dag> pattern> 6733 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 6734 asm, 6735 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 6736 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 6737 Sched<[WriteV]> { 6738 bits<5> Rd; 6739 bits<5> Rn; 6740 bits<5> Rm; 6741 6742 let Inst{31} = 0; 6743 let Inst{30} = Q; 6744 let Inst{29} = U; 6745 let Inst{28} = Scalar; 6746 let Inst{27-24} = 0b1111; 6747 let Inst{23-22} = size; 6748 // Bit 21 must be set by the derived class. 6749 let Inst{20-16} = Rm; 6750 let Inst{15-12} = opc; 6751 // Bit 11 must be set by the derived class. 6752 let Inst{10} = 0; 6753 let Inst{9-5} = Rn; 6754 let Inst{4-0} = Rd; 6755} 6756 6757let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6758class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 6759 RegisterOperand dst_reg, RegisterOperand lhs_reg, 6760 RegisterOperand rhs_reg, Operand vec_idx, string asm, 6761 string apple_kind, string dst_kind, string lhs_kind, 6762 string rhs_kind, list<dag> pattern> 6763 : I<(outs dst_reg:$dst), 6764 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 6765 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 6766 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 6767 Sched<[WriteV]> { 6768 bits<5> Rd; 6769 bits<5> Rn; 6770 bits<5> Rm; 6771 6772 let Inst{31} = 0; 6773 let Inst{30} = Q; 6774 let Inst{29} = U; 6775 let Inst{28} = Scalar; 6776 let Inst{27-24} = 0b1111; 6777 let Inst{23-22} = size; 6778 // Bit 21 must be set by the derived class. 6779 let Inst{20-16} = Rm; 6780 let Inst{15-12} = opc; 6781 // Bit 11 must be set by the derived class. 6782 let Inst{10} = 0; 6783 let Inst{9-5} = Rn; 6784 let Inst{4-0} = Rd; 6785} 6786 6787multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 6788 SDPatternOperator OpNode> { 6789 let Predicates = [HasNEON, HasFullFP16] in { 6790 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 6791 V64, V64, 6792 V128_lo, VectorIndexH, 6793 asm, ".4h", ".4h", ".4h", ".h", 6794 [(set (v4f16 V64:$Rd), 6795 (OpNode (v4f16 V64:$Rn), 6796 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6797 bits<3> idx; 6798 let Inst{11} = idx{2}; 6799 let Inst{21} = idx{1}; 6800 let Inst{20} = idx{0}; 6801 } 6802 6803 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 6804 V128, V128, 6805 V128_lo, VectorIndexH, 6806 asm, ".8h", ".8h", ".8h", ".h", 6807 [(set (v8f16 V128:$Rd), 6808 (OpNode (v8f16 V128:$Rn), 6809 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6810 bits<3> idx; 6811 let Inst{11} = idx{2}; 6812 let Inst{21} = idx{1}; 6813 let Inst{20} = idx{0}; 6814 } 6815 } // Predicates = [HasNEON, HasFullFP16] 6816 6817 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6818 V64, V64, 6819 V128, VectorIndexS, 6820 asm, ".2s", ".2s", ".2s", ".s", 6821 [(set (v2f32 V64:$Rd), 6822 (OpNode (v2f32 V64:$Rn), 6823 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 6824 bits<2> idx; 6825 let Inst{11} = idx{1}; 6826 let Inst{21} = idx{0}; 6827 } 6828 6829 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6830 V128, V128, 6831 V128, VectorIndexS, 6832 asm, ".4s", ".4s", ".4s", ".s", 6833 [(set (v4f32 V128:$Rd), 6834 (OpNode (v4f32 V128:$Rn), 6835 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 6836 bits<2> idx; 6837 let Inst{11} = idx{1}; 6838 let Inst{21} = idx{0}; 6839 } 6840 6841 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 6842 V128, V128, 6843 V128, VectorIndexD, 6844 asm, ".2d", ".2d", ".2d", ".d", 6845 [(set (v2f64 V128:$Rd), 6846 (OpNode (v2f64 V128:$Rn), 6847 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 6848 bits<1> idx; 6849 let Inst{11} = idx{0}; 6850 let Inst{21} = 0; 6851 } 6852 6853 let Predicates = [HasNEON, HasFullFP16] in { 6854 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 6855 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 6856 asm, ".h", "", "", ".h", 6857 [(set (f16 FPR16Op:$Rd), 6858 (OpNode (f16 FPR16Op:$Rn), 6859 (f16 (vector_extract (v8f16 V128_lo:$Rm), 6860 VectorIndexH:$idx))))]> { 6861 bits<3> idx; 6862 let Inst{11} = idx{2}; 6863 let Inst{21} = idx{1}; 6864 let Inst{20} = idx{0}; 6865 } 6866 } // Predicates = [HasNEON, HasFullFP16] 6867 6868 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 6869 FPR32Op, FPR32Op, V128, VectorIndexS, 6870 asm, ".s", "", "", ".s", 6871 [(set (f32 FPR32Op:$Rd), 6872 (OpNode (f32 FPR32Op:$Rn), 6873 (f32 (vector_extract (v4f32 V128:$Rm), 6874 VectorIndexS:$idx))))]> { 6875 bits<2> idx; 6876 let Inst{11} = idx{1}; 6877 let Inst{21} = idx{0}; 6878 } 6879 6880 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 6881 FPR64Op, FPR64Op, V128, VectorIndexD, 6882 asm, ".d", "", "", ".d", 6883 [(set (f64 FPR64Op:$Rd), 6884 (OpNode (f64 FPR64Op:$Rn), 6885 (f64 (vector_extract (v2f64 V128:$Rm), 6886 VectorIndexD:$idx))))]> { 6887 bits<1> idx; 6888 let Inst{11} = idx{0}; 6889 let Inst{21} = 0; 6890 } 6891} 6892 6893multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 6894 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 6895 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 6896 (AArch64duplane32 (v4f32 V128:$Rm), 6897 VectorIndexS:$idx))), 6898 (!cast<Instruction>(INST # v2i32_indexed) 6899 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6900 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 6901 (AArch64dup (f32 FPR32Op:$Rm)))), 6902 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 6903 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 6904 6905 6906 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 6907 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 6908 (AArch64duplane32 (v4f32 V128:$Rm), 6909 VectorIndexS:$idx))), 6910 (!cast<Instruction>(INST # "v4i32_indexed") 6911 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6912 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 6913 (AArch64dup (f32 FPR32Op:$Rm)))), 6914 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 6915 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 6916 6917 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 6918 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 6919 (AArch64duplane64 (v2f64 V128:$Rm), 6920 VectorIndexD:$idx))), 6921 (!cast<Instruction>(INST # "v2i64_indexed") 6922 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6923 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 6924 (AArch64dup (f64 FPR64Op:$Rm)))), 6925 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 6926 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 6927 6928 // 2 variants for 32-bit scalar version: extract from .2s or from .4s 6929 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 6930 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 6931 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 6932 V128:$Rm, VectorIndexS:$idx)>; 6933 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 6934 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))), 6935 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 6936 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>; 6937 6938 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 6939 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 6940 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 6941 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 6942 V128:$Rm, VectorIndexD:$idx)>; 6943} 6944 6945multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 6946 let Predicates = [HasNEON, HasFullFP16] in { 6947 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 6948 V128_lo, VectorIndexH, 6949 asm, ".4h", ".4h", ".4h", ".h", []> { 6950 bits<3> idx; 6951 let Inst{11} = idx{2}; 6952 let Inst{21} = idx{1}; 6953 let Inst{20} = idx{0}; 6954 } 6955 6956 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 6957 V128, V128, 6958 V128_lo, VectorIndexH, 6959 asm, ".8h", ".8h", ".8h", ".h", []> { 6960 bits<3> idx; 6961 let Inst{11} = idx{2}; 6962 let Inst{21} = idx{1}; 6963 let Inst{20} = idx{0}; 6964 } 6965 } // Predicates = [HasNEON, HasFullFP16] 6966 6967 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 6968 V128, VectorIndexS, 6969 asm, ".2s", ".2s", ".2s", ".s", []> { 6970 bits<2> idx; 6971 let Inst{11} = idx{1}; 6972 let Inst{21} = idx{0}; 6973 } 6974 6975 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 6976 V128, V128, 6977 V128, VectorIndexS, 6978 asm, ".4s", ".4s", ".4s", ".s", []> { 6979 bits<2> idx; 6980 let Inst{11} = idx{1}; 6981 let Inst{21} = idx{0}; 6982 } 6983 6984 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 6985 V128, V128, 6986 V128, VectorIndexD, 6987 asm, ".2d", ".2d", ".2d", ".d", []> { 6988 bits<1> idx; 6989 let Inst{11} = idx{0}; 6990 let Inst{21} = 0; 6991 } 6992 6993 let Predicates = [HasNEON, HasFullFP16] in { 6994 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 6995 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 6996 asm, ".h", "", "", ".h", []> { 6997 bits<3> idx; 6998 let Inst{11} = idx{2}; 6999 let Inst{21} = idx{1}; 7000 let Inst{20} = idx{0}; 7001 } 7002 } // Predicates = [HasNEON, HasFullFP16] 7003 7004 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 7005 FPR32Op, FPR32Op, V128, VectorIndexS, 7006 asm, ".s", "", "", ".s", []> { 7007 bits<2> idx; 7008 let Inst{11} = idx{1}; 7009 let Inst{21} = idx{0}; 7010 } 7011 7012 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 7013 FPR64Op, FPR64Op, V128, VectorIndexD, 7014 asm, ".d", "", "", ".d", []> { 7015 bits<1> idx; 7016 let Inst{11} = idx{0}; 7017 let Inst{21} = 0; 7018 } 7019} 7020 7021multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 7022 SDPatternOperator OpNode> { 7023 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 7024 V128_lo, VectorIndexH, 7025 asm, ".4h", ".4h", ".4h", ".h", 7026 [(set (v4i16 V64:$Rd), 7027 (OpNode (v4i16 V64:$Rn), 7028 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7029 bits<3> idx; 7030 let Inst{11} = idx{2}; 7031 let Inst{21} = idx{1}; 7032 let Inst{20} = idx{0}; 7033 } 7034 7035 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7036 V128, V128, 7037 V128_lo, VectorIndexH, 7038 asm, ".8h", ".8h", ".8h", ".h", 7039 [(set (v8i16 V128:$Rd), 7040 (OpNode (v8i16 V128:$Rn), 7041 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7042 bits<3> idx; 7043 let Inst{11} = idx{2}; 7044 let Inst{21} = idx{1}; 7045 let Inst{20} = idx{0}; 7046 } 7047 7048 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7049 V64, V64, 7050 V128, VectorIndexS, 7051 asm, ".2s", ".2s", ".2s", ".s", 7052 [(set (v2i32 V64:$Rd), 7053 (OpNode (v2i32 V64:$Rn), 7054 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7055 bits<2> idx; 7056 let Inst{11} = idx{1}; 7057 let Inst{21} = idx{0}; 7058 } 7059 7060 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7061 V128, V128, 7062 V128, VectorIndexS, 7063 asm, ".4s", ".4s", ".4s", ".s", 7064 [(set (v4i32 V128:$Rd), 7065 (OpNode (v4i32 V128:$Rn), 7066 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7067 bits<2> idx; 7068 let Inst{11} = idx{1}; 7069 let Inst{21} = idx{0}; 7070 } 7071 7072 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 7073 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7074 asm, ".h", "", "", ".h", []> { 7075 bits<3> idx; 7076 let Inst{11} = idx{2}; 7077 let Inst{21} = idx{1}; 7078 let Inst{20} = idx{0}; 7079 } 7080 7081 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7082 FPR32Op, FPR32Op, V128, VectorIndexS, 7083 asm, ".s", "", "", ".s", 7084 [(set (i32 FPR32Op:$Rd), 7085 (OpNode FPR32Op:$Rn, 7086 (i32 (vector_extract (v4i32 V128:$Rm), 7087 VectorIndexS:$idx))))]> { 7088 bits<2> idx; 7089 let Inst{11} = idx{1}; 7090 let Inst{21} = idx{0}; 7091 } 7092} 7093 7094multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 7095 SDPatternOperator OpNode> { 7096 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7097 V64, V64, 7098 V128_lo, VectorIndexH, 7099 asm, ".4h", ".4h", ".4h", ".h", 7100 [(set (v4i16 V64:$Rd), 7101 (OpNode (v4i16 V64:$Rn), 7102 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7103 bits<3> idx; 7104 let Inst{11} = idx{2}; 7105 let Inst{21} = idx{1}; 7106 let Inst{20} = idx{0}; 7107 } 7108 7109 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7110 V128, V128, 7111 V128_lo, VectorIndexH, 7112 asm, ".8h", ".8h", ".8h", ".h", 7113 [(set (v8i16 V128:$Rd), 7114 (OpNode (v8i16 V128:$Rn), 7115 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7116 bits<3> idx; 7117 let Inst{11} = idx{2}; 7118 let Inst{21} = idx{1}; 7119 let Inst{20} = idx{0}; 7120 } 7121 7122 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7123 V64, V64, 7124 V128, VectorIndexS, 7125 asm, ".2s", ".2s", ".2s", ".s", 7126 [(set (v2i32 V64:$Rd), 7127 (OpNode (v2i32 V64:$Rn), 7128 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7129 bits<2> idx; 7130 let Inst{11} = idx{1}; 7131 let Inst{21} = idx{0}; 7132 } 7133 7134 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7135 V128, V128, 7136 V128, VectorIndexS, 7137 asm, ".4s", ".4s", ".4s", ".s", 7138 [(set (v4i32 V128:$Rd), 7139 (OpNode (v4i32 V128:$Rn), 7140 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7141 bits<2> idx; 7142 let Inst{11} = idx{1}; 7143 let Inst{21} = idx{0}; 7144 } 7145} 7146 7147multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 7148 SDPatternOperator OpNode> { 7149 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 7150 V128_lo, VectorIndexH, 7151 asm, ".4h", ".4h", ".4h", ".h", 7152 [(set (v4i16 V64:$dst), 7153 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 7154 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7155 bits<3> idx; 7156 let Inst{11} = idx{2}; 7157 let Inst{21} = idx{1}; 7158 let Inst{20} = idx{0}; 7159 } 7160 7161 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7162 V128, V128, 7163 V128_lo, VectorIndexH, 7164 asm, ".8h", ".8h", ".8h", ".h", 7165 [(set (v8i16 V128:$dst), 7166 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 7167 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7168 bits<3> idx; 7169 let Inst{11} = idx{2}; 7170 let Inst{21} = idx{1}; 7171 let Inst{20} = idx{0}; 7172 } 7173 7174 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7175 V64, V64, 7176 V128, VectorIndexS, 7177 asm, ".2s", ".2s", ".2s", ".s", 7178 [(set (v2i32 V64:$dst), 7179 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 7180 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7181 bits<2> idx; 7182 let Inst{11} = idx{1}; 7183 let Inst{21} = idx{0}; 7184 } 7185 7186 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7187 V128, V128, 7188 V128, VectorIndexS, 7189 asm, ".4s", ".4s", ".4s", ".s", 7190 [(set (v4i32 V128:$dst), 7191 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 7192 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7193 bits<2> idx; 7194 let Inst{11} = idx{1}; 7195 let Inst{21} = idx{0}; 7196 } 7197} 7198 7199multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 7200 SDPatternOperator OpNode> { 7201 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7202 V128, V64, 7203 V128_lo, VectorIndexH, 7204 asm, ".4s", ".4s", ".4h", ".h", 7205 [(set (v4i32 V128:$Rd), 7206 (OpNode (v4i16 V64:$Rn), 7207 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7208 bits<3> idx; 7209 let Inst{11} = idx{2}; 7210 let Inst{21} = idx{1}; 7211 let Inst{20} = idx{0}; 7212 } 7213 7214 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7215 V128, V128, 7216 V128_lo, VectorIndexH, 7217 asm#"2", ".4s", ".4s", ".8h", ".h", 7218 [(set (v4i32 V128:$Rd), 7219 (OpNode (extract_high_v8i16 V128:$Rn), 7220 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7221 VectorIndexH:$idx))))]> { 7222 7223 bits<3> idx; 7224 let Inst{11} = idx{2}; 7225 let Inst{21} = idx{1}; 7226 let Inst{20} = idx{0}; 7227 } 7228 7229 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7230 V128, V64, 7231 V128, VectorIndexS, 7232 asm, ".2d", ".2d", ".2s", ".s", 7233 [(set (v2i64 V128:$Rd), 7234 (OpNode (v2i32 V64:$Rn), 7235 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7236 bits<2> idx; 7237 let Inst{11} = idx{1}; 7238 let Inst{21} = idx{0}; 7239 } 7240 7241 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7242 V128, V128, 7243 V128, VectorIndexS, 7244 asm#"2", ".2d", ".2d", ".4s", ".s", 7245 [(set (v2i64 V128:$Rd), 7246 (OpNode (extract_high_v4i32 V128:$Rn), 7247 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 7248 VectorIndexS:$idx))))]> { 7249 bits<2> idx; 7250 let Inst{11} = idx{1}; 7251 let Inst{21} = idx{0}; 7252 } 7253 7254 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 7255 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 7256 asm, ".h", "", "", ".h", []> { 7257 bits<3> idx; 7258 let Inst{11} = idx{2}; 7259 let Inst{21} = idx{1}; 7260 let Inst{20} = idx{0}; 7261 } 7262 7263 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7264 FPR64Op, FPR32Op, V128, VectorIndexS, 7265 asm, ".s", "", "", ".s", []> { 7266 bits<2> idx; 7267 let Inst{11} = idx{1}; 7268 let Inst{21} = idx{0}; 7269 } 7270} 7271 7272multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 7273 SDPatternOperator Accum> { 7274 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 7275 V128, V64, 7276 V128_lo, VectorIndexH, 7277 asm, ".4s", ".4s", ".4h", ".h", 7278 [(set (v4i32 V128:$dst), 7279 (Accum (v4i32 V128:$Rd), 7280 (v4i32 (int_aarch64_neon_sqdmull 7281 (v4i16 V64:$Rn), 7282 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7283 VectorIndexH:$idx))))))]> { 7284 bits<3> idx; 7285 let Inst{11} = idx{2}; 7286 let Inst{21} = idx{1}; 7287 let Inst{20} = idx{0}; 7288 } 7289 7290 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 7291 // intermediate EXTRACT_SUBREG would be untyped. 7292 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 7293 (i32 (vector_extract (v4i32 7294 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 7295 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7296 VectorIndexH:$idx)))), 7297 (i64 0))))), 7298 (EXTRACT_SUBREG 7299 (!cast<Instruction>(NAME # v4i16_indexed) 7300 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 7301 V128_lo:$Rm, VectorIndexH:$idx), 7302 ssub)>; 7303 7304 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7305 V128, V128, 7306 V128_lo, VectorIndexH, 7307 asm#"2", ".4s", ".4s", ".8h", ".h", 7308 [(set (v4i32 V128:$dst), 7309 (Accum (v4i32 V128:$Rd), 7310 (v4i32 (int_aarch64_neon_sqdmull 7311 (extract_high_v8i16 V128:$Rn), 7312 (extract_high_v8i16 7313 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7314 VectorIndexH:$idx))))))]> { 7315 bits<3> idx; 7316 let Inst{11} = idx{2}; 7317 let Inst{21} = idx{1}; 7318 let Inst{20} = idx{0}; 7319 } 7320 7321 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7322 V128, V64, 7323 V128, VectorIndexS, 7324 asm, ".2d", ".2d", ".2s", ".s", 7325 [(set (v2i64 V128:$dst), 7326 (Accum (v2i64 V128:$Rd), 7327 (v2i64 (int_aarch64_neon_sqdmull 7328 (v2i32 V64:$Rn), 7329 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 7330 VectorIndexS:$idx))))))]> { 7331 bits<2> idx; 7332 let Inst{11} = idx{1}; 7333 let Inst{21} = idx{0}; 7334 } 7335 7336 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7337 V128, V128, 7338 V128, VectorIndexS, 7339 asm#"2", ".2d", ".2d", ".4s", ".s", 7340 [(set (v2i64 V128:$dst), 7341 (Accum (v2i64 V128:$Rd), 7342 (v2i64 (int_aarch64_neon_sqdmull 7343 (extract_high_v4i32 V128:$Rn), 7344 (extract_high_v4i32 7345 (AArch64duplane32 (v4i32 V128:$Rm), 7346 VectorIndexS:$idx))))))]> { 7347 bits<2> idx; 7348 let Inst{11} = idx{1}; 7349 let Inst{21} = idx{0}; 7350 } 7351 7352 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 7353 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 7354 asm, ".h", "", "", ".h", []> { 7355 bits<3> idx; 7356 let Inst{11} = idx{2}; 7357 let Inst{21} = idx{1}; 7358 let Inst{20} = idx{0}; 7359 } 7360 7361 7362 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 7363 FPR64Op, FPR32Op, V128, VectorIndexS, 7364 asm, ".s", "", "", ".s", 7365 [(set (i64 FPR64Op:$dst), 7366 (Accum (i64 FPR64Op:$Rd), 7367 (i64 (int_aarch64_neon_sqdmulls_scalar 7368 (i32 FPR32Op:$Rn), 7369 (i32 (vector_extract (v4i32 V128:$Rm), 7370 VectorIndexS:$idx))))))]> { 7371 7372 bits<2> idx; 7373 let Inst{11} = idx{1}; 7374 let Inst{21} = idx{0}; 7375 } 7376} 7377 7378multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 7379 SDPatternOperator OpNode> { 7380 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7381 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7382 V128, V64, 7383 V128_lo, VectorIndexH, 7384 asm, ".4s", ".4s", ".4h", ".h", 7385 [(set (v4i32 V128:$Rd), 7386 (OpNode (v4i16 V64:$Rn), 7387 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7388 bits<3> idx; 7389 let Inst{11} = idx{2}; 7390 let Inst{21} = idx{1}; 7391 let Inst{20} = idx{0}; 7392 } 7393 7394 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7395 V128, V128, 7396 V128_lo, VectorIndexH, 7397 asm#"2", ".4s", ".4s", ".8h", ".h", 7398 [(set (v4i32 V128:$Rd), 7399 (OpNode (extract_high_v8i16 V128:$Rn), 7400 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7401 VectorIndexH:$idx))))]> { 7402 7403 bits<3> idx; 7404 let Inst{11} = idx{2}; 7405 let Inst{21} = idx{1}; 7406 let Inst{20} = idx{0}; 7407 } 7408 7409 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7410 V128, V64, 7411 V128, VectorIndexS, 7412 asm, ".2d", ".2d", ".2s", ".s", 7413 [(set (v2i64 V128:$Rd), 7414 (OpNode (v2i32 V64:$Rn), 7415 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7416 bits<2> idx; 7417 let Inst{11} = idx{1}; 7418 let Inst{21} = idx{0}; 7419 } 7420 7421 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7422 V128, V128, 7423 V128, VectorIndexS, 7424 asm#"2", ".2d", ".2d", ".4s", ".s", 7425 [(set (v2i64 V128:$Rd), 7426 (OpNode (extract_high_v4i32 V128:$Rn), 7427 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 7428 VectorIndexS:$idx))))]> { 7429 bits<2> idx; 7430 let Inst{11} = idx{1}; 7431 let Inst{21} = idx{0}; 7432 } 7433 } 7434} 7435 7436multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 7437 SDPatternOperator OpNode> { 7438 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7439 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 7440 V128, V64, 7441 V128_lo, VectorIndexH, 7442 asm, ".4s", ".4s", ".4h", ".h", 7443 [(set (v4i32 V128:$dst), 7444 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 7445 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7446 bits<3> idx; 7447 let Inst{11} = idx{2}; 7448 let Inst{21} = idx{1}; 7449 let Inst{20} = idx{0}; 7450 } 7451 7452 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7453 V128, V128, 7454 V128_lo, VectorIndexH, 7455 asm#"2", ".4s", ".4s", ".8h", ".h", 7456 [(set (v4i32 V128:$dst), 7457 (OpNode (v4i32 V128:$Rd), 7458 (extract_high_v8i16 V128:$Rn), 7459 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7460 VectorIndexH:$idx))))]> { 7461 bits<3> idx; 7462 let Inst{11} = idx{2}; 7463 let Inst{21} = idx{1}; 7464 let Inst{20} = idx{0}; 7465 } 7466 7467 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7468 V128, V64, 7469 V128, VectorIndexS, 7470 asm, ".2d", ".2d", ".2s", ".s", 7471 [(set (v2i64 V128:$dst), 7472 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 7473 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7474 bits<2> idx; 7475 let Inst{11} = idx{1}; 7476 let Inst{21} = idx{0}; 7477 } 7478 7479 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7480 V128, V128, 7481 V128, VectorIndexS, 7482 asm#"2", ".2d", ".2d", ".4s", ".s", 7483 [(set (v2i64 V128:$dst), 7484 (OpNode (v2i64 V128:$Rd), 7485 (extract_high_v4i32 V128:$Rn), 7486 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 7487 VectorIndexS:$idx))))]> { 7488 bits<2> idx; 7489 let Inst{11} = idx{1}; 7490 let Inst{21} = idx{0}; 7491 } 7492 } 7493} 7494 7495//---------------------------------------------------------------------------- 7496// AdvSIMD scalar shift by immediate 7497//---------------------------------------------------------------------------- 7498 7499let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7500class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 7501 RegisterClass regtype1, RegisterClass regtype2, 7502 Operand immtype, string asm, list<dag> pattern> 7503 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 7504 asm, "\t$Rd, $Rn, $imm", "", pattern>, 7505 Sched<[WriteV]> { 7506 bits<5> Rd; 7507 bits<5> Rn; 7508 bits<7> imm; 7509 let Inst{31-30} = 0b01; 7510 let Inst{29} = U; 7511 let Inst{28-23} = 0b111110; 7512 let Inst{22-16} = fixed_imm; 7513 let Inst{15-11} = opc; 7514 let Inst{10} = 1; 7515 let Inst{9-5} = Rn; 7516 let Inst{4-0} = Rd; 7517} 7518 7519let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7520class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 7521 RegisterClass regtype1, RegisterClass regtype2, 7522 Operand immtype, string asm, list<dag> pattern> 7523 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 7524 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 7525 Sched<[WriteV]> { 7526 bits<5> Rd; 7527 bits<5> Rn; 7528 bits<7> imm; 7529 let Inst{31-30} = 0b01; 7530 let Inst{29} = U; 7531 let Inst{28-23} = 0b111110; 7532 let Inst{22-16} = fixed_imm; 7533 let Inst{15-11} = opc; 7534 let Inst{10} = 1; 7535 let Inst{9-5} = Rn; 7536 let Inst{4-0} = Rd; 7537} 7538 7539 7540multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 7541 let Predicates = [HasNEON, HasFullFP16] in { 7542 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7543 FPR16, FPR16, vecshiftR16, asm, []> { 7544 let Inst{19-16} = imm{3-0}; 7545 } 7546 } // Predicates = [HasNEON, HasFullFP16] 7547 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7548 FPR32, FPR32, vecshiftR32, asm, []> { 7549 let Inst{20-16} = imm{4-0}; 7550 } 7551 7552 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7553 FPR64, FPR64, vecshiftR64, asm, []> { 7554 let Inst{21-16} = imm{5-0}; 7555 } 7556} 7557 7558multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 7559 SDPatternOperator OpNode> { 7560 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7561 FPR64, FPR64, vecshiftR64, asm, 7562 [(set (i64 FPR64:$Rd), 7563 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 7564 let Inst{21-16} = imm{5-0}; 7565 } 7566 7567 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 7568 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 7569} 7570 7571multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 7572 SDPatternOperator OpNode = null_frag> { 7573 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 7574 FPR64, FPR64, vecshiftR64, asm, 7575 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 7576 (i32 vecshiftR64:$imm)))]> { 7577 let Inst{21-16} = imm{5-0}; 7578 } 7579 7580 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 7581 (i32 vecshiftR64:$imm))), 7582 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 7583 vecshiftR64:$imm)>; 7584} 7585 7586multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 7587 SDPatternOperator OpNode> { 7588 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7589 FPR64, FPR64, vecshiftL64, asm, 7590 [(set (v1i64 FPR64:$Rd), 7591 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 7592 let Inst{21-16} = imm{5-0}; 7593 } 7594} 7595 7596let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7597multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 7598 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 7599 FPR64, FPR64, vecshiftL64, asm, []> { 7600 let Inst{21-16} = imm{5-0}; 7601 } 7602} 7603 7604let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7605multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 7606 SDPatternOperator OpNode = null_frag> { 7607 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7608 FPR8, FPR16, vecshiftR8, asm, []> { 7609 let Inst{18-16} = imm{2-0}; 7610 } 7611 7612 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7613 FPR16, FPR32, vecshiftR16, asm, []> { 7614 let Inst{19-16} = imm{3-0}; 7615 } 7616 7617 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7618 FPR32, FPR64, vecshiftR32, asm, 7619 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 7620 let Inst{20-16} = imm{4-0}; 7621 } 7622} 7623 7624multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 7625 SDPatternOperator OpNode> { 7626 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7627 FPR8, FPR8, vecshiftL8, asm, []> { 7628 let Inst{18-16} = imm{2-0}; 7629 } 7630 7631 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7632 FPR16, FPR16, vecshiftL16, asm, []> { 7633 let Inst{19-16} = imm{3-0}; 7634 } 7635 7636 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7637 FPR32, FPR32, vecshiftL32, asm, 7638 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 7639 let Inst{20-16} = imm{4-0}; 7640 } 7641 7642 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7643 FPR64, FPR64, vecshiftL64, asm, 7644 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 7645 let Inst{21-16} = imm{5-0}; 7646 } 7647 7648 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 7649 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 7650} 7651 7652multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 7653 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7654 FPR8, FPR8, vecshiftR8, asm, []> { 7655 let Inst{18-16} = imm{2-0}; 7656 } 7657 7658 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7659 FPR16, FPR16, vecshiftR16, asm, []> { 7660 let Inst{19-16} = imm{3-0}; 7661 } 7662 7663 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7664 FPR32, FPR32, vecshiftR32, asm, []> { 7665 let Inst{20-16} = imm{4-0}; 7666 } 7667 7668 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7669 FPR64, FPR64, vecshiftR64, asm, []> { 7670 let Inst{21-16} = imm{5-0}; 7671 } 7672} 7673 7674//---------------------------------------------------------------------------- 7675// AdvSIMD vector x indexed element 7676//---------------------------------------------------------------------------- 7677 7678let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7679class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 7680 RegisterOperand dst_reg, RegisterOperand src_reg, 7681 Operand immtype, 7682 string asm, string dst_kind, string src_kind, 7683 list<dag> pattern> 7684 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 7685 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 7686 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 7687 Sched<[WriteV]> { 7688 bits<5> Rd; 7689 bits<5> Rn; 7690 let Inst{31} = 0; 7691 let Inst{30} = Q; 7692 let Inst{29} = U; 7693 let Inst{28-23} = 0b011110; 7694 let Inst{22-16} = fixed_imm; 7695 let Inst{15-11} = opc; 7696 let Inst{10} = 1; 7697 let Inst{9-5} = Rn; 7698 let Inst{4-0} = Rd; 7699} 7700 7701let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7702class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 7703 RegisterOperand vectype1, RegisterOperand vectype2, 7704 Operand immtype, 7705 string asm, string dst_kind, string src_kind, 7706 list<dag> pattern> 7707 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 7708 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 7709 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 7710 Sched<[WriteV]> { 7711 bits<5> Rd; 7712 bits<5> Rn; 7713 let Inst{31} = 0; 7714 let Inst{30} = Q; 7715 let Inst{29} = U; 7716 let Inst{28-23} = 0b011110; 7717 let Inst{22-16} = fixed_imm; 7718 let Inst{15-11} = opc; 7719 let Inst{10} = 1; 7720 let Inst{9-5} = Rn; 7721 let Inst{4-0} = Rd; 7722} 7723 7724multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 7725 Intrinsic OpNode> { 7726 let Predicates = [HasNEON, HasFullFP16] in { 7727 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7728 V64, V64, vecshiftR16, 7729 asm, ".4h", ".4h", 7730 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 7731 bits<4> imm; 7732 let Inst{19-16} = imm; 7733 } 7734 7735 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7736 V128, V128, vecshiftR16, 7737 asm, ".8h", ".8h", 7738 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 7739 bits<4> imm; 7740 let Inst{19-16} = imm; 7741 } 7742 } // Predicates = [HasNEON, HasFullFP16] 7743 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7744 V64, V64, vecshiftR32, 7745 asm, ".2s", ".2s", 7746 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 7747 bits<5> imm; 7748 let Inst{20-16} = imm; 7749 } 7750 7751 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7752 V128, V128, vecshiftR32, 7753 asm, ".4s", ".4s", 7754 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 7755 bits<5> imm; 7756 let Inst{20-16} = imm; 7757 } 7758 7759 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7760 V128, V128, vecshiftR64, 7761 asm, ".2d", ".2d", 7762 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 7763 bits<6> imm; 7764 let Inst{21-16} = imm; 7765 } 7766} 7767 7768multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 7769 Intrinsic OpNode> { 7770 let Predicates = [HasNEON, HasFullFP16] in { 7771 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7772 V64, V64, vecshiftR16, 7773 asm, ".4h", ".4h", 7774 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 7775 bits<4> imm; 7776 let Inst{19-16} = imm; 7777 } 7778 7779 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7780 V128, V128, vecshiftR16, 7781 asm, ".8h", ".8h", 7782 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 7783 bits<4> imm; 7784 let Inst{19-16} = imm; 7785 } 7786 } // Predicates = [HasNEON, HasFullFP16] 7787 7788 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7789 V64, V64, vecshiftR32, 7790 asm, ".2s", ".2s", 7791 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 7792 bits<5> imm; 7793 let Inst{20-16} = imm; 7794 } 7795 7796 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7797 V128, V128, vecshiftR32, 7798 asm, ".4s", ".4s", 7799 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 7800 bits<5> imm; 7801 let Inst{20-16} = imm; 7802 } 7803 7804 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7805 V128, V128, vecshiftR64, 7806 asm, ".2d", ".2d", 7807 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 7808 bits<6> imm; 7809 let Inst{21-16} = imm; 7810 } 7811} 7812 7813multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 7814 SDPatternOperator OpNode> { 7815 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7816 V64, V128, vecshiftR16Narrow, 7817 asm, ".8b", ".8h", 7818 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 7819 bits<3> imm; 7820 let Inst{18-16} = imm; 7821 } 7822 7823 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 7824 V128, V128, vecshiftR16Narrow, 7825 asm#"2", ".16b", ".8h", []> { 7826 bits<3> imm; 7827 let Inst{18-16} = imm; 7828 let hasSideEffects = 0; 7829 } 7830 7831 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7832 V64, V128, vecshiftR32Narrow, 7833 asm, ".4h", ".4s", 7834 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 7835 bits<4> imm; 7836 let Inst{19-16} = imm; 7837 } 7838 7839 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 7840 V128, V128, vecshiftR32Narrow, 7841 asm#"2", ".8h", ".4s", []> { 7842 bits<4> imm; 7843 let Inst{19-16} = imm; 7844 let hasSideEffects = 0; 7845 } 7846 7847 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7848 V64, V128, vecshiftR64Narrow, 7849 asm, ".2s", ".2d", 7850 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 7851 bits<5> imm; 7852 let Inst{20-16} = imm; 7853 } 7854 7855 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 7856 V128, V128, vecshiftR64Narrow, 7857 asm#"2", ".4s", ".2d", []> { 7858 bits<5> imm; 7859 let Inst{20-16} = imm; 7860 let hasSideEffects = 0; 7861 } 7862 7863 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 7864 // themselves, so put them here instead. 7865 7866 // Patterns involving what's effectively an insert high and a normal 7867 // intrinsic, represented by CONCAT_VECTORS. 7868 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 7869 vecshiftR16Narrow:$imm)), 7870 (!cast<Instruction>(NAME # "v16i8_shift") 7871 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7872 V128:$Rn, vecshiftR16Narrow:$imm)>; 7873 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 7874 vecshiftR32Narrow:$imm)), 7875 (!cast<Instruction>(NAME # "v8i16_shift") 7876 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7877 V128:$Rn, vecshiftR32Narrow:$imm)>; 7878 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 7879 vecshiftR64Narrow:$imm)), 7880 (!cast<Instruction>(NAME # "v4i32_shift") 7881 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7882 V128:$Rn, vecshiftR64Narrow:$imm)>; 7883} 7884 7885multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 7886 SDPatternOperator OpNode> { 7887 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7888 V64, V64, vecshiftL8, 7889 asm, ".8b", ".8b", 7890 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 7891 (i32 vecshiftL8:$imm)))]> { 7892 bits<3> imm; 7893 let Inst{18-16} = imm; 7894 } 7895 7896 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7897 V128, V128, vecshiftL8, 7898 asm, ".16b", ".16b", 7899 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 7900 (i32 vecshiftL8:$imm)))]> { 7901 bits<3> imm; 7902 let Inst{18-16} = imm; 7903 } 7904 7905 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7906 V64, V64, vecshiftL16, 7907 asm, ".4h", ".4h", 7908 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 7909 (i32 vecshiftL16:$imm)))]> { 7910 bits<4> imm; 7911 let Inst{19-16} = imm; 7912 } 7913 7914 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7915 V128, V128, vecshiftL16, 7916 asm, ".8h", ".8h", 7917 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7918 (i32 vecshiftL16:$imm)))]> { 7919 bits<4> imm; 7920 let Inst{19-16} = imm; 7921 } 7922 7923 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7924 V64, V64, vecshiftL32, 7925 asm, ".2s", ".2s", 7926 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 7927 (i32 vecshiftL32:$imm)))]> { 7928 bits<5> imm; 7929 let Inst{20-16} = imm; 7930 } 7931 7932 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7933 V128, V128, vecshiftL32, 7934 asm, ".4s", ".4s", 7935 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7936 (i32 vecshiftL32:$imm)))]> { 7937 bits<5> imm; 7938 let Inst{20-16} = imm; 7939 } 7940 7941 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7942 V128, V128, vecshiftL64, 7943 asm, ".2d", ".2d", 7944 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7945 (i32 vecshiftL64:$imm)))]> { 7946 bits<6> imm; 7947 let Inst{21-16} = imm; 7948 } 7949} 7950 7951multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 7952 SDPatternOperator OpNode> { 7953 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7954 V64, V64, vecshiftR8, 7955 asm, ".8b", ".8b", 7956 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 7957 (i32 vecshiftR8:$imm)))]> { 7958 bits<3> imm; 7959 let Inst{18-16} = imm; 7960 } 7961 7962 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7963 V128, V128, vecshiftR8, 7964 asm, ".16b", ".16b", 7965 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 7966 (i32 vecshiftR8:$imm)))]> { 7967 bits<3> imm; 7968 let Inst{18-16} = imm; 7969 } 7970 7971 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7972 V64, V64, vecshiftR16, 7973 asm, ".4h", ".4h", 7974 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 7975 (i32 vecshiftR16:$imm)))]> { 7976 bits<4> imm; 7977 let Inst{19-16} = imm; 7978 } 7979 7980 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7981 V128, V128, vecshiftR16, 7982 asm, ".8h", ".8h", 7983 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7984 (i32 vecshiftR16:$imm)))]> { 7985 bits<4> imm; 7986 let Inst{19-16} = imm; 7987 } 7988 7989 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7990 V64, V64, vecshiftR32, 7991 asm, ".2s", ".2s", 7992 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 7993 (i32 vecshiftR32:$imm)))]> { 7994 bits<5> imm; 7995 let Inst{20-16} = imm; 7996 } 7997 7998 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7999 V128, V128, vecshiftR32, 8000 asm, ".4s", ".4s", 8001 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 8002 (i32 vecshiftR32:$imm)))]> { 8003 bits<5> imm; 8004 let Inst{20-16} = imm; 8005 } 8006 8007 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8008 V128, V128, vecshiftR64, 8009 asm, ".2d", ".2d", 8010 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 8011 (i32 vecshiftR64:$imm)))]> { 8012 bits<6> imm; 8013 let Inst{21-16} = imm; 8014 } 8015} 8016 8017let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8018multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 8019 SDPatternOperator OpNode = null_frag> { 8020 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8021 V64, V64, vecshiftR8, asm, ".8b", ".8b", 8022 [(set (v8i8 V64:$dst), 8023 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8024 (i32 vecshiftR8:$imm)))]> { 8025 bits<3> imm; 8026 let Inst{18-16} = imm; 8027 } 8028 8029 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8030 V128, V128, vecshiftR8, asm, ".16b", ".16b", 8031 [(set (v16i8 V128:$dst), 8032 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8033 (i32 vecshiftR8:$imm)))]> { 8034 bits<3> imm; 8035 let Inst{18-16} = imm; 8036 } 8037 8038 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8039 V64, V64, vecshiftR16, asm, ".4h", ".4h", 8040 [(set (v4i16 V64:$dst), 8041 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8042 (i32 vecshiftR16:$imm)))]> { 8043 bits<4> imm; 8044 let Inst{19-16} = imm; 8045 } 8046 8047 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8048 V128, V128, vecshiftR16, asm, ".8h", ".8h", 8049 [(set (v8i16 V128:$dst), 8050 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8051 (i32 vecshiftR16:$imm)))]> { 8052 bits<4> imm; 8053 let Inst{19-16} = imm; 8054 } 8055 8056 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8057 V64, V64, vecshiftR32, asm, ".2s", ".2s", 8058 [(set (v2i32 V64:$dst), 8059 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8060 (i32 vecshiftR32:$imm)))]> { 8061 bits<5> imm; 8062 let Inst{20-16} = imm; 8063 } 8064 8065 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8066 V128, V128, vecshiftR32, asm, ".4s", ".4s", 8067 [(set (v4i32 V128:$dst), 8068 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8069 (i32 vecshiftR32:$imm)))]> { 8070 bits<5> imm; 8071 let Inst{20-16} = imm; 8072 } 8073 8074 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8075 V128, V128, vecshiftR64, 8076 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 8077 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8078 (i32 vecshiftR64:$imm)))]> { 8079 bits<6> imm; 8080 let Inst{21-16} = imm; 8081 } 8082} 8083 8084multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 8085 SDPatternOperator OpNode = null_frag> { 8086 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8087 V64, V64, vecshiftL8, 8088 asm, ".8b", ".8b", 8089 [(set (v8i8 V64:$dst), 8090 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8091 (i32 vecshiftL8:$imm)))]> { 8092 bits<3> imm; 8093 let Inst{18-16} = imm; 8094 } 8095 8096 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8097 V128, V128, vecshiftL8, 8098 asm, ".16b", ".16b", 8099 [(set (v16i8 V128:$dst), 8100 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8101 (i32 vecshiftL8:$imm)))]> { 8102 bits<3> imm; 8103 let Inst{18-16} = imm; 8104 } 8105 8106 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8107 V64, V64, vecshiftL16, 8108 asm, ".4h", ".4h", 8109 [(set (v4i16 V64:$dst), 8110 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8111 (i32 vecshiftL16:$imm)))]> { 8112 bits<4> imm; 8113 let Inst{19-16} = imm; 8114 } 8115 8116 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8117 V128, V128, vecshiftL16, 8118 asm, ".8h", ".8h", 8119 [(set (v8i16 V128:$dst), 8120 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8121 (i32 vecshiftL16:$imm)))]> { 8122 bits<4> imm; 8123 let Inst{19-16} = imm; 8124 } 8125 8126 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8127 V64, V64, vecshiftL32, 8128 asm, ".2s", ".2s", 8129 [(set (v2i32 V64:$dst), 8130 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8131 (i32 vecshiftL32:$imm)))]> { 8132 bits<5> imm; 8133 let Inst{20-16} = imm; 8134 } 8135 8136 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8137 V128, V128, vecshiftL32, 8138 asm, ".4s", ".4s", 8139 [(set (v4i32 V128:$dst), 8140 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8141 (i32 vecshiftL32:$imm)))]> { 8142 bits<5> imm; 8143 let Inst{20-16} = imm; 8144 } 8145 8146 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8147 V128, V128, vecshiftL64, 8148 asm, ".2d", ".2d", 8149 [(set (v2i64 V128:$dst), 8150 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8151 (i32 vecshiftL64:$imm)))]> { 8152 bits<6> imm; 8153 let Inst{21-16} = imm; 8154 } 8155} 8156 8157multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 8158 SDPatternOperator OpNode> { 8159 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8160 V128, V64, vecshiftL8, asm, ".8h", ".8b", 8161 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 8162 bits<3> imm; 8163 let Inst{18-16} = imm; 8164 } 8165 8166 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8167 V128, V128, vecshiftL8, 8168 asm#"2", ".8h", ".16b", 8169 [(set (v8i16 V128:$Rd), 8170 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 8171 bits<3> imm; 8172 let Inst{18-16} = imm; 8173 } 8174 8175 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8176 V128, V64, vecshiftL16, asm, ".4s", ".4h", 8177 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 8178 bits<4> imm; 8179 let Inst{19-16} = imm; 8180 } 8181 8182 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8183 V128, V128, vecshiftL16, 8184 asm#"2", ".4s", ".8h", 8185 [(set (v4i32 V128:$Rd), 8186 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 8187 8188 bits<4> imm; 8189 let Inst{19-16} = imm; 8190 } 8191 8192 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8193 V128, V64, vecshiftL32, asm, ".2d", ".2s", 8194 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 8195 bits<5> imm; 8196 let Inst{20-16} = imm; 8197 } 8198 8199 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8200 V128, V128, vecshiftL32, 8201 asm#"2", ".2d", ".4s", 8202 [(set (v2i64 V128:$Rd), 8203 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 8204 bits<5> imm; 8205 let Inst{20-16} = imm; 8206 } 8207} 8208 8209 8210//--- 8211// Vector load/store 8212//--- 8213// SIMD ldX/stX no-index memory references don't allow the optional 8214// ", #0" constant and handle post-indexing explicitly, so we use 8215// a more specialized parse method for them. Otherwise, it's the same as 8216// the general GPR64sp handling. 8217 8218class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 8219 string asm, dag oops, dag iops, list<dag> pattern> 8220 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 8221 bits<5> Vt; 8222 bits<5> Rn; 8223 let Inst{31} = 0; 8224 let Inst{30} = Q; 8225 let Inst{29-23} = 0b0011000; 8226 let Inst{22} = L; 8227 let Inst{21-16} = 0b000000; 8228 let Inst{15-12} = opcode; 8229 let Inst{11-10} = size; 8230 let Inst{9-5} = Rn; 8231 let Inst{4-0} = Vt; 8232} 8233 8234class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 8235 string asm, dag oops, dag iops> 8236 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 8237 bits<5> Vt; 8238 bits<5> Rn; 8239 bits<5> Xm; 8240 let Inst{31} = 0; 8241 let Inst{30} = Q; 8242 let Inst{29-23} = 0b0011001; 8243 let Inst{22} = L; 8244 let Inst{21} = 0; 8245 let Inst{20-16} = Xm; 8246 let Inst{15-12} = opcode; 8247 let Inst{11-10} = size; 8248 let Inst{9-5} = Rn; 8249 let Inst{4-0} = Vt; 8250} 8251 8252// The immediate form of AdvSIMD post-indexed addressing is encoded with 8253// register post-index addressing from the zero register. 8254multiclass SIMDLdStAliases<string asm, string layout, string Count, 8255 int Offset, int Size> { 8256 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 8257 // "ld1\t$Vt, [$Rn], #16" 8258 // may get mapped to 8259 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 8260 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 8261 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 8262 GPR64sp:$Rn, 8263 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8264 XZR), 1>; 8265 8266 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 8267 // "ld1.8b\t$Vt, [$Rn], #16" 8268 // may get mapped to 8269 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 8270 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 8271 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 8272 GPR64sp:$Rn, 8273 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8274 XZR), 0>; 8275 8276 // E.g. "ld1.8b { v0, v1 }, [x1]" 8277 // "ld1\t$Vt, [$Rn]" 8278 // may get mapped to 8279 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 8280 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 8281 (!cast<Instruction>(NAME # Count # "v" # layout) 8282 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8283 GPR64sp:$Rn), 0>; 8284 8285 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 8286 // "ld1\t$Vt, [$Rn], $Xm" 8287 // may get mapped to 8288 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 8289 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 8290 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 8291 GPR64sp:$Rn, 8292 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8293 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 8294} 8295 8296multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128, 8297 int Offset64, bits<4> opcode> { 8298 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 8299 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 8300 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 8301 (ins GPR64sp:$Rn), []>; 8302 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 8303 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 8304 (ins GPR64sp:$Rn), []>; 8305 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 8306 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 8307 (ins GPR64sp:$Rn), []>; 8308 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 8309 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 8310 (ins GPR64sp:$Rn), []>; 8311 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 8312 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 8313 (ins GPR64sp:$Rn), []>; 8314 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 8315 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 8316 (ins GPR64sp:$Rn), []>; 8317 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 8318 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 8319 (ins GPR64sp:$Rn), []>; 8320 8321 8322 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 8323 (outs GPR64sp:$wback, 8324 !cast<RegisterOperand>(veclist # "16b"):$Vt), 8325 (ins GPR64sp:$Rn, 8326 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8327 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 8328 (outs GPR64sp:$wback, 8329 !cast<RegisterOperand>(veclist # "8h"):$Vt), 8330 (ins GPR64sp:$Rn, 8331 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8332 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 8333 (outs GPR64sp:$wback, 8334 !cast<RegisterOperand>(veclist # "4s"):$Vt), 8335 (ins GPR64sp:$Rn, 8336 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8337 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 8338 (outs GPR64sp:$wback, 8339 !cast<RegisterOperand>(veclist # "2d"):$Vt), 8340 (ins GPR64sp:$Rn, 8341 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8342 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 8343 (outs GPR64sp:$wback, 8344 !cast<RegisterOperand>(veclist # "8b"):$Vt), 8345 (ins GPR64sp:$Rn, 8346 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8347 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 8348 (outs GPR64sp:$wback, 8349 !cast<RegisterOperand>(veclist # "4h"):$Vt), 8350 (ins GPR64sp:$Rn, 8351 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8352 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 8353 (outs GPR64sp:$wback, 8354 !cast<RegisterOperand>(veclist # "2s"):$Vt), 8355 (ins GPR64sp:$Rn, 8356 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8357 } 8358 8359 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>; 8360 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>; 8361 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>; 8362 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>; 8363 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>; 8364 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>; 8365 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>; 8366} 8367 8368// Only ld1/st1 has a v1d version. 8369multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128, 8370 int Offset64, bits<4> opcode> { 8371 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 8372 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 8373 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 8374 GPR64sp:$Rn), []>; 8375 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 8376 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 8377 GPR64sp:$Rn), []>; 8378 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 8379 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 8380 GPR64sp:$Rn), []>; 8381 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 8382 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 8383 GPR64sp:$Rn), []>; 8384 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 8385 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 8386 GPR64sp:$Rn), []>; 8387 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 8388 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 8389 GPR64sp:$Rn), []>; 8390 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 8391 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 8392 GPR64sp:$Rn), []>; 8393 8394 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 8395 (outs GPR64sp:$wback), 8396 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 8397 GPR64sp:$Rn, 8398 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8399 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 8400 (outs GPR64sp:$wback), 8401 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 8402 GPR64sp:$Rn, 8403 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8404 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 8405 (outs GPR64sp:$wback), 8406 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 8407 GPR64sp:$Rn, 8408 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8409 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 8410 (outs GPR64sp:$wback), 8411 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 8412 GPR64sp:$Rn, 8413 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8414 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 8415 (outs GPR64sp:$wback), 8416 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 8417 GPR64sp:$Rn, 8418 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8419 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 8420 (outs GPR64sp:$wback), 8421 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 8422 GPR64sp:$Rn, 8423 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8424 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 8425 (outs GPR64sp:$wback), 8426 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 8427 GPR64sp:$Rn, 8428 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8429 } 8430 8431 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>; 8432 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>; 8433 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>; 8434 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>; 8435 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>; 8436 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>; 8437 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>; 8438} 8439 8440multiclass BaseSIMDLd1<string Count, string asm, string veclist, 8441 int Offset128, int Offset64, bits<4> opcode> 8442 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> { 8443 8444 // LD1 instructions have extra "1d" variants. 8445 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 8446 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 8447 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 8448 (ins GPR64sp:$Rn), []>; 8449 8450 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 8451 (outs GPR64sp:$wback, 8452 !cast<RegisterOperand>(veclist # "1d"):$Vt), 8453 (ins GPR64sp:$Rn, 8454 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8455 } 8456 8457 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>; 8458} 8459 8460multiclass BaseSIMDSt1<string Count, string asm, string veclist, 8461 int Offset128, int Offset64, bits<4> opcode> 8462 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> { 8463 8464 // ST1 instructions have extra "1d" variants. 8465 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 8466 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 8467 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 8468 GPR64sp:$Rn), []>; 8469 8470 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 8471 (outs GPR64sp:$wback), 8472 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 8473 GPR64sp:$Rn, 8474 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8475 } 8476 8477 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>; 8478} 8479 8480multiclass SIMDLd1Multiple<string asm> { 8481 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>; 8482 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; 8483 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>; 8484 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>; 8485} 8486 8487multiclass SIMDSt1Multiple<string asm> { 8488 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>; 8489 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; 8490 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>; 8491 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>; 8492} 8493 8494multiclass SIMDLd2Multiple<string asm> { 8495 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; 8496} 8497 8498multiclass SIMDSt2Multiple<string asm> { 8499 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; 8500} 8501 8502multiclass SIMDLd3Multiple<string asm> { 8503 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>; 8504} 8505 8506multiclass SIMDSt3Multiple<string asm> { 8507 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>; 8508} 8509 8510multiclass SIMDLd4Multiple<string asm> { 8511 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>; 8512} 8513 8514multiclass SIMDSt4Multiple<string asm> { 8515 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>; 8516} 8517 8518//--- 8519// AdvSIMD Load/store single-element 8520//--- 8521 8522class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 8523 string asm, string operands, string cst, 8524 dag oops, dag iops, list<dag> pattern> 8525 : I<oops, iops, asm, operands, cst, pattern> { 8526 bits<5> Vt; 8527 bits<5> Rn; 8528 let Inst{31} = 0; 8529 let Inst{29-24} = 0b001101; 8530 let Inst{22} = L; 8531 let Inst{21} = R; 8532 let Inst{15-13} = opcode; 8533 let Inst{9-5} = Rn; 8534 let Inst{4-0} = Vt; 8535} 8536 8537class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 8538 string asm, string operands, string cst, 8539 dag oops, dag iops, list<dag> pattern> 8540 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 8541 bits<5> Vt; 8542 bits<5> Rn; 8543 let Inst{31} = 0; 8544 let Inst{29-24} = 0b001101; 8545 let Inst{22} = L; 8546 let Inst{21} = R; 8547 let Inst{15-13} = opcode; 8548 let Inst{9-5} = Rn; 8549 let Inst{4-0} = Vt; 8550} 8551 8552 8553let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8554class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 8555 Operand listtype> 8556 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 8557 (outs listtype:$Vt), (ins GPR64sp:$Rn), 8558 []> { 8559 let Inst{30} = Q; 8560 let Inst{23} = 0; 8561 let Inst{20-16} = 0b00000; 8562 let Inst{12} = S; 8563 let Inst{11-10} = size; 8564} 8565let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8566class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 8567 string asm, Operand listtype, Operand GPR64pi> 8568 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 8569 "$Rn = $wback", 8570 (outs GPR64sp:$wback, listtype:$Vt), 8571 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 8572 bits<5> Xm; 8573 let Inst{30} = Q; 8574 let Inst{23} = 1; 8575 let Inst{20-16} = Xm; 8576 let Inst{12} = S; 8577 let Inst{11-10} = size; 8578} 8579 8580multiclass SIMDLdrAliases<string asm, string layout, string Count, 8581 int Offset, int Size> { 8582 // E.g. "ld1r { v0.8b }, [x1], #1" 8583 // "ld1r.8b\t$Vt, [$Rn], #1" 8584 // may get mapped to 8585 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 8586 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 8587 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8588 GPR64sp:$Rn, 8589 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8590 XZR), 1>; 8591 8592 // E.g. "ld1r.8b { v0 }, [x1], #1" 8593 // "ld1r.8b\t$Vt, [$Rn], #1" 8594 // may get mapped to 8595 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 8596 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 8597 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8598 GPR64sp:$Rn, 8599 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8600 XZR), 0>; 8601 8602 // E.g. "ld1r.8b { v0 }, [x1]" 8603 // "ld1r.8b\t$Vt, [$Rn]" 8604 // may get mapped to 8605 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 8606 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 8607 (!cast<Instruction>(NAME # "v" # layout) 8608 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8609 GPR64sp:$Rn), 0>; 8610 8611 // E.g. "ld1r.8b { v0 }, [x1], x2" 8612 // "ld1r.8b\t$Vt, [$Rn], $Xm" 8613 // may get mapped to 8614 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 8615 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 8616 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8617 GPR64sp:$Rn, 8618 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8619 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 8620} 8621 8622multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 8623 int Offset1, int Offset2, int Offset4, int Offset8> { 8624 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 8625 !cast<Operand>("VecList" # Count # "8b")>; 8626 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 8627 !cast<Operand>("VecList" # Count #"16b")>; 8628 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 8629 !cast<Operand>("VecList" # Count #"4h")>; 8630 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 8631 !cast<Operand>("VecList" # Count #"8h")>; 8632 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 8633 !cast<Operand>("VecList" # Count #"2s")>; 8634 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 8635 !cast<Operand>("VecList" # Count #"4s")>; 8636 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 8637 !cast<Operand>("VecList" # Count #"1d")>; 8638 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 8639 !cast<Operand>("VecList" # Count #"2d")>; 8640 8641 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 8642 !cast<Operand>("VecList" # Count # "8b"), 8643 !cast<Operand>("GPR64pi" # Offset1)>; 8644 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 8645 !cast<Operand>("VecList" # Count # "16b"), 8646 !cast<Operand>("GPR64pi" # Offset1)>; 8647 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 8648 !cast<Operand>("VecList" # Count # "4h"), 8649 !cast<Operand>("GPR64pi" # Offset2)>; 8650 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 8651 !cast<Operand>("VecList" # Count # "8h"), 8652 !cast<Operand>("GPR64pi" # Offset2)>; 8653 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 8654 !cast<Operand>("VecList" # Count # "2s"), 8655 !cast<Operand>("GPR64pi" # Offset4)>; 8656 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 8657 !cast<Operand>("VecList" # Count # "4s"), 8658 !cast<Operand>("GPR64pi" # Offset4)>; 8659 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 8660 !cast<Operand>("VecList" # Count # "1d"), 8661 !cast<Operand>("GPR64pi" # Offset8)>; 8662 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 8663 !cast<Operand>("VecList" # Count # "2d"), 8664 !cast<Operand>("GPR64pi" # Offset8)>; 8665 8666 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>; 8667 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>; 8668 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>; 8669 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>; 8670 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>; 8671 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>; 8672 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>; 8673 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>; 8674} 8675 8676class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 8677 dag oops, dag iops, list<dag> pattern> 8678 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8679 pattern> { 8680 // idx encoded in Q:S:size fields. 8681 bits<4> idx; 8682 let Inst{30} = idx{3}; 8683 let Inst{23} = 0; 8684 let Inst{20-16} = 0b00000; 8685 let Inst{12} = idx{2}; 8686 let Inst{11-10} = idx{1-0}; 8687} 8688class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 8689 dag oops, dag iops, list<dag> pattern> 8690 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8691 oops, iops, pattern> { 8692 // idx encoded in Q:S:size fields. 8693 bits<4> idx; 8694 let Inst{30} = idx{3}; 8695 let Inst{23} = 0; 8696 let Inst{20-16} = 0b00000; 8697 let Inst{12} = idx{2}; 8698 let Inst{11-10} = idx{1-0}; 8699} 8700class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 8701 dag oops, dag iops> 8702 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8703 "$Rn = $wback", oops, iops, []> { 8704 // idx encoded in Q:S:size fields. 8705 bits<4> idx; 8706 bits<5> Xm; 8707 let Inst{30} = idx{3}; 8708 let Inst{23} = 1; 8709 let Inst{20-16} = Xm; 8710 let Inst{12} = idx{2}; 8711 let Inst{11-10} = idx{1-0}; 8712} 8713class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 8714 dag oops, dag iops> 8715 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8716 "$Rn = $wback", oops, iops, []> { 8717 // idx encoded in Q:S:size fields. 8718 bits<4> idx; 8719 bits<5> Xm; 8720 let Inst{30} = idx{3}; 8721 let Inst{23} = 1; 8722 let Inst{20-16} = Xm; 8723 let Inst{12} = idx{2}; 8724 let Inst{11-10} = idx{1-0}; 8725} 8726 8727class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 8728 dag oops, dag iops, list<dag> pattern> 8729 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8730 pattern> { 8731 // idx encoded in Q:S:size<1> fields. 8732 bits<3> idx; 8733 let Inst{30} = idx{2}; 8734 let Inst{23} = 0; 8735 let Inst{20-16} = 0b00000; 8736 let Inst{12} = idx{1}; 8737 let Inst{11} = idx{0}; 8738 let Inst{10} = size; 8739} 8740class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 8741 dag oops, dag iops, list<dag> pattern> 8742 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8743 oops, iops, pattern> { 8744 // idx encoded in Q:S:size<1> fields. 8745 bits<3> idx; 8746 let Inst{30} = idx{2}; 8747 let Inst{23} = 0; 8748 let Inst{20-16} = 0b00000; 8749 let Inst{12} = idx{1}; 8750 let Inst{11} = idx{0}; 8751 let Inst{10} = size; 8752} 8753 8754class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 8755 dag oops, dag iops> 8756 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8757 "$Rn = $wback", oops, iops, []> { 8758 // idx encoded in Q:S:size<1> fields. 8759 bits<3> idx; 8760 bits<5> Xm; 8761 let Inst{30} = idx{2}; 8762 let Inst{23} = 1; 8763 let Inst{20-16} = Xm; 8764 let Inst{12} = idx{1}; 8765 let Inst{11} = idx{0}; 8766 let Inst{10} = size; 8767} 8768class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 8769 dag oops, dag iops> 8770 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8771 "$Rn = $wback", oops, iops, []> { 8772 // idx encoded in Q:S:size<1> fields. 8773 bits<3> idx; 8774 bits<5> Xm; 8775 let Inst{30} = idx{2}; 8776 let Inst{23} = 1; 8777 let Inst{20-16} = Xm; 8778 let Inst{12} = idx{1}; 8779 let Inst{11} = idx{0}; 8780 let Inst{10} = size; 8781} 8782class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8783 dag oops, dag iops, list<dag> pattern> 8784 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8785 pattern> { 8786 // idx encoded in Q:S fields. 8787 bits<2> idx; 8788 let Inst{30} = idx{1}; 8789 let Inst{23} = 0; 8790 let Inst{20-16} = 0b00000; 8791 let Inst{12} = idx{0}; 8792 let Inst{11-10} = size; 8793} 8794class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8795 dag oops, dag iops, list<dag> pattern> 8796 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8797 oops, iops, pattern> { 8798 // idx encoded in Q:S fields. 8799 bits<2> idx; 8800 let Inst{30} = idx{1}; 8801 let Inst{23} = 0; 8802 let Inst{20-16} = 0b00000; 8803 let Inst{12} = idx{0}; 8804 let Inst{11-10} = size; 8805} 8806class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 8807 string asm, dag oops, dag iops> 8808 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8809 "$Rn = $wback", oops, iops, []> { 8810 // idx encoded in Q:S fields. 8811 bits<2> idx; 8812 bits<5> Xm; 8813 let Inst{30} = idx{1}; 8814 let Inst{23} = 1; 8815 let Inst{20-16} = Xm; 8816 let Inst{12} = idx{0}; 8817 let Inst{11-10} = size; 8818} 8819class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 8820 string asm, dag oops, dag iops> 8821 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8822 "$Rn = $wback", oops, iops, []> { 8823 // idx encoded in Q:S fields. 8824 bits<2> idx; 8825 bits<5> Xm; 8826 let Inst{30} = idx{1}; 8827 let Inst{23} = 1; 8828 let Inst{20-16} = Xm; 8829 let Inst{12} = idx{0}; 8830 let Inst{11-10} = size; 8831} 8832class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8833 dag oops, dag iops, list<dag> pattern> 8834 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8835 pattern> { 8836 // idx encoded in Q field. 8837 bits<1> idx; 8838 let Inst{30} = idx; 8839 let Inst{23} = 0; 8840 let Inst{20-16} = 0b00000; 8841 let Inst{12} = 0; 8842 let Inst{11-10} = size; 8843} 8844class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8845 dag oops, dag iops, list<dag> pattern> 8846 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8847 oops, iops, pattern> { 8848 // idx encoded in Q field. 8849 bits<1> idx; 8850 let Inst{30} = idx; 8851 let Inst{23} = 0; 8852 let Inst{20-16} = 0b00000; 8853 let Inst{12} = 0; 8854 let Inst{11-10} = size; 8855} 8856class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 8857 string asm, dag oops, dag iops> 8858 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8859 "$Rn = $wback", oops, iops, []> { 8860 // idx encoded in Q field. 8861 bits<1> idx; 8862 bits<5> Xm; 8863 let Inst{30} = idx; 8864 let Inst{23} = 1; 8865 let Inst{20-16} = Xm; 8866 let Inst{12} = 0; 8867 let Inst{11-10} = size; 8868} 8869class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 8870 string asm, dag oops, dag iops> 8871 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8872 "$Rn = $wback", oops, iops, []> { 8873 // idx encoded in Q field. 8874 bits<1> idx; 8875 bits<5> Xm; 8876 let Inst{30} = idx; 8877 let Inst{23} = 1; 8878 let Inst{20-16} = Xm; 8879 let Inst{12} = 0; 8880 let Inst{11-10} = size; 8881} 8882 8883let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8884multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 8885 RegisterOperand listtype, 8886 RegisterOperand GPR64pi> { 8887 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 8888 (outs listtype:$dst), 8889 (ins listtype:$Vt, VectorIndexB:$idx, 8890 GPR64sp:$Rn), []>; 8891 8892 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 8893 (outs GPR64sp:$wback, listtype:$dst), 8894 (ins listtype:$Vt, VectorIndexB:$idx, 8895 GPR64sp:$Rn, GPR64pi:$Xm)>; 8896} 8897let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8898multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 8899 RegisterOperand listtype, 8900 RegisterOperand GPR64pi> { 8901 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 8902 (outs listtype:$dst), 8903 (ins listtype:$Vt, VectorIndexH:$idx, 8904 GPR64sp:$Rn), []>; 8905 8906 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 8907 (outs GPR64sp:$wback, listtype:$dst), 8908 (ins listtype:$Vt, VectorIndexH:$idx, 8909 GPR64sp:$Rn, GPR64pi:$Xm)>; 8910} 8911let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8912multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 8913 RegisterOperand listtype, 8914 RegisterOperand GPR64pi> { 8915 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 8916 (outs listtype:$dst), 8917 (ins listtype:$Vt, VectorIndexS:$idx, 8918 GPR64sp:$Rn), []>; 8919 8920 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 8921 (outs GPR64sp:$wback, listtype:$dst), 8922 (ins listtype:$Vt, VectorIndexS:$idx, 8923 GPR64sp:$Rn, GPR64pi:$Xm)>; 8924} 8925let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8926multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 8927 RegisterOperand listtype, RegisterOperand GPR64pi> { 8928 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 8929 (outs listtype:$dst), 8930 (ins listtype:$Vt, VectorIndexD:$idx, 8931 GPR64sp:$Rn), []>; 8932 8933 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 8934 (outs GPR64sp:$wback, listtype:$dst), 8935 (ins listtype:$Vt, VectorIndexD:$idx, 8936 GPR64sp:$Rn, GPR64pi:$Xm)>; 8937} 8938let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8939multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 8940 RegisterOperand listtype, RegisterOperand GPR64pi> { 8941 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 8942 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 8943 GPR64sp:$Rn), []>; 8944 8945 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 8946 (outs GPR64sp:$wback), 8947 (ins listtype:$Vt, VectorIndexB:$idx, 8948 GPR64sp:$Rn, GPR64pi:$Xm)>; 8949} 8950let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8951multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 8952 RegisterOperand listtype, RegisterOperand GPR64pi> { 8953 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 8954 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 8955 GPR64sp:$Rn), []>; 8956 8957 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 8958 (outs GPR64sp:$wback), 8959 (ins listtype:$Vt, VectorIndexH:$idx, 8960 GPR64sp:$Rn, GPR64pi:$Xm)>; 8961} 8962let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8963multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 8964 RegisterOperand listtype, RegisterOperand GPR64pi> { 8965 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 8966 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 8967 GPR64sp:$Rn), []>; 8968 8969 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 8970 (outs GPR64sp:$wback), 8971 (ins listtype:$Vt, VectorIndexS:$idx, 8972 GPR64sp:$Rn, GPR64pi:$Xm)>; 8973} 8974let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8975multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 8976 RegisterOperand listtype, RegisterOperand GPR64pi> { 8977 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 8978 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 8979 GPR64sp:$Rn), []>; 8980 8981 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 8982 (outs GPR64sp:$wback), 8983 (ins listtype:$Vt, VectorIndexD:$idx, 8984 GPR64sp:$Rn, GPR64pi:$Xm)>; 8985} 8986 8987multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 8988 string Count, int Offset, Operand idxtype> { 8989 // E.g. "ld1 { v0.8b }[0], [x1], #1" 8990 // "ld1\t$Vt, [$Rn], #1" 8991 // may get mapped to 8992 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 8993 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 8994 (!cast<Instruction>(NAME # Type # "_POST") 8995 GPR64sp:$Rn, 8996 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8997 idxtype:$idx, XZR), 1>; 8998 8999 // E.g. "ld1.8b { v0 }[0], [x1], #1" 9000 // "ld1.8b\t$Vt, [$Rn], #1" 9001 // may get mapped to 9002 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9003 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 9004 (!cast<Instruction>(NAME # Type # "_POST") 9005 GPR64sp:$Rn, 9006 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9007 idxtype:$idx, XZR), 0>; 9008 9009 // E.g. "ld1.8b { v0 }[0], [x1]" 9010 // "ld1.8b\t$Vt, [$Rn]" 9011 // may get mapped to 9012 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9013 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 9014 (!cast<Instruction>(NAME # Type) 9015 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9016 idxtype:$idx, GPR64sp:$Rn), 0>; 9017 9018 // E.g. "ld1.8b { v0 }[0], [x1], x2" 9019 // "ld1.8b\t$Vt, [$Rn], $Xm" 9020 // may get mapped to 9021 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9022 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 9023 (!cast<Instruction>(NAME # Type # "_POST") 9024 GPR64sp:$Rn, 9025 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9026 idxtype:$idx, 9027 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9028} 9029 9030multiclass SIMDLdSt1SingleAliases<string asm> { 9031 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 9032 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 9033 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 9034 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 9035} 9036 9037multiclass SIMDLdSt2SingleAliases<string asm> { 9038 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 9039 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 9040 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 9041 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 9042} 9043 9044multiclass SIMDLdSt3SingleAliases<string asm> { 9045 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 9046 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 9047 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 9048 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 9049} 9050 9051multiclass SIMDLdSt4SingleAliases<string asm> { 9052 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 9053 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 9054 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 9055 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 9056} 9057} // end of 'let Predicates = [HasNEON]' 9058 9059//---------------------------------------------------------------------------- 9060// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 9061//---------------------------------------------------------------------------- 9062 9063let Predicates = [HasNEON, HasV8_1a] in { 9064 9065class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 9066 RegisterOperand regtype, string asm, 9067 string kind, list<dag> pattern> 9068 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 9069 pattern> { 9070} 9071multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 9072 SDPatternOperator Accum> { 9073 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 9074 [(set (v4i16 V64:$dst), 9075 (Accum (v4i16 V64:$Rd), 9076 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 9077 (v4i16 V64:$Rm)))))]>; 9078 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 9079 [(set (v8i16 V128:$dst), 9080 (Accum (v8i16 V128:$Rd), 9081 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 9082 (v8i16 V128:$Rm)))))]>; 9083 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 9084 [(set (v2i32 V64:$dst), 9085 (Accum (v2i32 V64:$Rd), 9086 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 9087 (v2i32 V64:$Rm)))))]>; 9088 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 9089 [(set (v4i32 V128:$dst), 9090 (Accum (v4i32 V128:$Rd), 9091 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 9092 (v4i32 V128:$Rm)))))]>; 9093} 9094 9095multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 9096 SDPatternOperator Accum> { 9097 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9098 V64, V64, V128_lo, VectorIndexH, 9099 asm, ".4h", ".4h", ".4h", ".h", 9100 [(set (v4i16 V64:$dst), 9101 (Accum (v4i16 V64:$Rd), 9102 (v4i16 (int_aarch64_neon_sqrdmulh 9103 (v4i16 V64:$Rn), 9104 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9105 VectorIndexH:$idx))))))]> { 9106 bits<3> idx; 9107 let Inst{11} = idx{2}; 9108 let Inst{21} = idx{1}; 9109 let Inst{20} = idx{0}; 9110 } 9111 9112 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9113 V128, V128, V128_lo, VectorIndexH, 9114 asm, ".8h", ".8h", ".8h", ".h", 9115 [(set (v8i16 V128:$dst), 9116 (Accum (v8i16 V128:$Rd), 9117 (v8i16 (int_aarch64_neon_sqrdmulh 9118 (v8i16 V128:$Rn), 9119 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9120 VectorIndexH:$idx))))))]> { 9121 bits<3> idx; 9122 let Inst{11} = idx{2}; 9123 let Inst{21} = idx{1}; 9124 let Inst{20} = idx{0}; 9125 } 9126 9127 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9128 V64, V64, V128, VectorIndexS, 9129 asm, ".2s", ".2s", ".2s", ".s", 9130 [(set (v2i32 V64:$dst), 9131 (Accum (v2i32 V64:$Rd), 9132 (v2i32 (int_aarch64_neon_sqrdmulh 9133 (v2i32 V64:$Rn), 9134 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 9135 VectorIndexS:$idx))))))]> { 9136 bits<2> idx; 9137 let Inst{11} = idx{1}; 9138 let Inst{21} = idx{0}; 9139 } 9140 9141 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 9142 // an intermediate EXTRACT_SUBREG would be untyped. 9143 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 9144 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 9145 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9146 (i32 (vector_extract 9147 (v4i32 (insert_subvector 9148 (undef), 9149 (v2i32 (int_aarch64_neon_sqrdmulh 9150 (v2i32 V64:$Rn), 9151 (v2i32 (AArch64duplane32 9152 (v4i32 V128:$Rm), 9153 VectorIndexS:$idx)))), 9154 (i32 0))), 9155 (i64 0))))), 9156 (EXTRACT_SUBREG 9157 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 9158 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 9159 FPR32Op:$Rd, 9160 ssub)), 9161 V64:$Rn, 9162 V128:$Rm, 9163 VectorIndexS:$idx)), 9164 ssub)>; 9165 9166 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9167 V128, V128, V128, VectorIndexS, 9168 asm, ".4s", ".4s", ".4s", ".s", 9169 [(set (v4i32 V128:$dst), 9170 (Accum (v4i32 V128:$Rd), 9171 (v4i32 (int_aarch64_neon_sqrdmulh 9172 (v4i32 V128:$Rn), 9173 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 9174 VectorIndexS:$idx))))))]> { 9175 bits<2> idx; 9176 let Inst{11} = idx{1}; 9177 let Inst{21} = idx{0}; 9178 } 9179 9180 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 9181 // an intermediate EXTRACT_SUBREG would be untyped. 9182 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9183 (i32 (vector_extract 9184 (v4i32 (int_aarch64_neon_sqrdmulh 9185 (v4i32 V128:$Rn), 9186 (v4i32 (AArch64duplane32 9187 (v4i32 V128:$Rm), 9188 VectorIndexS:$idx)))), 9189 (i64 0))))), 9190 (EXTRACT_SUBREG 9191 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 9192 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 9193 FPR32Op:$Rd, 9194 ssub)), 9195 V128:$Rn, 9196 V128:$Rm, 9197 VectorIndexS:$idx)), 9198 ssub)>; 9199 9200 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9201 FPR16Op, FPR16Op, V128_lo, 9202 VectorIndexH, asm, ".h", "", "", ".h", 9203 []> { 9204 bits<3> idx; 9205 let Inst{11} = idx{2}; 9206 let Inst{21} = idx{1}; 9207 let Inst{20} = idx{0}; 9208 } 9209 9210 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9211 FPR32Op, FPR32Op, V128, VectorIndexS, 9212 asm, ".s", "", "", ".s", 9213 [(set (i32 FPR32Op:$dst), 9214 (Accum (i32 FPR32Op:$Rd), 9215 (i32 (int_aarch64_neon_sqrdmulh 9216 (i32 FPR32Op:$Rn), 9217 (i32 (vector_extract (v4i32 V128:$Rm), 9218 VectorIndexS:$idx))))))]> { 9219 bits<2> idx; 9220 let Inst{11} = idx{1}; 9221 let Inst{21} = idx{0}; 9222 } 9223} 9224} // let Predicates = [HasNeon, HasV8_1a] 9225 9226//---------------------------------------------------------------------------- 9227// Crypto extensions 9228//---------------------------------------------------------------------------- 9229 9230let Predicates = [HasCrypto] in { 9231let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9232class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 9233 list<dag> pat> 9234 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 9235 Sched<[WriteV]>{ 9236 bits<5> Rd; 9237 bits<5> Rn; 9238 let Inst{31-16} = 0b0100111000101000; 9239 let Inst{15-12} = opc; 9240 let Inst{11-10} = 0b10; 9241 let Inst{9-5} = Rn; 9242 let Inst{4-0} = Rd; 9243} 9244 9245class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 9246 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 9247 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 9248 9249class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 9250 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 9251 "$Rd = $dst", 9252 [(set (v16i8 V128:$dst), 9253 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 9254 9255let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9256class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 9257 dag oops, dag iops, list<dag> pat> 9258 : I<oops, iops, asm, 9259 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 9260 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 9261 Sched<[WriteV]>{ 9262 bits<5> Rd; 9263 bits<5> Rn; 9264 bits<5> Rm; 9265 let Inst{31-21} = 0b01011110000; 9266 let Inst{20-16} = Rm; 9267 let Inst{15} = 0; 9268 let Inst{14-12} = opc; 9269 let Inst{11-10} = 0b00; 9270 let Inst{9-5} = Rn; 9271 let Inst{4-0} = Rd; 9272} 9273 9274class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 9275 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 9276 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 9277 [(set (v4i32 FPR128:$dst), 9278 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 9279 (v4i32 V128:$Rm)))]>; 9280 9281class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 9282 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 9283 (ins V128:$Rd, V128:$Rn, V128:$Rm), 9284 [(set (v4i32 V128:$dst), 9285 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9286 (v4i32 V128:$Rm)))]>; 9287 9288class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 9289 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 9290 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 9291 [(set (v4i32 FPR128:$dst), 9292 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 9293 (v4i32 V128:$Rm)))]>; 9294 9295let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9296class SHA2OpInst<bits<4> opc, string asm, string kind, 9297 string cstr, dag oops, dag iops, 9298 list<dag> pat> 9299 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 9300 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 9301 Sched<[WriteV]>{ 9302 bits<5> Rd; 9303 bits<5> Rn; 9304 let Inst{31-16} = 0b0101111000101000; 9305 let Inst{15-12} = opc; 9306 let Inst{11-10} = 0b10; 9307 let Inst{9-5} = Rn; 9308 let Inst{4-0} = Rd; 9309} 9310 9311class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 9312 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 9313 (ins V128:$Rd, V128:$Rn), 9314 [(set (v4i32 V128:$dst), 9315 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 9316 9317class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 9318 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 9319 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 9320} // end of 'let Predicates = [HasCrypto]' 9321 9322//---------------------------------------------------------------------------- 9323// v8.1 atomic instructions extension: 9324// * CAS 9325// * CASP 9326// * SWP 9327// * LDOPregister<OP>, and aliases STOPregister<OP> 9328 9329// Instruction encodings: 9330// 9331// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 9332// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 9333// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 9334// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 9335// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 9336// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 9337 9338// Instruction syntax: 9339// 9340// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 9341// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 9342// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 9343// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 9344// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 9345// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 9346// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 9347// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 9348// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 9349// ST<OP>{<order>} <Xs>, [<Xn|SP>] 9350 9351let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 9352class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 9353 string cstr, list<dag> pattern> 9354 : I<oops, iops, asm, operands, cstr, pattern> { 9355 bits<2> Sz; 9356 bit NP; 9357 bit Acq; 9358 bit Rel; 9359 bits<5> Rs; 9360 bits<5> Rn; 9361 bits<5> Rt; 9362 let Inst{31-30} = Sz; 9363 let Inst{29-24} = 0b001000; 9364 let Inst{23} = NP; 9365 let Inst{22} = Acq; 9366 let Inst{21} = 0b1; 9367 let Inst{20-16} = Rs; 9368 let Inst{15} = Rel; 9369 let Inst{14-10} = 0b11111; 9370 let Inst{9-5} = Rn; 9371 let Inst{4-0} = Rt; 9372} 9373 9374class BaseCAS<string order, string size, RegisterClass RC> 9375 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 9376 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 9377 "$out = $Rs",[]>, 9378 Sched<[WriteAtomic]> { 9379 let NP = 1; 9380} 9381 9382multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 9383 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>; 9384 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>; 9385 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>; 9386 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>; 9387} 9388 9389class BaseCASP<string order, string size, RegisterOperand RC> 9390 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 9391 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 9392 "$out = $Rs",[]>, 9393 Sched<[WriteAtomic]> { 9394 let NP = 0; 9395} 9396 9397multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 9398 let Sz = 0b00, Acq = Acq, Rel = Rel in 9399 def s : BaseCASP<order, "", WSeqPairClassOperand>; 9400 let Sz = 0b01, Acq = Acq, Rel = Rel in 9401 def d : BaseCASP<order, "", XSeqPairClassOperand>; 9402} 9403 9404let Predicates = [HasV8_1a] in 9405class BaseSWP<string order, string size, RegisterClass RC> 9406 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 9407 "\t$Rs, $Rt, [$Rn]","",[]>, 9408 Sched<[WriteAtomic]> { 9409 bits<2> Sz; 9410 bit Acq; 9411 bit Rel; 9412 bits<5> Rs; 9413 bits<3> opc = 0b000; 9414 bits<5> Rn; 9415 bits<5> Rt; 9416 let Inst{31-30} = Sz; 9417 let Inst{29-24} = 0b111000; 9418 let Inst{23} = Acq; 9419 let Inst{22} = Rel; 9420 let Inst{21} = 0b1; 9421 let Inst{20-16} = Rs; 9422 let Inst{15} = 0b1; 9423 let Inst{14-12} = opc; 9424 let Inst{11-10} = 0b00; 9425 let Inst{9-5} = Rn; 9426 let Inst{4-0} = Rt; 9427} 9428 9429multiclass Swap<bits<1> Acq, bits<1> Rel, string order> { 9430 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>; 9431 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>; 9432 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>; 9433 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>; 9434} 9435 9436let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 9437class BaseLDOPregister<string op, string order, string size, RegisterClass RC> 9438 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size, 9439 "\t$Rs, $Rt, [$Rn]","",[]>, 9440 Sched<[WriteAtomic]> { 9441 bits<2> Sz; 9442 bit Acq; 9443 bit Rel; 9444 bits<5> Rs; 9445 bits<3> opc; 9446 bits<5> Rn; 9447 bits<5> Rt; 9448 let Inst{31-30} = Sz; 9449 let Inst{29-24} = 0b111000; 9450 let Inst{23} = Acq; 9451 let Inst{22} = Rel; 9452 let Inst{21} = 0b1; 9453 let Inst{20-16} = Rs; 9454 let Inst{15} = 0b0; 9455 let Inst{14-12} = opc; 9456 let Inst{11-10} = 0b00; 9457 let Inst{9-5} = Rn; 9458 let Inst{4-0} = Rt; 9459} 9460 9461multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 9462 string order> { 9463 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 9464 def b : BaseLDOPregister<op, order, "b", GPR32>; 9465 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 9466 def h : BaseLDOPregister<op, order, "h", GPR32>; 9467 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 9468 def s : BaseLDOPregister<op, order, "", GPR32>; 9469 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 9470 def d : BaseLDOPregister<op, order, "", GPR64>; 9471} 9472 9473let Predicates = [HasV8_1a] in 9474class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 9475 Instruction inst> : 9476 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 9477 9478multiclass STOPregister<string asm, string instr> { 9479 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 9480 !cast<Instruction>(instr # "Lb")>; 9481 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 9482 !cast<Instruction>(instr # "Lh")>; 9483 def : BaseSTOPregister<asm # "l", GPR32, WZR, 9484 !cast<Instruction>(instr # "Ls")>; 9485 def : BaseSTOPregister<asm # "l", GPR64, XZR, 9486 !cast<Instruction>(instr # "Ld")>; 9487 def : BaseSTOPregister<asm # "b", GPR32, WZR, 9488 !cast<Instruction>(instr # "b")>; 9489 def : BaseSTOPregister<asm # "h", GPR32, WZR, 9490 !cast<Instruction>(instr # "h")>; 9491 def : BaseSTOPregister<asm, GPR32, WZR, 9492 !cast<Instruction>(instr # "s")>; 9493 def : BaseSTOPregister<asm, GPR64, XZR, 9494 !cast<Instruction>(instr # "d")>; 9495} 9496 9497//---------------------------------------------------------------------------- 9498// Allow the size specifier tokens to be upper case, not just lower. 9499def : TokenAlias<".8B", ".8b">; 9500def : TokenAlias<".4H", ".4h">; 9501def : TokenAlias<".2S", ".2s">; 9502def : TokenAlias<".1D", ".1d">; 9503def : TokenAlias<".16B", ".16b">; 9504def : TokenAlias<".8H", ".8h">; 9505def : TokenAlias<".4S", ".4s">; 9506def : TokenAlias<".2D", ".2d">; 9507def : TokenAlias<".1Q", ".1q">; 9508def : TokenAlias<".2H", ".2h">; 9509def : TokenAlias<".B", ".b">; 9510def : TokenAlias<".H", ".h">; 9511def : TokenAlias<".S", ".s">; 9512def : TokenAlias<".D", ".d">; 9513def : TokenAlias<".Q", ".q">; 9514