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 = "printHexImm"; 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 = "printHexImm"; 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 = "printHexImm"; 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 bool ValidNamed; 927 (void)AArch64PSBHint::PSBHintMapper().toString(MCOp.getImm(), 928 STI.getFeatureBits(), ValidNamed); 929 return ValidNamed; 930 }]; 931} 932 933class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 934 "mrs", "\t$Rt, $systemreg"> { 935 bits<16> systemreg; 936 let Inst{20-5} = systemreg; 937} 938 939// FIXME: Some of these def NZCV, others don't. Best way to model that? 940// Explicitly modeling each of the system register as a register class 941// would do it, but feels like overkill at this point. 942class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 943 "msr", "\t$systemreg, $Rt"> { 944 bits<16> systemreg; 945 let Inst{20-5} = systemreg; 946} 947 948def SystemPStateFieldWithImm0_15Operand : AsmOperandClass { 949 let Name = "SystemPStateFieldWithImm0_15"; 950 let ParserMethod = "tryParseSysReg"; 951} 952def pstatefield4_op : Operand<i32> { 953 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand; 954 let PrintMethod = "printSystemPStateField"; 955} 956 957let Defs = [NZCV] in 958class MSRpstateImm0_15 959 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm), 960 "msr", "\t$pstatefield, $imm">, 961 Sched<[WriteSys]> { 962 bits<6> pstatefield; 963 bits<4> imm; 964 let Inst{20-19} = 0b00; 965 let Inst{18-16} = pstatefield{5-3}; 966 let Inst{15-12} = 0b0100; 967 let Inst{11-8} = imm; 968 let Inst{7-5} = pstatefield{2-0}; 969 970 let DecoderMethod = "DecodeSystemPStateInstruction"; 971 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 972 // Fail the decoder should attempt to decode the instruction as MSRI. 973 let hasCompleteDecoder = 0; 974} 975 976def SystemPStateFieldWithImm0_1Operand : AsmOperandClass { 977 let Name = "SystemPStateFieldWithImm0_1"; 978 let ParserMethod = "tryParseSysReg"; 979} 980def pstatefield1_op : Operand<i32> { 981 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand; 982 let PrintMethod = "printSystemPStateField"; 983} 984 985let Defs = [NZCV] in 986class MSRpstateImm0_1 987 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm), 988 "msr", "\t$pstatefield, $imm">, 989 Sched<[WriteSys]> { 990 bits<6> pstatefield; 991 bit imm; 992 let Inst{20-19} = 0b00; 993 let Inst{18-16} = pstatefield{5-3}; 994 let Inst{15-9} = 0b0100000; 995 let Inst{8} = imm; 996 let Inst{7-5} = pstatefield{2-0}; 997 998 let DecoderMethod = "DecodeSystemPStateInstruction"; 999 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns 1000 // Fail the decoder should attempt to decode the instruction as MSRI. 1001 let hasCompleteDecoder = 0; 1002} 1003 1004// SYS and SYSL generic system instructions. 1005def SysCRAsmOperand : AsmOperandClass { 1006 let Name = "SysCR"; 1007 let ParserMethod = "tryParseSysCROperand"; 1008} 1009 1010def sys_cr_op : Operand<i32> { 1011 let PrintMethod = "printSysCROperand"; 1012 let ParserMatchClass = SysCRAsmOperand; 1013} 1014 1015class SystemXtI<bit L, string asm> 1016 : RtSystemI<L, (outs), 1017 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 1018 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 1019 bits<3> op1; 1020 bits<4> Cn; 1021 bits<4> Cm; 1022 bits<3> op2; 1023 let Inst{20-19} = 0b01; 1024 let Inst{18-16} = op1; 1025 let Inst{15-12} = Cn; 1026 let Inst{11-8} = Cm; 1027 let Inst{7-5} = op2; 1028} 1029 1030class SystemLXtI<bit L, string asm> 1031 : RtSystemI<L, (outs), 1032 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 1033 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 1034 bits<3> op1; 1035 bits<4> Cn; 1036 bits<4> Cm; 1037 bits<3> op2; 1038 let Inst{20-19} = 0b01; 1039 let Inst{18-16} = op1; 1040 let Inst{15-12} = Cn; 1041 let Inst{11-8} = Cm; 1042 let Inst{7-5} = op2; 1043} 1044 1045 1046// Branch (register) instructions: 1047// 1048// case opc of 1049// 0001 blr 1050// 0000 br 1051// 0101 dret 1052// 0100 eret 1053// 0010 ret 1054// otherwise UNDEFINED 1055class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 1056 string operands, list<dag> pattern> 1057 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 1058 let Inst{31-25} = 0b1101011; 1059 let Inst{24-21} = opc; 1060 let Inst{20-16} = 0b11111; 1061 let Inst{15-10} = 0b000000; 1062 let Inst{4-0} = 0b00000; 1063} 1064 1065class BranchReg<bits<4> opc, string asm, list<dag> pattern> 1066 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 1067 bits<5> Rn; 1068 let Inst{9-5} = Rn; 1069} 1070 1071let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 1072class SpecialReturn<bits<4> opc, string asm> 1073 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 1074 let Inst{9-5} = 0b11111; 1075} 1076 1077//--- 1078// Conditional branch instruction. 1079//--- 1080 1081// Condition code. 1082// 4-bit immediate. Pretty-printed as <cc> 1083def ccode : Operand<i32> { 1084 let PrintMethod = "printCondCode"; 1085 let ParserMatchClass = CondCode; 1086} 1087def inv_ccode : Operand<i32> { 1088 // AL and NV are invalid in the aliases which use inv_ccode 1089 let PrintMethod = "printInverseCondCode"; 1090 let ParserMatchClass = CondCode; 1091 let MCOperandPredicate = [{ 1092 return MCOp.isImm() && 1093 MCOp.getImm() != AArch64CC::AL && 1094 MCOp.getImm() != AArch64CC::NV; 1095 }]; 1096} 1097 1098// Conditional branch target. 19-bit immediate. The low two bits of the target 1099// offset are implied zero and so are not part of the immediate. 1100def PCRelLabel19Operand : AsmOperandClass { 1101 let Name = "PCRelLabel19"; 1102 let DiagnosticType = "InvalidLabel"; 1103} 1104def am_brcond : Operand<OtherVT> { 1105 let EncoderMethod = "getCondBranchTargetOpValue"; 1106 let DecoderMethod = "DecodePCRelLabel19"; 1107 let PrintMethod = "printAlignedLabel"; 1108 let ParserMatchClass = PCRelLabel19Operand; 1109} 1110 1111class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1112 "b", ".$cond\t$target", "", 1113 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1114 Sched<[WriteBr]> { 1115 let isBranch = 1; 1116 let isTerminator = 1; 1117 let Uses = [NZCV]; 1118 1119 bits<4> cond; 1120 bits<19> target; 1121 let Inst{31-24} = 0b01010100; 1122 let Inst{23-5} = target; 1123 let Inst{4} = 0; 1124 let Inst{3-0} = cond; 1125} 1126 1127//--- 1128// Compare-and-branch instructions. 1129//--- 1130class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1131 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1132 asm, "\t$Rt, $target", "", 1133 [(node regtype:$Rt, bb:$target)]>, 1134 Sched<[WriteBr]> { 1135 let isBranch = 1; 1136 let isTerminator = 1; 1137 1138 bits<5> Rt; 1139 bits<19> target; 1140 let Inst{30-25} = 0b011010; 1141 let Inst{24} = op; 1142 let Inst{23-5} = target; 1143 let Inst{4-0} = Rt; 1144} 1145 1146multiclass CmpBranch<bit op, string asm, SDNode node> { 1147 def W : BaseCmpBranch<GPR32, op, asm, node> { 1148 let Inst{31} = 0; 1149 } 1150 def X : BaseCmpBranch<GPR64, op, asm, node> { 1151 let Inst{31} = 1; 1152 } 1153} 1154 1155//--- 1156// Test-bit-and-branch instructions. 1157//--- 1158// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1159// the target offset are implied zero and so are not part of the immediate. 1160def BranchTarget14Operand : AsmOperandClass { 1161 let Name = "BranchTarget14"; 1162} 1163def am_tbrcond : Operand<OtherVT> { 1164 let EncoderMethod = "getTestBranchTargetOpValue"; 1165 let PrintMethod = "printAlignedLabel"; 1166 let ParserMatchClass = BranchTarget14Operand; 1167} 1168 1169// AsmOperand classes to emit (or not) special diagnostics 1170def TBZImm0_31Operand : AsmOperandClass { 1171 let Name = "TBZImm0_31"; 1172 let PredicateMethod = "isImm0_31"; 1173 let RenderMethod = "addImm0_31Operands"; 1174} 1175def TBZImm32_63Operand : AsmOperandClass { 1176 let Name = "Imm32_63"; 1177 let DiagnosticType = "InvalidImm0_63"; 1178} 1179 1180class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1181 return (((uint32_t)Imm) < 32); 1182}]> { 1183 let ParserMatchClass = matcher; 1184} 1185 1186def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1187def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1188 1189def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1190 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1191}]> { 1192 let ParserMatchClass = TBZImm32_63Operand; 1193} 1194 1195class BaseTestBranch<RegisterClass regtype, Operand immtype, 1196 bit op, string asm, SDNode node> 1197 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1198 asm, "\t$Rt, $bit_off, $target", "", 1199 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1200 Sched<[WriteBr]> { 1201 let isBranch = 1; 1202 let isTerminator = 1; 1203 1204 bits<5> Rt; 1205 bits<6> bit_off; 1206 bits<14> target; 1207 1208 let Inst{30-25} = 0b011011; 1209 let Inst{24} = op; 1210 let Inst{23-19} = bit_off{4-0}; 1211 let Inst{18-5} = target; 1212 let Inst{4-0} = Rt; 1213 1214 let DecoderMethod = "DecodeTestAndBranch"; 1215} 1216 1217multiclass TestBranch<bit op, string asm, SDNode node> { 1218 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1219 let Inst{31} = 0; 1220 } 1221 1222 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1223 let Inst{31} = 1; 1224 } 1225 1226 // Alias X-reg with 0-31 imm to W-Reg. 1227 def : InstAlias<asm # "\t$Rd, $imm, $target", 1228 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1229 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1230 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1231 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1232 tbz_imm0_31_diag:$imm, bb:$target)>; 1233} 1234 1235//--- 1236// Unconditional branch (immediate) instructions. 1237//--- 1238def BranchTarget26Operand : AsmOperandClass { 1239 let Name = "BranchTarget26"; 1240 let DiagnosticType = "InvalidLabel"; 1241} 1242def am_b_target : Operand<OtherVT> { 1243 let EncoderMethod = "getBranchTargetOpValue"; 1244 let PrintMethod = "printAlignedLabel"; 1245 let ParserMatchClass = BranchTarget26Operand; 1246} 1247def am_bl_target : Operand<i64> { 1248 let EncoderMethod = "getBranchTargetOpValue"; 1249 let PrintMethod = "printAlignedLabel"; 1250 let ParserMatchClass = BranchTarget26Operand; 1251} 1252 1253class BImm<bit op, dag iops, string asm, list<dag> pattern> 1254 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1255 bits<26> addr; 1256 let Inst{31} = op; 1257 let Inst{30-26} = 0b00101; 1258 let Inst{25-0} = addr; 1259 1260 let DecoderMethod = "DecodeUnconditionalBranch"; 1261} 1262 1263class BranchImm<bit op, string asm, list<dag> pattern> 1264 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1265class CallImm<bit op, string asm, list<dag> pattern> 1266 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1267 1268//--- 1269// Basic one-operand data processing instructions. 1270//--- 1271 1272let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1273class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1274 SDPatternOperator node> 1275 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1276 [(set regtype:$Rd, (node regtype:$Rn))]>, 1277 Sched<[WriteI, ReadI]> { 1278 bits<5> Rd; 1279 bits<5> Rn; 1280 1281 let Inst{30-13} = 0b101101011000000000; 1282 let Inst{12-10} = opc; 1283 let Inst{9-5} = Rn; 1284 let Inst{4-0} = Rd; 1285} 1286 1287let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1288multiclass OneOperandData<bits<3> opc, string asm, 1289 SDPatternOperator node = null_frag> { 1290 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1291 let Inst{31} = 0; 1292 } 1293 1294 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1295 let Inst{31} = 1; 1296 } 1297} 1298 1299class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1300 : BaseOneOperandData<opc, GPR32, asm, node> { 1301 let Inst{31} = 0; 1302} 1303 1304class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1305 : BaseOneOperandData<opc, GPR64, asm, node> { 1306 let Inst{31} = 1; 1307} 1308 1309//--- 1310// Basic two-operand data processing instructions. 1311//--- 1312class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1313 list<dag> pattern> 1314 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1315 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1316 Sched<[WriteI, ReadI, ReadI]> { 1317 let Uses = [NZCV]; 1318 bits<5> Rd; 1319 bits<5> Rn; 1320 bits<5> Rm; 1321 let Inst{30} = isSub; 1322 let Inst{28-21} = 0b11010000; 1323 let Inst{20-16} = Rm; 1324 let Inst{15-10} = 0; 1325 let Inst{9-5} = Rn; 1326 let Inst{4-0} = Rd; 1327} 1328 1329class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1330 SDNode OpNode> 1331 : BaseBaseAddSubCarry<isSub, regtype, asm, 1332 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 1333 1334class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 1335 SDNode OpNode> 1336 : BaseBaseAddSubCarry<isSub, regtype, asm, 1337 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 1338 (implicit NZCV)]> { 1339 let Defs = [NZCV]; 1340} 1341 1342multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 1343 SDNode OpNode, SDNode OpNode_setflags> { 1344 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 1345 let Inst{31} = 0; 1346 let Inst{29} = 0; 1347 } 1348 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 1349 let Inst{31} = 1; 1350 let Inst{29} = 0; 1351 } 1352 1353 // Sets flags. 1354 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 1355 OpNode_setflags> { 1356 let Inst{31} = 0; 1357 let Inst{29} = 1; 1358 } 1359 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 1360 OpNode_setflags> { 1361 let Inst{31} = 1; 1362 let Inst{29} = 1; 1363 } 1364} 1365 1366class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 1367 SDPatternOperator OpNode> 1368 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1369 asm, "\t$Rd, $Rn, $Rm", "", 1370 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> { 1371 bits<5> Rd; 1372 bits<5> Rn; 1373 bits<5> Rm; 1374 let Inst{30-21} = 0b0011010110; 1375 let Inst{20-16} = Rm; 1376 let Inst{15-14} = 0b00; 1377 let Inst{13-10} = opc; 1378 let Inst{9-5} = Rn; 1379 let Inst{4-0} = Rd; 1380} 1381 1382class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 1383 SDPatternOperator OpNode> 1384 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 1385 let Inst{10} = isSigned; 1386} 1387 1388multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 1389 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 1390 Sched<[WriteID32, ReadID, ReadID]> { 1391 let Inst{31} = 0; 1392 } 1393 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 1394 Sched<[WriteID64, ReadID, ReadID]> { 1395 let Inst{31} = 1; 1396 } 1397} 1398 1399class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 1400 SDPatternOperator OpNode = null_frag> 1401 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 1402 Sched<[WriteIS, ReadI]> { 1403 let Inst{11-10} = shift_type; 1404} 1405 1406multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 1407 def Wr : BaseShift<shift_type, GPR32, asm> { 1408 let Inst{31} = 0; 1409 } 1410 1411 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 1412 let Inst{31} = 1; 1413 } 1414 1415 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 1416 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 1417 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 1418 1419 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 1420 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1421 1422 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 1423 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1424 1425 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 1426 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1427} 1428 1429class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 1430 : InstAlias<asm#"\t$dst, $src1, $src2", 1431 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 1432 1433class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 1434 RegisterClass addtype, string asm, 1435 list<dag> pattern> 1436 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 1437 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 1438 bits<5> Rd; 1439 bits<5> Rn; 1440 bits<5> Rm; 1441 bits<5> Ra; 1442 let Inst{30-24} = 0b0011011; 1443 let Inst{23-21} = opc; 1444 let Inst{20-16} = Rm; 1445 let Inst{15} = isSub; 1446 let Inst{14-10} = Ra; 1447 let Inst{9-5} = Rn; 1448 let Inst{4-0} = Rd; 1449} 1450 1451multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 1452 // MADD/MSUB generation is decided by MachineCombiner.cpp 1453 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 1454 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 1455 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1456 let Inst{31} = 0; 1457 } 1458 1459 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 1460 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 1461 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 1462 let Inst{31} = 1; 1463 } 1464} 1465 1466class WideMulAccum<bit isSub, bits<3> opc, string asm, 1467 SDNode AccNode, SDNode ExtNode> 1468 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 1469 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 1470 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 1471 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1472 let Inst{31} = 1; 1473} 1474 1475class MulHi<bits<3> opc, string asm, SDNode OpNode> 1476 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 1477 asm, "\t$Rd, $Rn, $Rm", "", 1478 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 1479 Sched<[WriteIM64, ReadIM, ReadIM]> { 1480 bits<5> Rd; 1481 bits<5> Rn; 1482 bits<5> Rm; 1483 let Inst{31-24} = 0b10011011; 1484 let Inst{23-21} = opc; 1485 let Inst{20-16} = Rm; 1486 let Inst{15} = 0; 1487 let Inst{9-5} = Rn; 1488 let Inst{4-0} = Rd; 1489 1490 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 1491 // (i.e. all bits 1) but is ignored by the processor. 1492 let PostEncoderMethod = "fixMulHigh"; 1493} 1494 1495class MulAccumWAlias<string asm, Instruction inst> 1496 : InstAlias<asm#"\t$dst, $src1, $src2", 1497 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 1498class MulAccumXAlias<string asm, Instruction inst> 1499 : InstAlias<asm#"\t$dst, $src1, $src2", 1500 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 1501class WideMulAccumAlias<string asm, Instruction inst> 1502 : InstAlias<asm#"\t$dst, $src1, $src2", 1503 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 1504 1505class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 1506 SDPatternOperator OpNode, string asm> 1507 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 1508 asm, "\t$Rd, $Rn, $Rm", "", 1509 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 1510 Sched<[WriteISReg, ReadI, ReadISReg]> { 1511 bits<5> Rd; 1512 bits<5> Rn; 1513 bits<5> Rm; 1514 1515 let Inst{31} = sf; 1516 let Inst{30-21} = 0b0011010110; 1517 let Inst{20-16} = Rm; 1518 let Inst{15-13} = 0b010; 1519 let Inst{12} = C; 1520 let Inst{11-10} = sz; 1521 let Inst{9-5} = Rn; 1522 let Inst{4-0} = Rd; 1523 let Predicates = [HasCRC]; 1524} 1525 1526//--- 1527// Address generation. 1528//--- 1529 1530class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 1531 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 1532 pattern>, 1533 Sched<[WriteI]> { 1534 bits<5> Xd; 1535 bits<21> label; 1536 let Inst{31} = page; 1537 let Inst{30-29} = label{1-0}; 1538 let Inst{28-24} = 0b10000; 1539 let Inst{23-5} = label{20-2}; 1540 let Inst{4-0} = Xd; 1541 1542 let DecoderMethod = "DecodeAdrInstruction"; 1543} 1544 1545//--- 1546// Move immediate. 1547//--- 1548 1549def movimm32_imm : Operand<i32> { 1550 let ParserMatchClass = Imm0_65535Operand; 1551 let EncoderMethod = "getMoveWideImmOpValue"; 1552 let PrintMethod = "printHexImm"; 1553} 1554def movimm32_shift : Operand<i32> { 1555 let PrintMethod = "printShifter"; 1556 let ParserMatchClass = MovImm32ShifterOperand; 1557} 1558def movimm64_shift : Operand<i32> { 1559 let PrintMethod = "printShifter"; 1560 let ParserMatchClass = MovImm64ShifterOperand; 1561} 1562 1563let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1564class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 1565 string asm> 1566 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 1567 asm, "\t$Rd, $imm$shift", "", []>, 1568 Sched<[WriteImm]> { 1569 bits<5> Rd; 1570 bits<16> imm; 1571 bits<6> shift; 1572 let Inst{30-29} = opc; 1573 let Inst{28-23} = 0b100101; 1574 let Inst{22-21} = shift{5-4}; 1575 let Inst{20-5} = imm; 1576 let Inst{4-0} = Rd; 1577 1578 let DecoderMethod = "DecodeMoveImmInstruction"; 1579} 1580 1581multiclass MoveImmediate<bits<2> opc, string asm> { 1582 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 1583 let Inst{31} = 0; 1584 } 1585 1586 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 1587 let Inst{31} = 1; 1588 } 1589} 1590 1591let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1592class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 1593 string asm> 1594 : I<(outs regtype:$Rd), 1595 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 1596 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 1597 Sched<[WriteI, ReadI]> { 1598 bits<5> Rd; 1599 bits<16> imm; 1600 bits<6> shift; 1601 let Inst{30-29} = opc; 1602 let Inst{28-23} = 0b100101; 1603 let Inst{22-21} = shift{5-4}; 1604 let Inst{20-5} = imm; 1605 let Inst{4-0} = Rd; 1606 1607 let DecoderMethod = "DecodeMoveImmInstruction"; 1608} 1609 1610multiclass InsertImmediate<bits<2> opc, string asm> { 1611 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 1612 let Inst{31} = 0; 1613 } 1614 1615 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 1616 let Inst{31} = 1; 1617 } 1618} 1619 1620//--- 1621// Add/Subtract 1622//--- 1623 1624class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 1625 RegisterClass srcRegtype, addsub_shifted_imm immtype, 1626 string asm, SDPatternOperator OpNode> 1627 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm), 1628 asm, "\t$Rd, $Rn, $imm", "", 1629 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>, 1630 Sched<[WriteI, ReadI]> { 1631 bits<5> Rd; 1632 bits<5> Rn; 1633 bits<14> imm; 1634 let Inst{30} = isSub; 1635 let Inst{29} = setFlags; 1636 let Inst{28-24} = 0b10001; 1637 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 1638 let Inst{21-10} = imm{11-0}; 1639 let Inst{9-5} = Rn; 1640 let Inst{4-0} = Rd; 1641 let DecoderMethod = "DecodeBaseAddSubImm"; 1642} 1643 1644class BaseAddSubRegPseudo<RegisterClass regtype, 1645 SDPatternOperator OpNode> 1646 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1647 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 1648 Sched<[WriteI, ReadI, ReadI]>; 1649 1650class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 1651 arith_shifted_reg shifted_regtype, string asm, 1652 SDPatternOperator OpNode> 1653 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 1654 asm, "\t$Rd, $Rn, $Rm", "", 1655 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 1656 Sched<[WriteISReg, ReadI, ReadISReg]> { 1657 // The operands are in order to match the 'addr' MI operands, so we 1658 // don't need an encoder method and by-name matching. Just use the default 1659 // in-order handling. Since we're using by-order, make sure the names 1660 // do not match. 1661 bits<5> dst; 1662 bits<5> src1; 1663 bits<5> src2; 1664 bits<8> shift; 1665 let Inst{30} = isSub; 1666 let Inst{29} = setFlags; 1667 let Inst{28-24} = 0b01011; 1668 let Inst{23-22} = shift{7-6}; 1669 let Inst{21} = 0; 1670 let Inst{20-16} = src2; 1671 let Inst{15-10} = shift{5-0}; 1672 let Inst{9-5} = src1; 1673 let Inst{4-0} = dst; 1674 1675 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 1676} 1677 1678class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 1679 RegisterClass src1Regtype, Operand src2Regtype, 1680 string asm, SDPatternOperator OpNode> 1681 : I<(outs dstRegtype:$R1), 1682 (ins src1Regtype:$R2, src2Regtype:$R3), 1683 asm, "\t$R1, $R2, $R3", "", 1684 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 1685 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 1686 bits<5> Rd; 1687 bits<5> Rn; 1688 bits<5> Rm; 1689 bits<6> ext; 1690 let Inst{30} = isSub; 1691 let Inst{29} = setFlags; 1692 let Inst{28-24} = 0b01011; 1693 let Inst{23-21} = 0b001; 1694 let Inst{20-16} = Rm; 1695 let Inst{15-13} = ext{5-3}; 1696 let Inst{12-10} = ext{2-0}; 1697 let Inst{9-5} = Rn; 1698 let Inst{4-0} = Rd; 1699 1700 let DecoderMethod = "DecodeAddSubERegInstruction"; 1701} 1702 1703let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1704class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 1705 RegisterClass src1Regtype, RegisterClass src2Regtype, 1706 Operand ext_op, string asm> 1707 : I<(outs dstRegtype:$Rd), 1708 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 1709 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 1710 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 1711 bits<5> Rd; 1712 bits<5> Rn; 1713 bits<5> Rm; 1714 bits<6> ext; 1715 let Inst{30} = isSub; 1716 let Inst{29} = setFlags; 1717 let Inst{28-24} = 0b01011; 1718 let Inst{23-21} = 0b001; 1719 let Inst{20-16} = Rm; 1720 let Inst{15} = ext{5}; 1721 let Inst{12-10} = ext{2-0}; 1722 let Inst{9-5} = Rn; 1723 let Inst{4-0} = Rd; 1724 1725 let DecoderMethod = "DecodeAddSubERegInstruction"; 1726} 1727 1728// Aliases for register+register add/subtract. 1729class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 1730 RegisterClass src1Regtype, RegisterClass src2Regtype, 1731 int shiftExt> 1732 : InstAlias<asm#"\t$dst, $src1, $src2", 1733 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 1734 shiftExt)>; 1735 1736multiclass AddSub<bit isSub, string mnemonic, string alias, 1737 SDPatternOperator OpNode = null_frag> { 1738 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1739 // Add/Subtract immediate 1740 // Increase the weight of the immediate variant to try to match it before 1741 // the extended register variant. 1742 // We used to match the register variant before the immediate when the 1743 // register argument could be implicitly zero-extended. 1744 let AddedComplexity = 6 in 1745 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 1746 mnemonic, OpNode> { 1747 let Inst{31} = 0; 1748 } 1749 let AddedComplexity = 6 in 1750 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 1751 mnemonic, OpNode> { 1752 let Inst{31} = 1; 1753 } 1754 1755 // Add/Subtract register - Only used for CodeGen 1756 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 1757 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 1758 1759 // Add/Subtract shifted register 1760 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 1761 OpNode> { 1762 let Inst{31} = 0; 1763 } 1764 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 1765 OpNode> { 1766 let Inst{31} = 1; 1767 } 1768 } 1769 1770 // Add/Subtract extended register 1771 let AddedComplexity = 1, hasSideEffects = 0 in { 1772 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 1773 arith_extended_reg32<i32>, mnemonic, OpNode> { 1774 let Inst{31} = 0; 1775 } 1776 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 1777 arith_extended_reg32to64<i64>, mnemonic, OpNode> { 1778 let Inst{31} = 1; 1779 } 1780 } 1781 1782 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 1783 arith_extendlsl64, mnemonic> { 1784 // UXTX and SXTX only. 1785 let Inst{14-13} = 0b11; 1786 let Inst{31} = 1; 1787 } 1788 1789 // add Rd, Rb, -imm -> sub Rd, Rn, imm 1790 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1791 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn, 1792 addsub_shifted_imm32_neg:$imm), 0>; 1793 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1794 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn, 1795 addsub_shifted_imm64_neg:$imm), 0>; 1796 1797 // Register/register aliases with no shift when SP is not used. 1798 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 1799 GPR32, GPR32, GPR32, 0>; 1800 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 1801 GPR64, GPR64, GPR64, 0>; 1802 1803 // Register/register aliases with no shift when either the destination or 1804 // first source register is SP. 1805 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1806 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 1807 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1808 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 1809 def : AddSubRegAlias<mnemonic, 1810 !cast<Instruction>(NAME#"Xrx64"), 1811 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 1812 def : AddSubRegAlias<mnemonic, 1813 !cast<Instruction>(NAME#"Xrx64"), 1814 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 1815} 1816 1817multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp, 1818 string alias, string cmpAlias> { 1819 let isCompare = 1, Defs = [NZCV] in { 1820 // Add/Subtract immediate 1821 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 1822 mnemonic, OpNode> { 1823 let Inst{31} = 0; 1824 } 1825 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 1826 mnemonic, OpNode> { 1827 let Inst{31} = 1; 1828 } 1829 1830 // Add/Subtract register 1831 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 1832 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 1833 1834 // Add/Subtract shifted register 1835 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 1836 OpNode> { 1837 let Inst{31} = 0; 1838 } 1839 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 1840 OpNode> { 1841 let Inst{31} = 1; 1842 } 1843 1844 // Add/Subtract extended register 1845 let AddedComplexity = 1 in { 1846 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 1847 arith_extended_reg32<i32>, mnemonic, OpNode> { 1848 let Inst{31} = 0; 1849 } 1850 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 1851 arith_extended_reg32<i64>, mnemonic, OpNode> { 1852 let Inst{31} = 1; 1853 } 1854 } 1855 1856 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 1857 arith_extendlsl64, mnemonic> { 1858 // UXTX and SXTX only. 1859 let Inst{14-13} = 0b11; 1860 let Inst{31} = 1; 1861 } 1862 } // Defs = [NZCV] 1863 1864 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm 1865 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1866 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn, 1867 addsub_shifted_imm32_neg:$imm), 0>; 1868 def : InstAlias<alias#"\t$Rd, $Rn, $imm", 1869 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn, 1870 addsub_shifted_imm64_neg:$imm), 0>; 1871 1872 // Compare aliases 1873 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 1874 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 1875 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 1876 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 1877 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 1878 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 1879 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 1880 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 1881 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 1882 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 1883 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 1884 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 1885 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 1886 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 1887 1888 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm 1889 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri") 1890 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>; 1891 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri") 1892 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>; 1893 1894 // Compare shorthands 1895 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs") 1896 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 1897 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs") 1898 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 1899 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx") 1900 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 1901 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 1902 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 1903 1904 // Register/register aliases with no shift when SP is not used. 1905 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 1906 GPR32, GPR32, GPR32, 0>; 1907 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 1908 GPR64, GPR64, GPR64, 0>; 1909 1910 // Register/register aliases with no shift when the first source register 1911 // is SP. 1912 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1913 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 1914 def : AddSubRegAlias<mnemonic, 1915 !cast<Instruction>(NAME#"Xrx64"), 1916 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 1917} 1918 1919//--- 1920// Extract 1921//--- 1922def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 1923 SDTCisPtrTy<3>]>; 1924def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 1925 1926class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 1927 list<dag> patterns> 1928 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 1929 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 1930 Sched<[WriteExtr, ReadExtrHi]> { 1931 bits<5> Rd; 1932 bits<5> Rn; 1933 bits<5> Rm; 1934 bits<6> imm; 1935 1936 let Inst{30-23} = 0b00100111; 1937 let Inst{21} = 0; 1938 let Inst{20-16} = Rm; 1939 let Inst{15-10} = imm; 1940 let Inst{9-5} = Rn; 1941 let Inst{4-0} = Rd; 1942} 1943 1944multiclass ExtractImm<string asm> { 1945 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 1946 [(set GPR32:$Rd, 1947 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 1948 let Inst{31} = 0; 1949 let Inst{22} = 0; 1950 // imm<5> must be zero. 1951 let imm{5} = 0; 1952 } 1953 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 1954 [(set GPR64:$Rd, 1955 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 1956 1957 let Inst{31} = 1; 1958 let Inst{22} = 1; 1959 } 1960} 1961 1962//--- 1963// Bitfield 1964//--- 1965 1966let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1967class BaseBitfieldImm<bits<2> opc, 1968 RegisterClass regtype, Operand imm_type, string asm> 1969 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 1970 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 1971 Sched<[WriteIS, ReadI]> { 1972 bits<5> Rd; 1973 bits<5> Rn; 1974 bits<6> immr; 1975 bits<6> imms; 1976 1977 let Inst{30-29} = opc; 1978 let Inst{28-23} = 0b100110; 1979 let Inst{21-16} = immr; 1980 let Inst{15-10} = imms; 1981 let Inst{9-5} = Rn; 1982 let Inst{4-0} = Rd; 1983} 1984 1985multiclass BitfieldImm<bits<2> opc, string asm> { 1986 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 1987 let Inst{31} = 0; 1988 let Inst{22} = 0; 1989 // imms<5> and immr<5> must be zero, else ReservedValue(). 1990 let Inst{21} = 0; 1991 let Inst{15} = 0; 1992 } 1993 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 1994 let Inst{31} = 1; 1995 let Inst{22} = 1; 1996 } 1997} 1998 1999let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2000class BaseBitfieldImmWith2RegArgs<bits<2> opc, 2001 RegisterClass regtype, Operand imm_type, string asm> 2002 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 2003 imm_type:$imms), 2004 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 2005 Sched<[WriteIS, ReadI]> { 2006 bits<5> Rd; 2007 bits<5> Rn; 2008 bits<6> immr; 2009 bits<6> imms; 2010 2011 let Inst{30-29} = opc; 2012 let Inst{28-23} = 0b100110; 2013 let Inst{21-16} = immr; 2014 let Inst{15-10} = imms; 2015 let Inst{9-5} = Rn; 2016 let Inst{4-0} = Rd; 2017} 2018 2019multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 2020 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 2021 let Inst{31} = 0; 2022 let Inst{22} = 0; 2023 // imms<5> and immr<5> must be zero, else ReservedValue(). 2024 let Inst{21} = 0; 2025 let Inst{15} = 0; 2026 } 2027 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 2028 let Inst{31} = 1; 2029 let Inst{22} = 1; 2030 } 2031} 2032 2033//--- 2034// Logical 2035//--- 2036 2037// Logical (immediate) 2038class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 2039 RegisterClass sregtype, Operand imm_type, string asm, 2040 list<dag> pattern> 2041 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 2042 asm, "\t$Rd, $Rn, $imm", "", pattern>, 2043 Sched<[WriteI, ReadI]> { 2044 bits<5> Rd; 2045 bits<5> Rn; 2046 bits<13> imm; 2047 let Inst{30-29} = opc; 2048 let Inst{28-23} = 0b100100; 2049 let Inst{22} = imm{12}; 2050 let Inst{21-16} = imm{11-6}; 2051 let Inst{15-10} = imm{5-0}; 2052 let Inst{9-5} = Rn; 2053 let Inst{4-0} = Rd; 2054 2055 let DecoderMethod = "DecodeLogicalImmInstruction"; 2056} 2057 2058// Logical (shifted register) 2059class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 2060 logical_shifted_reg shifted_regtype, string asm, 2061 list<dag> pattern> 2062 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 2063 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 2064 Sched<[WriteISReg, ReadI, ReadISReg]> { 2065 // The operands are in order to match the 'addr' MI operands, so we 2066 // don't need an encoder method and by-name matching. Just use the default 2067 // in-order handling. Since we're using by-order, make sure the names 2068 // do not match. 2069 bits<5> dst; 2070 bits<5> src1; 2071 bits<5> src2; 2072 bits<8> shift; 2073 let Inst{30-29} = opc; 2074 let Inst{28-24} = 0b01010; 2075 let Inst{23-22} = shift{7-6}; 2076 let Inst{21} = N; 2077 let Inst{20-16} = src2; 2078 let Inst{15-10} = shift{5-0}; 2079 let Inst{9-5} = src1; 2080 let Inst{4-0} = dst; 2081 2082 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 2083} 2084 2085// Aliases for register+register logical instructions. 2086class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 2087 : InstAlias<asm#"\t$dst, $src1, $src2", 2088 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 2089 2090multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 2091 string Alias> { 2092 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2093 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 2094 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 2095 logical_imm32:$imm))]> { 2096 let Inst{31} = 0; 2097 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2098 } 2099 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 2100 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 2101 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 2102 logical_imm64:$imm))]> { 2103 let Inst{31} = 1; 2104 } 2105 2106 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2107 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 2108 logical_imm32_not:$imm), 0>; 2109 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2110 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 2111 logical_imm64_not:$imm), 0>; 2112} 2113 2114multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 2115 string Alias> { 2116 let isCompare = 1, Defs = [NZCV] in { 2117 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 2118 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 2119 let Inst{31} = 0; 2120 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 2121 } 2122 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 2123 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 2124 let Inst{31} = 1; 2125 } 2126 } // end Defs = [NZCV] 2127 2128 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2129 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2130 logical_imm32_not:$imm), 0>; 2131 def : InstAlias<Alias # "\t$Rd, $Rn, $imm", 2132 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2133 logical_imm64_not:$imm), 0>; 2134} 2135 2136class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2137 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2138 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2139 Sched<[WriteI, ReadI, ReadI]>; 2140 2141// Split from LogicalImm as not all instructions have both. 2142multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2143 SDPatternOperator OpNode> { 2144 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2145 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2146 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2147 } 2148 2149 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2150 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2151 logical_shifted_reg32:$Rm))]> { 2152 let Inst{31} = 0; 2153 } 2154 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2155 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2156 logical_shifted_reg64:$Rm))]> { 2157 let Inst{31} = 1; 2158 } 2159 2160 def : LogicalRegAlias<mnemonic, 2161 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2162 def : LogicalRegAlias<mnemonic, 2163 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2164} 2165 2166// Split from LogicalReg to allow setting NZCV Defs 2167multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2168 SDPatternOperator OpNode = null_frag> { 2169 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2170 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2171 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2172 2173 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2174 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2175 let Inst{31} = 0; 2176 } 2177 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2178 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2179 let Inst{31} = 1; 2180 } 2181 } // Defs = [NZCV] 2182 2183 def : LogicalRegAlias<mnemonic, 2184 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2185 def : LogicalRegAlias<mnemonic, 2186 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2187} 2188 2189//--- 2190// Conditionally set flags 2191//--- 2192 2193let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2194class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype, 2195 string mnemonic, SDNode OpNode> 2196 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond), 2197 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "", 2198 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv), 2199 (i32 imm:$cond), NZCV))]>, 2200 Sched<[WriteI, ReadI]> { 2201 let Uses = [NZCV]; 2202 let Defs = [NZCV]; 2203 2204 bits<5> Rn; 2205 bits<5> imm; 2206 bits<4> nzcv; 2207 bits<4> cond; 2208 2209 let Inst{30} = op; 2210 let Inst{29-21} = 0b111010010; 2211 let Inst{20-16} = imm; 2212 let Inst{15-12} = cond; 2213 let Inst{11-10} = 0b10; 2214 let Inst{9-5} = Rn; 2215 let Inst{4} = 0b0; 2216 let Inst{3-0} = nzcv; 2217} 2218 2219let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2220class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic, 2221 SDNode OpNode> 2222 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 2223 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", 2224 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv), 2225 (i32 imm:$cond), NZCV))]>, 2226 Sched<[WriteI, ReadI, ReadI]> { 2227 let Uses = [NZCV]; 2228 let Defs = [NZCV]; 2229 2230 bits<5> Rn; 2231 bits<5> Rm; 2232 bits<4> nzcv; 2233 bits<4> cond; 2234 2235 let Inst{30} = op; 2236 let Inst{29-21} = 0b111010010; 2237 let Inst{20-16} = Rm; 2238 let Inst{15-12} = cond; 2239 let Inst{11-10} = 0b00; 2240 let Inst{9-5} = Rn; 2241 let Inst{4} = 0b0; 2242 let Inst{3-0} = nzcv; 2243} 2244 2245multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> { 2246 // immediate operand variants 2247 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> { 2248 let Inst{31} = 0; 2249 } 2250 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> { 2251 let Inst{31} = 1; 2252 } 2253 // register operand variants 2254 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> { 2255 let Inst{31} = 0; 2256 } 2257 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> { 2258 let Inst{31} = 1; 2259 } 2260} 2261 2262//--- 2263// Conditional select 2264//--- 2265 2266class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2267 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2268 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2269 [(set regtype:$Rd, 2270 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2271 Sched<[WriteI, ReadI, ReadI]> { 2272 let Uses = [NZCV]; 2273 2274 bits<5> Rd; 2275 bits<5> Rn; 2276 bits<5> Rm; 2277 bits<4> cond; 2278 2279 let Inst{30} = op; 2280 let Inst{29-21} = 0b011010100; 2281 let Inst{20-16} = Rm; 2282 let Inst{15-12} = cond; 2283 let Inst{11-10} = op2; 2284 let Inst{9-5} = Rn; 2285 let Inst{4-0} = Rd; 2286} 2287 2288multiclass CondSelect<bit op, bits<2> op2, string asm> { 2289 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2290 let Inst{31} = 0; 2291 } 2292 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 2293 let Inst{31} = 1; 2294 } 2295} 2296 2297class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 2298 PatFrag frag> 2299 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2300 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2301 [(set regtype:$Rd, 2302 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 2303 (i32 imm:$cond), NZCV))]>, 2304 Sched<[WriteI, ReadI, ReadI]> { 2305 let Uses = [NZCV]; 2306 2307 bits<5> Rd; 2308 bits<5> Rn; 2309 bits<5> Rm; 2310 bits<4> cond; 2311 2312 let Inst{30} = op; 2313 let Inst{29-21} = 0b011010100; 2314 let Inst{20-16} = Rm; 2315 let Inst{15-12} = cond; 2316 let Inst{11-10} = op2; 2317 let Inst{9-5} = Rn; 2318 let Inst{4-0} = Rd; 2319} 2320 2321def inv_cond_XFORM : SDNodeXForm<imm, [{ 2322 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 2323 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N), 2324 MVT::i32); 2325}]>; 2326 2327multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 2328 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 2329 let Inst{31} = 0; 2330 } 2331 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 2332 let Inst{31} = 1; 2333 } 2334 2335 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 2336 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 2337 (inv_cond_XFORM imm:$cond))>; 2338 2339 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 2340 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 2341 (inv_cond_XFORM imm:$cond))>; 2342} 2343 2344//--- 2345// Special Mask Value 2346//--- 2347def maski8_or_more : Operand<i32>, 2348 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 2349} 2350def maski16_or_more : Operand<i32>, 2351 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 2352} 2353 2354 2355//--- 2356// Load/store 2357//--- 2358 2359// (unsigned immediate) 2360// Indexed for 8-bit registers. offset is in range [0,4095]. 2361def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 2362def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 2363def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 2364def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 2365def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 2366 2367class UImm12OffsetOperand<int Scale> : AsmOperandClass { 2368 let Name = "UImm12Offset" # Scale; 2369 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 2370 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 2371 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 2372} 2373 2374def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 2375def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 2376def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 2377def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 2378def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 2379 2380class uimm12_scaled<int Scale> : Operand<i64> { 2381 let ParserMatchClass 2382 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 2383 let EncoderMethod 2384 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 2385 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 2386} 2387 2388def uimm12s1 : uimm12_scaled<1>; 2389def uimm12s2 : uimm12_scaled<2>; 2390def uimm12s4 : uimm12_scaled<4>; 2391def uimm12s8 : uimm12_scaled<8>; 2392def uimm12s16 : uimm12_scaled<16>; 2393 2394class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2395 string asm, list<dag> pattern> 2396 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 2397 bits<5> Rt; 2398 2399 bits<5> Rn; 2400 bits<12> offset; 2401 2402 let Inst{31-30} = sz; 2403 let Inst{29-27} = 0b111; 2404 let Inst{26} = V; 2405 let Inst{25-24} = 0b01; 2406 let Inst{23-22} = opc; 2407 let Inst{21-10} = offset; 2408 let Inst{9-5} = Rn; 2409 let Inst{4-0} = Rt; 2410 2411 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 2412} 2413 2414multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2415 Operand indextype, string asm, list<dag> pattern> { 2416 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2417 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 2418 (ins GPR64sp:$Rn, indextype:$offset), 2419 asm, pattern>, 2420 Sched<[WriteLD]>; 2421 2422 def : InstAlias<asm # "\t$Rt, [$Rn]", 2423 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2424} 2425 2426multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2427 Operand indextype, string asm, list<dag> pattern> { 2428 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2429 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 2430 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 2431 asm, pattern>, 2432 Sched<[WriteST]>; 2433 2434 def : InstAlias<asm # "\t$Rt, [$Rn]", 2435 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2436} 2437 2438def PrefetchOperand : AsmOperandClass { 2439 let Name = "Prefetch"; 2440 let ParserMethod = "tryParsePrefetch"; 2441} 2442def prfop : Operand<i32> { 2443 let PrintMethod = "printPrefetchOp"; 2444 let ParserMatchClass = PrefetchOperand; 2445} 2446 2447let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2448class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 2449 : BaseLoadStoreUI<sz, V, opc, 2450 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 2451 asm, pat>, 2452 Sched<[WriteLD]>; 2453 2454//--- 2455// Load literal 2456//--- 2457 2458// Load literal address: 19-bit immediate. The low two bits of the target 2459// offset are implied zero and so are not part of the immediate. 2460def am_ldrlit : Operand<OtherVT> { 2461 let EncoderMethod = "getLoadLiteralOpValue"; 2462 let DecoderMethod = "DecodePCRelLabel19"; 2463 let PrintMethod = "printAlignedLabel"; 2464 let ParserMatchClass = PCRelLabel19Operand; 2465} 2466 2467let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2468class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm> 2469 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 2470 asm, "\t$Rt, $label", "", []>, 2471 Sched<[WriteLD]> { 2472 bits<5> Rt; 2473 bits<19> label; 2474 let Inst{31-30} = opc; 2475 let Inst{29-27} = 0b011; 2476 let Inst{26} = V; 2477 let Inst{25-24} = 0b00; 2478 let Inst{23-5} = label; 2479 let Inst{4-0} = Rt; 2480} 2481 2482let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2483class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 2484 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 2485 asm, "\t$Rt, $label", "", pat>, 2486 Sched<[WriteLD]> { 2487 bits<5> Rt; 2488 bits<19> label; 2489 let Inst{31-30} = opc; 2490 let Inst{29-27} = 0b011; 2491 let Inst{26} = V; 2492 let Inst{25-24} = 0b00; 2493 let Inst{23-5} = label; 2494 let Inst{4-0} = Rt; 2495} 2496 2497//--- 2498// Load/store register offset 2499//--- 2500 2501def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 2502def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 2503def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 2504def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 2505def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 2506 2507def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 2508def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 2509def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 2510def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 2511def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 2512 2513class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 2514 let Name = "Mem" # Reg # "Extend" # Width; 2515 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 2516 let RenderMethod = "addMemExtendOperands"; 2517 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 2518} 2519 2520def MemWExtend8Operand : MemExtendOperand<"W", 8> { 2521 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 2522 // the trivial shift. 2523 let RenderMethod = "addMemExtend8Operands"; 2524} 2525def MemWExtend16Operand : MemExtendOperand<"W", 16>; 2526def MemWExtend32Operand : MemExtendOperand<"W", 32>; 2527def MemWExtend64Operand : MemExtendOperand<"W", 64>; 2528def MemWExtend128Operand : MemExtendOperand<"W", 128>; 2529 2530def MemXExtend8Operand : MemExtendOperand<"X", 8> { 2531 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 2532 // the trivial shift. 2533 let RenderMethod = "addMemExtend8Operands"; 2534} 2535def MemXExtend16Operand : MemExtendOperand<"X", 16>; 2536def MemXExtend32Operand : MemExtendOperand<"X", 32>; 2537def MemXExtend64Operand : MemExtendOperand<"X", 64>; 2538def MemXExtend128Operand : MemExtendOperand<"X", 128>; 2539 2540class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 2541 : Operand<i32> { 2542 let ParserMatchClass = ParserClass; 2543 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 2544 let DecoderMethod = "DecodeMemExtend"; 2545 let EncoderMethod = "getMemExtendOpValue"; 2546 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 2547} 2548 2549def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 2550def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 2551def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 2552def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 2553def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 2554 2555def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 2556def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 2557def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 2558def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 2559def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 2560 2561class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 2562 Operand wextend, Operand xextend> { 2563 // CodeGen-level pattern covering the entire addressing mode. 2564 ComplexPattern Wpat = windex; 2565 ComplexPattern Xpat = xindex; 2566 2567 // Asm-level Operand covering the valid "uxtw #3" style syntax. 2568 Operand Wext = wextend; 2569 Operand Xext = xextend; 2570} 2571 2572def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 2573def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 2574def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 2575def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 2576def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 2577 ro_Xextend128>; 2578 2579class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2580 string asm, dag ins, dag outs, list<dag> pat> 2581 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2582 bits<5> Rt; 2583 bits<5> Rn; 2584 bits<5> Rm; 2585 bits<2> extend; 2586 let Inst{31-30} = sz; 2587 let Inst{29-27} = 0b111; 2588 let Inst{26} = V; 2589 let Inst{25-24} = 0b00; 2590 let Inst{23-22} = opc; 2591 let Inst{21} = 1; 2592 let Inst{20-16} = Rm; 2593 let Inst{15} = extend{1}; // sign extend Rm? 2594 let Inst{14} = 1; 2595 let Inst{12} = extend{0}; // do shift? 2596 let Inst{11-10} = 0b10; 2597 let Inst{9-5} = Rn; 2598 let Inst{4-0} = Rt; 2599} 2600 2601class ROInstAlias<string asm, RegisterClass regtype, Instruction INST> 2602 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]", 2603 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 2604 2605multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2606 string asm, ValueType Ty, SDPatternOperator loadop> { 2607 let AddedComplexity = 10 in 2608 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 2609 (outs regtype:$Rt), 2610 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 2611 [(set (Ty regtype:$Rt), 2612 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 2613 ro_Wextend8:$extend)))]>, 2614 Sched<[WriteLDIdx, ReadAdrBase]> { 2615 let Inst{13} = 0b0; 2616 } 2617 2618 let AddedComplexity = 10 in 2619 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 2620 (outs regtype:$Rt), 2621 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 2622 [(set (Ty regtype:$Rt), 2623 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 2624 ro_Xextend8:$extend)))]>, 2625 Sched<[WriteLDIdx, ReadAdrBase]> { 2626 let Inst{13} = 0b1; 2627 } 2628 2629 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2630} 2631 2632multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2633 string asm, ValueType Ty, SDPatternOperator storeop> { 2634 let AddedComplexity = 10 in 2635 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 2636 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 2637 [(storeop (Ty regtype:$Rt), 2638 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 2639 ro_Wextend8:$extend))]>, 2640 Sched<[WriteSTIdx, ReadAdrBase]> { 2641 let Inst{13} = 0b0; 2642 } 2643 2644 let AddedComplexity = 10 in 2645 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 2646 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 2647 [(storeop (Ty regtype:$Rt), 2648 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 2649 ro_Xextend8:$extend))]>, 2650 Sched<[WriteSTIdx, ReadAdrBase]> { 2651 let Inst{13} = 0b1; 2652 } 2653 2654 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2655} 2656 2657class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2658 string asm, dag ins, dag outs, list<dag> pat> 2659 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2660 bits<5> Rt; 2661 bits<5> Rn; 2662 bits<5> Rm; 2663 bits<2> extend; 2664 let Inst{31-30} = sz; 2665 let Inst{29-27} = 0b111; 2666 let Inst{26} = V; 2667 let Inst{25-24} = 0b00; 2668 let Inst{23-22} = opc; 2669 let Inst{21} = 1; 2670 let Inst{20-16} = Rm; 2671 let Inst{15} = extend{1}; // sign extend Rm? 2672 let Inst{14} = 1; 2673 let Inst{12} = extend{0}; // do shift? 2674 let Inst{11-10} = 0b10; 2675 let Inst{9-5} = Rn; 2676 let Inst{4-0} = Rt; 2677} 2678 2679multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2680 string asm, ValueType Ty, SDPatternOperator loadop> { 2681 let AddedComplexity = 10 in 2682 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2683 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 2684 [(set (Ty regtype:$Rt), 2685 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 2686 ro_Wextend16:$extend)))]>, 2687 Sched<[WriteLDIdx, ReadAdrBase]> { 2688 let Inst{13} = 0b0; 2689 } 2690 2691 let AddedComplexity = 10 in 2692 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2693 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 2694 [(set (Ty regtype:$Rt), 2695 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 2696 ro_Xextend16:$extend)))]>, 2697 Sched<[WriteLDIdx, ReadAdrBase]> { 2698 let Inst{13} = 0b1; 2699 } 2700 2701 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2702} 2703 2704multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2705 string asm, ValueType Ty, SDPatternOperator storeop> { 2706 let AddedComplexity = 10 in 2707 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 2708 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 2709 [(storeop (Ty regtype:$Rt), 2710 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 2711 ro_Wextend16:$extend))]>, 2712 Sched<[WriteSTIdx, ReadAdrBase]> { 2713 let Inst{13} = 0b0; 2714 } 2715 2716 let AddedComplexity = 10 in 2717 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 2718 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 2719 [(storeop (Ty regtype:$Rt), 2720 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 2721 ro_Xextend16:$extend))]>, 2722 Sched<[WriteSTIdx, ReadAdrBase]> { 2723 let Inst{13} = 0b1; 2724 } 2725 2726 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2727} 2728 2729class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2730 string asm, dag ins, dag outs, list<dag> pat> 2731 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2732 bits<5> Rt; 2733 bits<5> Rn; 2734 bits<5> Rm; 2735 bits<2> extend; 2736 let Inst{31-30} = sz; 2737 let Inst{29-27} = 0b111; 2738 let Inst{26} = V; 2739 let Inst{25-24} = 0b00; 2740 let Inst{23-22} = opc; 2741 let Inst{21} = 1; 2742 let Inst{20-16} = Rm; 2743 let Inst{15} = extend{1}; // sign extend Rm? 2744 let Inst{14} = 1; 2745 let Inst{12} = extend{0}; // do shift? 2746 let Inst{11-10} = 0b10; 2747 let Inst{9-5} = Rn; 2748 let Inst{4-0} = Rt; 2749} 2750 2751multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2752 string asm, ValueType Ty, SDPatternOperator loadop> { 2753 let AddedComplexity = 10 in 2754 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2755 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 2756 [(set (Ty regtype:$Rt), 2757 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 2758 ro_Wextend32:$extend)))]>, 2759 Sched<[WriteLDIdx, ReadAdrBase]> { 2760 let Inst{13} = 0b0; 2761 } 2762 2763 let AddedComplexity = 10 in 2764 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2765 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 2766 [(set (Ty regtype:$Rt), 2767 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 2768 ro_Xextend32:$extend)))]>, 2769 Sched<[WriteLDIdx, ReadAdrBase]> { 2770 let Inst{13} = 0b1; 2771 } 2772 2773 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2774} 2775 2776multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2777 string asm, ValueType Ty, SDPatternOperator storeop> { 2778 let AddedComplexity = 10 in 2779 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 2780 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 2781 [(storeop (Ty regtype:$Rt), 2782 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 2783 ro_Wextend32:$extend))]>, 2784 Sched<[WriteSTIdx, ReadAdrBase]> { 2785 let Inst{13} = 0b0; 2786 } 2787 2788 let AddedComplexity = 10 in 2789 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 2790 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 2791 [(storeop (Ty regtype:$Rt), 2792 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 2793 ro_Xextend32:$extend))]>, 2794 Sched<[WriteSTIdx, ReadAdrBase]> { 2795 let Inst{13} = 0b1; 2796 } 2797 2798 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2799} 2800 2801class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2802 string asm, dag ins, dag outs, list<dag> pat> 2803 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2804 bits<5> Rt; 2805 bits<5> Rn; 2806 bits<5> Rm; 2807 bits<2> extend; 2808 let Inst{31-30} = sz; 2809 let Inst{29-27} = 0b111; 2810 let Inst{26} = V; 2811 let Inst{25-24} = 0b00; 2812 let Inst{23-22} = opc; 2813 let Inst{21} = 1; 2814 let Inst{20-16} = Rm; 2815 let Inst{15} = extend{1}; // sign extend Rm? 2816 let Inst{14} = 1; 2817 let Inst{12} = extend{0}; // do shift? 2818 let Inst{11-10} = 0b10; 2819 let Inst{9-5} = Rn; 2820 let Inst{4-0} = Rt; 2821} 2822 2823multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2824 string asm, ValueType Ty, SDPatternOperator loadop> { 2825 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2826 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2827 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2828 [(set (Ty regtype:$Rt), 2829 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2830 ro_Wextend64:$extend)))]>, 2831 Sched<[WriteLDIdx, ReadAdrBase]> { 2832 let Inst{13} = 0b0; 2833 } 2834 2835 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2836 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2837 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2838 [(set (Ty regtype:$Rt), 2839 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2840 ro_Xextend64:$extend)))]>, 2841 Sched<[WriteLDIdx, ReadAdrBase]> { 2842 let Inst{13} = 0b1; 2843 } 2844 2845 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2846} 2847 2848multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2849 string asm, ValueType Ty, SDPatternOperator storeop> { 2850 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2851 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 2852 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2853 [(storeop (Ty regtype:$Rt), 2854 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2855 ro_Wextend64:$extend))]>, 2856 Sched<[WriteSTIdx, ReadAdrBase]> { 2857 let Inst{13} = 0b0; 2858 } 2859 2860 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2861 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 2862 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2863 [(storeop (Ty regtype:$Rt), 2864 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2865 ro_Xextend64:$extend))]>, 2866 Sched<[WriteSTIdx, ReadAdrBase]> { 2867 let Inst{13} = 0b1; 2868 } 2869 2870 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2871} 2872 2873class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2874 string asm, dag ins, dag outs, list<dag> pat> 2875 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2876 bits<5> Rt; 2877 bits<5> Rn; 2878 bits<5> Rm; 2879 bits<2> extend; 2880 let Inst{31-30} = sz; 2881 let Inst{29-27} = 0b111; 2882 let Inst{26} = V; 2883 let Inst{25-24} = 0b00; 2884 let Inst{23-22} = opc; 2885 let Inst{21} = 1; 2886 let Inst{20-16} = Rm; 2887 let Inst{15} = extend{1}; // sign extend Rm? 2888 let Inst{14} = 1; 2889 let Inst{12} = extend{0}; // do shift? 2890 let Inst{11-10} = 0b10; 2891 let Inst{9-5} = Rn; 2892 let Inst{4-0} = Rt; 2893} 2894 2895multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2896 string asm, ValueType Ty, SDPatternOperator loadop> { 2897 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2898 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2899 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 2900 [(set (Ty regtype:$Rt), 2901 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 2902 ro_Wextend128:$extend)))]>, 2903 Sched<[WriteLDIdx, ReadAdrBase]> { 2904 let Inst{13} = 0b0; 2905 } 2906 2907 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2908 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2909 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 2910 [(set (Ty regtype:$Rt), 2911 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 2912 ro_Xextend128:$extend)))]>, 2913 Sched<[WriteLDIdx, ReadAdrBase]> { 2914 let Inst{13} = 0b1; 2915 } 2916 2917 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2918} 2919 2920multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2921 string asm, ValueType Ty, SDPatternOperator storeop> { 2922 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2923 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 2924 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 2925 [(storeop (Ty regtype:$Rt), 2926 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 2927 ro_Wextend128:$extend))]>, 2928 Sched<[WriteSTIdx, ReadAdrBase]> { 2929 let Inst{13} = 0b0; 2930 } 2931 2932 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2933 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 2934 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 2935 [(storeop (Ty regtype:$Rt), 2936 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 2937 ro_Xextend128:$extend))]>, 2938 Sched<[WriteSTIdx, ReadAdrBase]> { 2939 let Inst{13} = 0b1; 2940 } 2941 2942 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2943} 2944 2945let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2946class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 2947 string asm, list<dag> pat> 2948 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 2949 Sched<[WriteLD]> { 2950 bits<5> Rt; 2951 bits<5> Rn; 2952 bits<5> Rm; 2953 bits<2> extend; 2954 let Inst{31-30} = sz; 2955 let Inst{29-27} = 0b111; 2956 let Inst{26} = V; 2957 let Inst{25-24} = 0b00; 2958 let Inst{23-22} = opc; 2959 let Inst{21} = 1; 2960 let Inst{20-16} = Rm; 2961 let Inst{15} = extend{1}; // sign extend Rm? 2962 let Inst{14} = 1; 2963 let Inst{12} = extend{0}; // do shift? 2964 let Inst{11-10} = 0b10; 2965 let Inst{9-5} = Rn; 2966 let Inst{4-0} = Rt; 2967} 2968 2969multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 2970 def roW : BasePrefetchRO<sz, V, opc, (outs), 2971 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2972 asm, [(AArch64Prefetch imm:$Rt, 2973 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2974 ro_Wextend64:$extend))]> { 2975 let Inst{13} = 0b0; 2976 } 2977 2978 def roX : BasePrefetchRO<sz, V, opc, (outs), 2979 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2980 asm, [(AArch64Prefetch imm:$Rt, 2981 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2982 ro_Xextend64:$extend))]> { 2983 let Inst{13} = 0b1; 2984 } 2985 2986 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 2987 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 2988 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 2989} 2990 2991//--- 2992// Load/store unscaled immediate 2993//--- 2994 2995def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 2996def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 2997def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 2998def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 2999def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 3000 3001class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3002 string asm, list<dag> pattern> 3003 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 3004 bits<5> Rt; 3005 bits<5> Rn; 3006 bits<9> offset; 3007 let Inst{31-30} = sz; 3008 let Inst{29-27} = 0b111; 3009 let Inst{26} = V; 3010 let Inst{25-24} = 0b00; 3011 let Inst{23-22} = opc; 3012 let Inst{21} = 0; 3013 let Inst{20-12} = offset; 3014 let Inst{11-10} = 0b00; 3015 let Inst{9-5} = Rn; 3016 let Inst{4-0} = Rt; 3017 3018 let DecoderMethod = "DecodeSignedLdStInstruction"; 3019} 3020 3021multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3022 string asm, list<dag> pattern> { 3023 let AddedComplexity = 1 in // try this before LoadUI 3024 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 3025 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 3026 Sched<[WriteLD]>; 3027 3028 def : InstAlias<asm # "\t$Rt, [$Rn]", 3029 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3030} 3031 3032multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3033 string asm, list<dag> pattern> { 3034 let AddedComplexity = 1 in // try this before StoreUI 3035 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3036 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3037 asm, pattern>, 3038 Sched<[WriteST]>; 3039 3040 def : InstAlias<asm # "\t$Rt, [$Rn]", 3041 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3042} 3043 3044multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 3045 list<dag> pat> { 3046 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3047 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 3048 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 3049 asm, pat>, 3050 Sched<[WriteLD]>; 3051 3052 def : InstAlias<asm # "\t$Rt, [$Rn]", 3053 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 3054} 3055 3056//--- 3057// Load/store unscaled immediate, unprivileged 3058//--- 3059 3060class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3061 dag oops, dag iops, string asm> 3062 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 3063 bits<5> Rt; 3064 bits<5> Rn; 3065 bits<9> offset; 3066 let Inst{31-30} = sz; 3067 let Inst{29-27} = 0b111; 3068 let Inst{26} = V; 3069 let Inst{25-24} = 0b00; 3070 let Inst{23-22} = opc; 3071 let Inst{21} = 0; 3072 let Inst{20-12} = offset; 3073 let Inst{11-10} = 0b10; 3074 let Inst{9-5} = Rn; 3075 let Inst{4-0} = Rt; 3076 3077 let DecoderMethod = "DecodeSignedLdStInstruction"; 3078} 3079 3080multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 3081 RegisterClass regtype, string asm> { 3082 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 3083 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 3084 (ins GPR64sp:$Rn, simm9:$offset), asm>, 3085 Sched<[WriteLD]>; 3086 3087 def : InstAlias<asm # "\t$Rt, [$Rn]", 3088 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3089} 3090 3091multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 3092 RegisterClass regtype, string asm> { 3093 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 3094 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 3095 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3096 asm>, 3097 Sched<[WriteST]>; 3098 3099 def : InstAlias<asm # "\t$Rt, [$Rn]", 3100 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 3101} 3102 3103//--- 3104// Load/store pre-indexed 3105//--- 3106 3107class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3108 string asm, string cstr, list<dag> pat> 3109 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 3110 bits<5> Rt; 3111 bits<5> Rn; 3112 bits<9> offset; 3113 let Inst{31-30} = sz; 3114 let Inst{29-27} = 0b111; 3115 let Inst{26} = V; 3116 let Inst{25-24} = 0; 3117 let Inst{23-22} = opc; 3118 let Inst{21} = 0; 3119 let Inst{20-12} = offset; 3120 let Inst{11-10} = 0b11; 3121 let Inst{9-5} = Rn; 3122 let Inst{4-0} = Rt; 3123 3124 let DecoderMethod = "DecodeSignedLdStInstruction"; 3125} 3126 3127let hasSideEffects = 0 in { 3128let mayStore = 0, mayLoad = 1 in 3129class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3130 string asm> 3131 : BaseLoadStorePreIdx<sz, V, opc, 3132 (outs GPR64sp:$wback, regtype:$Rt), 3133 (ins GPR64sp:$Rn, simm9:$offset), asm, 3134 "$Rn = $wback,@earlyclobber $wback", []>, 3135 Sched<[WriteLD, WriteAdr]>; 3136 3137let mayStore = 1, mayLoad = 0 in 3138class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3139 string asm, SDPatternOperator storeop, ValueType Ty> 3140 : BaseLoadStorePreIdx<sz, V, opc, 3141 (outs GPR64sp:$wback), 3142 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3143 asm, "$Rn = $wback,@earlyclobber $wback", 3144 [(set GPR64sp:$wback, 3145 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3146 Sched<[WriteAdr, WriteST]>; 3147} // hasSideEffects = 0 3148 3149//--- 3150// Load/store post-indexed 3151//--- 3152 3153class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3154 string asm, string cstr, list<dag> pat> 3155 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3156 bits<5> Rt; 3157 bits<5> Rn; 3158 bits<9> offset; 3159 let Inst{31-30} = sz; 3160 let Inst{29-27} = 0b111; 3161 let Inst{26} = V; 3162 let Inst{25-24} = 0b00; 3163 let Inst{23-22} = opc; 3164 let Inst{21} = 0b0; 3165 let Inst{20-12} = offset; 3166 let Inst{11-10} = 0b01; 3167 let Inst{9-5} = Rn; 3168 let Inst{4-0} = Rt; 3169 3170 let DecoderMethod = "DecodeSignedLdStInstruction"; 3171} 3172 3173let hasSideEffects = 0 in { 3174let mayStore = 0, mayLoad = 1 in 3175class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3176 string asm> 3177 : BaseLoadStorePostIdx<sz, V, opc, 3178 (outs GPR64sp:$wback, regtype:$Rt), 3179 (ins GPR64sp:$Rn, simm9:$offset), 3180 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3181 Sched<[WriteLD, WriteI]>; 3182 3183let mayStore = 1, mayLoad = 0 in 3184class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3185 string asm, SDPatternOperator storeop, ValueType Ty> 3186 : BaseLoadStorePostIdx<sz, V, opc, 3187 (outs GPR64sp:$wback), 3188 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3189 asm, "$Rn = $wback,@earlyclobber $wback", 3190 [(set GPR64sp:$wback, 3191 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3192 Sched<[WriteAdr, WriteST, ReadAdrBase]>; 3193} // hasSideEffects = 0 3194 3195 3196//--- 3197// Load/store pair 3198//--- 3199 3200// (indexed, offset) 3201 3202class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 3203 string asm> 3204 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3205 bits<5> Rt; 3206 bits<5> Rt2; 3207 bits<5> Rn; 3208 bits<7> offset; 3209 let Inst{31-30} = opc; 3210 let Inst{29-27} = 0b101; 3211 let Inst{26} = V; 3212 let Inst{25-23} = 0b010; 3213 let Inst{22} = L; 3214 let Inst{21-15} = offset; 3215 let Inst{14-10} = Rt2; 3216 let Inst{9-5} = Rn; 3217 let Inst{4-0} = Rt; 3218 3219 let DecoderMethod = "DecodePairLdStInstruction"; 3220} 3221 3222multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype, 3223 Operand indextype, string asm> { 3224 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3225 def i : BaseLoadStorePairOffset<opc, V, 1, 3226 (outs regtype:$Rt, regtype:$Rt2), 3227 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3228 Sched<[WriteLD, WriteLDHi]>; 3229 3230 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3231 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3232 GPR64sp:$Rn, 0)>; 3233} 3234 3235 3236multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype, 3237 Operand indextype, string asm> { 3238 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 3239 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 3240 (ins regtype:$Rt, regtype:$Rt2, 3241 GPR64sp:$Rn, indextype:$offset), 3242 asm>, 3243 Sched<[WriteSTP]>; 3244 3245 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3246 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3247 GPR64sp:$Rn, 0)>; 3248} 3249 3250// (pre-indexed) 3251class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3252 string asm> 3253 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 3254 bits<5> Rt; 3255 bits<5> Rt2; 3256 bits<5> Rn; 3257 bits<7> offset; 3258 let Inst{31-30} = opc; 3259 let Inst{29-27} = 0b101; 3260 let Inst{26} = V; 3261 let Inst{25-23} = 0b011; 3262 let Inst{22} = L; 3263 let Inst{21-15} = offset; 3264 let Inst{14-10} = Rt2; 3265 let Inst{9-5} = Rn; 3266 let Inst{4-0} = Rt; 3267 3268 let DecoderMethod = "DecodePairLdStInstruction"; 3269} 3270 3271let hasSideEffects = 0 in { 3272let mayStore = 0, mayLoad = 1 in 3273class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype, 3274 Operand indextype, string asm> 3275 : BaseLoadStorePairPreIdx<opc, V, 1, 3276 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3277 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3278 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3279 3280let mayStore = 1, mayLoad = 0 in 3281class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype, 3282 Operand indextype, string asm> 3283 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 3284 (ins regtype:$Rt, regtype:$Rt2, 3285 GPR64sp:$Rn, indextype:$offset), 3286 asm>, 3287 Sched<[WriteAdr, WriteSTP]>; 3288} // hasSideEffects = 0 3289 3290// (post-indexed) 3291 3292class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3293 string asm> 3294 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 3295 bits<5> Rt; 3296 bits<5> Rt2; 3297 bits<5> Rn; 3298 bits<7> offset; 3299 let Inst{31-30} = opc; 3300 let Inst{29-27} = 0b101; 3301 let Inst{26} = V; 3302 let Inst{25-23} = 0b001; 3303 let Inst{22} = L; 3304 let Inst{21-15} = offset; 3305 let Inst{14-10} = Rt2; 3306 let Inst{9-5} = Rn; 3307 let Inst{4-0} = Rt; 3308 3309 let DecoderMethod = "DecodePairLdStInstruction"; 3310} 3311 3312let hasSideEffects = 0 in { 3313let mayStore = 0, mayLoad = 1 in 3314class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype, 3315 Operand idxtype, string asm> 3316 : BaseLoadStorePairPostIdx<opc, V, 1, 3317 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3318 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 3319 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3320 3321let mayStore = 1, mayLoad = 0 in 3322class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype, 3323 Operand idxtype, string asm> 3324 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback), 3325 (ins regtype:$Rt, regtype:$Rt2, 3326 GPR64sp:$Rn, idxtype:$offset), 3327 asm>, 3328 Sched<[WriteAdr, WriteSTP]>; 3329} // hasSideEffects = 0 3330 3331// (no-allocate) 3332 3333class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 3334 string asm> 3335 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3336 bits<5> Rt; 3337 bits<5> Rt2; 3338 bits<5> Rn; 3339 bits<7> offset; 3340 let Inst{31-30} = opc; 3341 let Inst{29-27} = 0b101; 3342 let Inst{26} = V; 3343 let Inst{25-23} = 0b000; 3344 let Inst{22} = L; 3345 let Inst{21-15} = offset; 3346 let Inst{14-10} = Rt2; 3347 let Inst{9-5} = Rn; 3348 let Inst{4-0} = Rt; 3349 3350 let DecoderMethod = "DecodePairLdStInstruction"; 3351} 3352 3353multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3354 Operand indextype, string asm> { 3355 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3356 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 3357 (outs regtype:$Rt, regtype:$Rt2), 3358 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3359 Sched<[WriteLD, WriteLDHi]>; 3360 3361 3362 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3363 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3364 GPR64sp:$Rn, 0)>; 3365} 3366 3367multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3368 Operand indextype, string asm> { 3369 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 3370 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 3371 (ins regtype:$Rt, regtype:$Rt2, 3372 GPR64sp:$Rn, indextype:$offset), 3373 asm>, 3374 Sched<[WriteSTP]>; 3375 3376 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3377 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3378 GPR64sp:$Rn, 0)>; 3379} 3380 3381//--- 3382// Load/store exclusive 3383//--- 3384 3385// True exclusive operations write to and/or read from the system's exclusive 3386// monitors, which as far as a compiler is concerned can be modelled as a 3387// random shared memory address. Hence LoadExclusive mayStore. 3388// 3389// Since these instructions have the undefined register bits set to 1 in 3390// their canonical form, we need a post encoder method to set those bits 3391// to 1 when encoding these instructions. We do this using the 3392// fixLoadStoreExclusive function. This function has template parameters: 3393// 3394// fixLoadStoreExclusive<int hasRs, int hasRt2> 3395// 3396// hasRs indicates that the instruction uses the Rs field, so we won't set 3397// it to 1 (and the same for Rt2). We don't need template parameters for 3398// the other register fields since Rt and Rn are always used. 3399// 3400let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 3401class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3402 dag oops, dag iops, string asm, string operands> 3403 : I<oops, iops, asm, operands, "", []> { 3404 let Inst{31-30} = sz; 3405 let Inst{29-24} = 0b001000; 3406 let Inst{23} = o2; 3407 let Inst{22} = L; 3408 let Inst{21} = o1; 3409 let Inst{15} = o0; 3410 3411 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 3412} 3413 3414// Neither Rs nor Rt2 operands. 3415class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3416 dag oops, dag iops, string asm, string operands> 3417 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 3418 bits<5> Rt; 3419 bits<5> Rn; 3420 let Inst{20-16} = 0b11111; 3421 let Unpredictable{20-16} = 0b11111; 3422 let Inst{14-10} = 0b11111; 3423 let Unpredictable{14-10} = 0b11111; 3424 let Inst{9-5} = Rn; 3425 let Inst{4-0} = Rt; 3426 3427 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 3428} 3429 3430// Simple load acquires don't set the exclusive monitor 3431let mayLoad = 1, mayStore = 0 in 3432class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3433 RegisterClass regtype, string asm> 3434 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 3435 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 3436 Sched<[WriteLD]>; 3437 3438class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3439 RegisterClass regtype, string asm> 3440 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 3441 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 3442 Sched<[WriteLD]>; 3443 3444class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3445 RegisterClass regtype, string asm> 3446 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 3447 (outs regtype:$Rt, regtype:$Rt2), 3448 (ins GPR64sp0:$Rn), asm, 3449 "\t$Rt, $Rt2, [$Rn]">, 3450 Sched<[WriteLD, WriteLDHi]> { 3451 bits<5> Rt; 3452 bits<5> Rt2; 3453 bits<5> Rn; 3454 let Inst{14-10} = Rt2; 3455 let Inst{9-5} = Rn; 3456 let Inst{4-0} = Rt; 3457 3458 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 3459} 3460 3461// Simple store release operations do not check the exclusive monitor. 3462let mayLoad = 0, mayStore = 1 in 3463class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3464 RegisterClass regtype, string asm> 3465 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 3466 (ins regtype:$Rt, GPR64sp0:$Rn), 3467 asm, "\t$Rt, [$Rn]">, 3468 Sched<[WriteST]>; 3469 3470let mayLoad = 1, mayStore = 1 in 3471class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3472 RegisterClass regtype, string asm> 3473 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 3474 (ins regtype:$Rt, GPR64sp0:$Rn), 3475 asm, "\t$Ws, $Rt, [$Rn]">, 3476 Sched<[WriteSTX]> { 3477 bits<5> Ws; 3478 bits<5> Rt; 3479 bits<5> Rn; 3480 let Inst{20-16} = Ws; 3481 let Inst{9-5} = Rn; 3482 let Inst{4-0} = Rt; 3483 3484 let Constraints = "@earlyclobber $Ws"; 3485 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 3486} 3487 3488class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3489 RegisterClass regtype, string asm> 3490 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 3491 (outs GPR32:$Ws), 3492 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 3493 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 3494 Sched<[WriteSTX]> { 3495 bits<5> Ws; 3496 bits<5> Rt; 3497 bits<5> Rt2; 3498 bits<5> Rn; 3499 let Inst{20-16} = Ws; 3500 let Inst{14-10} = Rt2; 3501 let Inst{9-5} = Rn; 3502 let Inst{4-0} = Rt; 3503 3504 let Constraints = "@earlyclobber $Ws"; 3505} 3506 3507//--- 3508// Exception generation 3509//--- 3510 3511let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3512class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 3513 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>, 3514 Sched<[WriteSys]> { 3515 bits<16> imm; 3516 let Inst{31-24} = 0b11010100; 3517 let Inst{23-21} = op1; 3518 let Inst{20-5} = imm; 3519 let Inst{4-2} = 0b000; 3520 let Inst{1-0} = ll; 3521} 3522 3523let Predicates = [HasFPARMv8] in { 3524 3525//--- 3526// Floating point to integer conversion 3527//--- 3528 3529class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 3530 RegisterClass srcType, RegisterClass dstType, 3531 string asm, list<dag> pattern> 3532 : I<(outs dstType:$Rd), (ins srcType:$Rn), 3533 asm, "\t$Rd, $Rn", "", pattern>, 3534 Sched<[WriteFCvt]> { 3535 bits<5> Rd; 3536 bits<5> Rn; 3537 let Inst{30-29} = 0b00; 3538 let Inst{28-24} = 0b11110; 3539 let Inst{23-22} = type; 3540 let Inst{21} = 1; 3541 let Inst{20-19} = rmode; 3542 let Inst{18-16} = opcode; 3543 let Inst{15-10} = 0; 3544 let Inst{9-5} = Rn; 3545 let Inst{4-0} = Rd; 3546} 3547 3548let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3549class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 3550 RegisterClass srcType, RegisterClass dstType, 3551 Operand immType, string asm, list<dag> pattern> 3552 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 3553 asm, "\t$Rd, $Rn, $scale", "", pattern>, 3554 Sched<[WriteFCvt]> { 3555 bits<5> Rd; 3556 bits<5> Rn; 3557 bits<6> scale; 3558 let Inst{30-29} = 0b00; 3559 let Inst{28-24} = 0b11110; 3560 let Inst{23-22} = type; 3561 let Inst{21} = 0; 3562 let Inst{20-19} = rmode; 3563 let Inst{18-16} = opcode; 3564 let Inst{15-10} = scale; 3565 let Inst{9-5} = Rn; 3566 let Inst{4-0} = Rd; 3567} 3568 3569multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 3570 SDPatternOperator OpN> { 3571 // Unscaled half-precision to 32-bit 3572 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm, 3573 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> { 3574 let Inst{31} = 0; // 32-bit GPR flag 3575 let Predicates = [HasFullFP16]; 3576 } 3577 3578 // Unscaled half-precision to 64-bit 3579 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm, 3580 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> { 3581 let Inst{31} = 1; // 64-bit GPR flag 3582 let Predicates = [HasFullFP16]; 3583 } 3584 3585 // Unscaled single-precision to 32-bit 3586 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 3587 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 3588 let Inst{31} = 0; // 32-bit GPR flag 3589 } 3590 3591 // Unscaled single-precision to 64-bit 3592 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 3593 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 3594 let Inst{31} = 1; // 64-bit GPR flag 3595 } 3596 3597 // Unscaled double-precision to 32-bit 3598 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 3599 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 3600 let Inst{31} = 0; // 32-bit GPR flag 3601 } 3602 3603 // Unscaled double-precision to 64-bit 3604 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 3605 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 3606 let Inst{31} = 1; // 64-bit GPR flag 3607 } 3608} 3609 3610multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 3611 SDPatternOperator OpN> { 3612 // Scaled half-precision to 32-bit 3613 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32, 3614 fixedpoint_f16_i32, asm, 3615 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn, 3616 fixedpoint_f16_i32:$scale)))]> { 3617 let Inst{31} = 0; // 32-bit GPR flag 3618 let scale{5} = 1; 3619 let Predicates = [HasFullFP16]; 3620 } 3621 3622 // Scaled half-precision to 64-bit 3623 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64, 3624 fixedpoint_f16_i64, asm, 3625 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn, 3626 fixedpoint_f16_i64:$scale)))]> { 3627 let Inst{31} = 1; // 64-bit GPR flag 3628 let Predicates = [HasFullFP16]; 3629 } 3630 3631 // Scaled single-precision to 32-bit 3632 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 3633 fixedpoint_f32_i32, asm, 3634 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 3635 fixedpoint_f32_i32:$scale)))]> { 3636 let Inst{31} = 0; // 32-bit GPR flag 3637 let scale{5} = 1; 3638 } 3639 3640 // Scaled single-precision to 64-bit 3641 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 3642 fixedpoint_f32_i64, asm, 3643 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 3644 fixedpoint_f32_i64:$scale)))]> { 3645 let Inst{31} = 1; // 64-bit GPR flag 3646 } 3647 3648 // Scaled double-precision to 32-bit 3649 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 3650 fixedpoint_f64_i32, asm, 3651 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 3652 fixedpoint_f64_i32:$scale)))]> { 3653 let Inst{31} = 0; // 32-bit GPR flag 3654 let scale{5} = 1; 3655 } 3656 3657 // Scaled double-precision to 64-bit 3658 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 3659 fixedpoint_f64_i64, asm, 3660 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 3661 fixedpoint_f64_i64:$scale)))]> { 3662 let Inst{31} = 1; // 64-bit GPR flag 3663 } 3664} 3665 3666//--- 3667// Integer to floating point conversion 3668//--- 3669 3670let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 3671class BaseIntegerToFP<bit isUnsigned, 3672 RegisterClass srcType, RegisterClass dstType, 3673 Operand immType, string asm, list<dag> pattern> 3674 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 3675 asm, "\t$Rd, $Rn, $scale", "", pattern>, 3676 Sched<[WriteFCvt]> { 3677 bits<5> Rd; 3678 bits<5> Rn; 3679 bits<6> scale; 3680 let Inst{30-24} = 0b0011110; 3681 let Inst{21-17} = 0b00001; 3682 let Inst{16} = isUnsigned; 3683 let Inst{15-10} = scale; 3684 let Inst{9-5} = Rn; 3685 let Inst{4-0} = Rd; 3686} 3687 3688class BaseIntegerToFPUnscaled<bit isUnsigned, 3689 RegisterClass srcType, RegisterClass dstType, 3690 ValueType dvt, string asm, SDNode node> 3691 : I<(outs dstType:$Rd), (ins srcType:$Rn), 3692 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 3693 Sched<[WriteFCvt]> { 3694 bits<5> Rd; 3695 bits<5> Rn; 3696 bits<6> scale; 3697 let Inst{30-24} = 0b0011110; 3698 let Inst{21-17} = 0b10001; 3699 let Inst{16} = isUnsigned; 3700 let Inst{15-10} = 0b000000; 3701 let Inst{9-5} = Rn; 3702 let Inst{4-0} = Rd; 3703} 3704 3705multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 3706 // Unscaled 3707 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> { 3708 let Inst{31} = 0; // 32-bit GPR flag 3709 let Inst{23-22} = 0b11; // 16-bit FPR flag 3710 let Predicates = [HasFullFP16]; 3711 } 3712 3713 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 3714 let Inst{31} = 0; // 32-bit GPR flag 3715 let Inst{23-22} = 0b00; // 32-bit FPR flag 3716 } 3717 3718 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 3719 let Inst{31} = 0; // 32-bit GPR flag 3720 let Inst{23-22} = 0b01; // 64-bit FPR flag 3721 } 3722 3723 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> { 3724 let Inst{31} = 1; // 64-bit GPR flag 3725 let Inst{23-22} = 0b11; // 16-bit FPR flag 3726 let Predicates = [HasFullFP16]; 3727 } 3728 3729 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 3730 let Inst{31} = 1; // 64-bit GPR flag 3731 let Inst{23-22} = 0b00; // 32-bit FPR flag 3732 } 3733 3734 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 3735 let Inst{31} = 1; // 64-bit GPR flag 3736 let Inst{23-22} = 0b01; // 64-bit FPR flag 3737 } 3738 3739 // Scaled 3740 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm, 3741 [(set FPR16:$Rd, 3742 (fdiv (node GPR32:$Rn), 3743 fixedpoint_f16_i32:$scale))]> { 3744 let Inst{31} = 0; // 32-bit GPR flag 3745 let Inst{23-22} = 0b11; // 16-bit FPR flag 3746 let scale{5} = 1; 3747 let Predicates = [HasFullFP16]; 3748 } 3749 3750 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 3751 [(set FPR32:$Rd, 3752 (fdiv (node GPR32:$Rn), 3753 fixedpoint_f32_i32:$scale))]> { 3754 let Inst{31} = 0; // 32-bit GPR flag 3755 let Inst{23-22} = 0b00; // 32-bit FPR flag 3756 let scale{5} = 1; 3757 } 3758 3759 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 3760 [(set FPR64:$Rd, 3761 (fdiv (node GPR32:$Rn), 3762 fixedpoint_f64_i32:$scale))]> { 3763 let Inst{31} = 0; // 32-bit GPR flag 3764 let Inst{23-22} = 0b01; // 64-bit FPR flag 3765 let scale{5} = 1; 3766 } 3767 3768 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm, 3769 [(set FPR16:$Rd, 3770 (fdiv (node GPR64:$Rn), 3771 fixedpoint_f16_i64:$scale))]> { 3772 let Inst{31} = 1; // 64-bit GPR flag 3773 let Inst{23-22} = 0b11; // 16-bit FPR flag 3774 let Predicates = [HasFullFP16]; 3775 } 3776 3777 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 3778 [(set FPR32:$Rd, 3779 (fdiv (node GPR64:$Rn), 3780 fixedpoint_f32_i64:$scale))]> { 3781 let Inst{31} = 1; // 64-bit GPR flag 3782 let Inst{23-22} = 0b00; // 32-bit FPR flag 3783 } 3784 3785 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 3786 [(set FPR64:$Rd, 3787 (fdiv (node GPR64:$Rn), 3788 fixedpoint_f64_i64:$scale))]> { 3789 let Inst{31} = 1; // 64-bit GPR flag 3790 let Inst{23-22} = 0b01; // 64-bit FPR flag 3791 } 3792} 3793 3794//--- 3795// Unscaled integer <-> floating point conversion (i.e. FMOV) 3796//--- 3797 3798let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3799class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 3800 RegisterClass srcType, RegisterClass dstType, 3801 string asm> 3802 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 3803 // We use COPY_TO_REGCLASS for these bitconvert operations. 3804 // copyPhysReg() expands the resultant COPY instructions after 3805 // regalloc is done. This gives greater freedom for the allocator 3806 // and related passes (coalescing, copy propagation, et. al.) to 3807 // be more effective. 3808 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 3809 Sched<[WriteFCopy]> { 3810 bits<5> Rd; 3811 bits<5> Rn; 3812 let Inst{30-24} = 0b0011110; 3813 let Inst{21} = 1; 3814 let Inst{20-19} = rmode; 3815 let Inst{18-16} = opcode; 3816 let Inst{15-10} = 0b000000; 3817 let Inst{9-5} = Rn; 3818 let Inst{4-0} = Rd; 3819} 3820 3821let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3822class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 3823 RegisterClass srcType, RegisterOperand dstType, string asm, 3824 string kind> 3825 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 3826 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 3827 Sched<[WriteFCopy]> { 3828 bits<5> Rd; 3829 bits<5> Rn; 3830 let Inst{30-23} = 0b00111101; 3831 let Inst{21} = 1; 3832 let Inst{20-19} = rmode; 3833 let Inst{18-16} = opcode; 3834 let Inst{15-10} = 0b000000; 3835 let Inst{9-5} = Rn; 3836 let Inst{4-0} = Rd; 3837 3838 let DecoderMethod = "DecodeFMOVLaneInstruction"; 3839} 3840 3841let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3842class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 3843 RegisterOperand srcType, RegisterClass dstType, string asm, 3844 string kind> 3845 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 3846 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 3847 Sched<[WriteFCopy]> { 3848 bits<5> Rd; 3849 bits<5> Rn; 3850 let Inst{30-23} = 0b00111101; 3851 let Inst{21} = 1; 3852 let Inst{20-19} = rmode; 3853 let Inst{18-16} = opcode; 3854 let Inst{15-10} = 0b000000; 3855 let Inst{9-5} = Rn; 3856 let Inst{4-0} = Rd; 3857 3858 let DecoderMethod = "DecodeFMOVLaneInstruction"; 3859} 3860 3861 3862multiclass UnscaledConversion<string asm> { 3863 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> { 3864 let Inst{31} = 0; // 32-bit GPR flag 3865 let Inst{23-22} = 0b11; // 16-bit FPR flag 3866 let Predicates = [HasFullFP16]; 3867 } 3868 3869 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> { 3870 let Inst{31} = 1; // 64-bit GPR flag 3871 let Inst{23-22} = 0b11; // 16-bit FPR flag 3872 let Predicates = [HasFullFP16]; 3873 } 3874 3875 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 3876 let Inst{31} = 0; // 32-bit GPR flag 3877 let Inst{23-22} = 0b00; // 32-bit FPR flag 3878 } 3879 3880 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 3881 let Inst{31} = 1; // 64-bit GPR flag 3882 let Inst{23-22} = 0b01; // 64-bit FPR flag 3883 } 3884 3885 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> { 3886 let Inst{31} = 0; // 32-bit GPR flag 3887 let Inst{23-22} = 0b11; // 16-bit FPR flag 3888 let Predicates = [HasFullFP16]; 3889 } 3890 3891 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> { 3892 let Inst{31} = 1; // 64-bit GPR flag 3893 let Inst{23-22} = 0b11; // 16-bit FPR flag 3894 let Predicates = [HasFullFP16]; 3895 } 3896 3897 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 3898 let Inst{31} = 0; // 32-bit GPR flag 3899 let Inst{23-22} = 0b00; // 32-bit FPR flag 3900 } 3901 3902 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 3903 let Inst{31} = 1; // 64-bit GPR flag 3904 let Inst{23-22} = 0b01; // 64-bit FPR flag 3905 } 3906 3907 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 3908 asm, ".d"> { 3909 let Inst{31} = 1; 3910 let Inst{22} = 0; 3911 } 3912 3913 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 3914 asm, ".d"> { 3915 let Inst{31} = 1; 3916 let Inst{22} = 0; 3917 } 3918} 3919 3920//--- 3921// Floating point conversion 3922//--- 3923 3924class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 3925 RegisterClass srcType, string asm, list<dag> pattern> 3926 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 3927 Sched<[WriteFCvt]> { 3928 bits<5> Rd; 3929 bits<5> Rn; 3930 let Inst{31-24} = 0b00011110; 3931 let Inst{23-22} = type; 3932 let Inst{21-17} = 0b10001; 3933 let Inst{16-15} = opcode; 3934 let Inst{14-10} = 0b10000; 3935 let Inst{9-5} = Rn; 3936 let Inst{4-0} = Rd; 3937} 3938 3939multiclass FPConversion<string asm> { 3940 // Double-precision to Half-precision 3941 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 3942 [(set FPR16:$Rd, (fround FPR64:$Rn))]>; 3943 3944 // Double-precision to Single-precision 3945 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 3946 [(set FPR32:$Rd, (fround FPR64:$Rn))]>; 3947 3948 // Half-precision to Double-precision 3949 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 3950 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>; 3951 3952 // Half-precision to Single-precision 3953 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 3954 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>; 3955 3956 // Single-precision to Double-precision 3957 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 3958 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>; 3959 3960 // Single-precision to Half-precision 3961 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 3962 [(set FPR16:$Rd, (fround FPR32:$Rn))]>; 3963} 3964 3965//--- 3966// Single operand floating point data processing 3967//--- 3968 3969let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3970class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype, 3971 ValueType vt, string asm, SDPatternOperator node> 3972 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 3973 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 3974 Sched<[WriteF]> { 3975 bits<5> Rd; 3976 bits<5> Rn; 3977 let Inst{31-24} = 0b00011110; 3978 let Inst{21-19} = 0b100; 3979 let Inst{18-15} = opcode; 3980 let Inst{14-10} = 0b10000; 3981 let Inst{9-5} = Rn; 3982 let Inst{4-0} = Rd; 3983} 3984 3985multiclass SingleOperandFPData<bits<4> opcode, string asm, 3986 SDPatternOperator node = null_frag> { 3987 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> { 3988 let Inst{23-22} = 0b11; // 16-bit size flag 3989 let Predicates = [HasFullFP16]; 3990 } 3991 3992 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 3993 let Inst{23-22} = 0b00; // 32-bit size flag 3994 } 3995 3996 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 3997 let Inst{23-22} = 0b01; // 64-bit size flag 3998 } 3999} 4000 4001//--- 4002// Two operand floating point data processing 4003//--- 4004 4005let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4006class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 4007 string asm, list<dag> pat> 4008 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 4009 asm, "\t$Rd, $Rn, $Rm", "", pat>, 4010 Sched<[WriteF]> { 4011 bits<5> Rd; 4012 bits<5> Rn; 4013 bits<5> Rm; 4014 let Inst{31-24} = 0b00011110; 4015 let Inst{21} = 1; 4016 let Inst{20-16} = Rm; 4017 let Inst{15-12} = opcode; 4018 let Inst{11-10} = 0b10; 4019 let Inst{9-5} = Rn; 4020 let Inst{4-0} = Rd; 4021} 4022 4023multiclass TwoOperandFPData<bits<4> opcode, string asm, 4024 SDPatternOperator node = null_frag> { 4025 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4026 [(set (f16 FPR16:$Rd), 4027 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> { 4028 let Inst{23-22} = 0b11; // 16-bit size flag 4029 let Predicates = [HasFullFP16]; 4030 } 4031 4032 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4033 [(set (f32 FPR32:$Rd), 4034 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 4035 let Inst{23-22} = 0b00; // 32-bit size flag 4036 } 4037 4038 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4039 [(set (f64 FPR64:$Rd), 4040 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 4041 let Inst{23-22} = 0b01; // 64-bit size flag 4042 } 4043} 4044 4045multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 4046 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm, 4047 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> { 4048 let Inst{23-22} = 0b11; // 16-bit size flag 4049 let Predicates = [HasFullFP16]; 4050 } 4051 4052 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 4053 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 4054 let Inst{23-22} = 0b00; // 32-bit size flag 4055 } 4056 4057 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 4058 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 4059 let Inst{23-22} = 0b01; // 64-bit size flag 4060 } 4061} 4062 4063 4064//--- 4065// Three operand floating point data processing 4066//--- 4067 4068class BaseThreeOperandFPData<bit isNegated, bit isSub, 4069 RegisterClass regtype, string asm, list<dag> pat> 4070 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 4071 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 4072 Sched<[WriteFMul]> { 4073 bits<5> Rd; 4074 bits<5> Rn; 4075 bits<5> Rm; 4076 bits<5> Ra; 4077 let Inst{31-24} = 0b00011111; 4078 let Inst{21} = isNegated; 4079 let Inst{20-16} = Rm; 4080 let Inst{15} = isSub; 4081 let Inst{14-10} = Ra; 4082 let Inst{9-5} = Rn; 4083 let Inst{4-0} = Rd; 4084} 4085 4086multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 4087 SDPatternOperator node> { 4088 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm, 4089 [(set FPR16:$Rd, 4090 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> { 4091 let Inst{23-22} = 0b11; // 16-bit size flag 4092 let Predicates = [HasFullFP16]; 4093 } 4094 4095 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 4096 [(set FPR32:$Rd, 4097 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 4098 let Inst{23-22} = 0b00; // 32-bit size flag 4099 } 4100 4101 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 4102 [(set FPR64:$Rd, 4103 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 4104 let Inst{23-22} = 0b01; // 64-bit size flag 4105 } 4106} 4107 4108//--- 4109// Floating point data comparisons 4110//--- 4111 4112let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4113class BaseOneOperandFPComparison<bit signalAllNans, 4114 RegisterClass regtype, string asm, 4115 list<dag> pat> 4116 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 4117 Sched<[WriteFCmp]> { 4118 bits<5> Rn; 4119 let Inst{31-24} = 0b00011110; 4120 let Inst{21} = 1; 4121 4122 let Inst{15-10} = 0b001000; 4123 let Inst{9-5} = Rn; 4124 let Inst{4} = signalAllNans; 4125 let Inst{3-0} = 0b1000; 4126 4127 // Rm should be 0b00000 canonically, but we need to accept any value. 4128 let PostEncoderMethod = "fixOneOperandFPComparison"; 4129} 4130 4131let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4132class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 4133 string asm, list<dag> pat> 4134 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 4135 Sched<[WriteFCmp]> { 4136 bits<5> Rm; 4137 bits<5> Rn; 4138 let Inst{31-24} = 0b00011110; 4139 let Inst{21} = 1; 4140 let Inst{20-16} = Rm; 4141 let Inst{15-10} = 0b001000; 4142 let Inst{9-5} = Rn; 4143 let Inst{4} = signalAllNans; 4144 let Inst{3-0} = 0b0000; 4145} 4146 4147multiclass FPComparison<bit signalAllNans, string asm, 4148 SDPatternOperator OpNode = null_frag> { 4149 let Defs = [NZCV] in { 4150 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm, 4151 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> { 4152 let Inst{23-22} = 0b11; 4153 let Predicates = [HasFullFP16]; 4154 } 4155 4156 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm, 4157 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> { 4158 let Inst{23-22} = 0b11; 4159 let Predicates = [HasFullFP16]; 4160 } 4161 4162 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 4163 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 4164 let Inst{23-22} = 0b00; 4165 } 4166 4167 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 4168 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 4169 let Inst{23-22} = 0b00; 4170 } 4171 4172 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 4173 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 4174 let Inst{23-22} = 0b01; 4175 } 4176 4177 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 4178 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 4179 let Inst{23-22} = 0b01; 4180 } 4181 } // Defs = [NZCV] 4182} 4183 4184//--- 4185// Floating point conditional comparisons 4186//--- 4187 4188let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4189class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype, 4190 string mnemonic, list<dag> pat> 4191 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond), 4192 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>, 4193 Sched<[WriteFCmp]> { 4194 let Uses = [NZCV]; 4195 let Defs = [NZCV]; 4196 4197 bits<5> Rn; 4198 bits<5> Rm; 4199 bits<4> nzcv; 4200 bits<4> cond; 4201 4202 let Inst{31-24} = 0b00011110; 4203 let Inst{21} = 1; 4204 let Inst{20-16} = Rm; 4205 let Inst{15-12} = cond; 4206 let Inst{11-10} = 0b01; 4207 let Inst{9-5} = Rn; 4208 let Inst{4} = signalAllNans; 4209 let Inst{3-0} = nzcv; 4210} 4211 4212multiclass FPCondComparison<bit signalAllNans, string mnemonic, 4213 SDPatternOperator OpNode = null_frag> { 4214 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> { 4215 let Inst{23-22} = 0b11; 4216 let Predicates = [HasFullFP16]; 4217 } 4218 4219 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic, 4220 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv), 4221 (i32 imm:$cond), NZCV))]> { 4222 let Inst{23-22} = 0b00; 4223 } 4224 4225 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic, 4226 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv), 4227 (i32 imm:$cond), NZCV))]> { 4228 let Inst{23-22} = 0b01; 4229 } 4230} 4231 4232//--- 4233// Floating point conditional select 4234//--- 4235 4236class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 4237 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 4238 asm, "\t$Rd, $Rn, $Rm, $cond", "", 4239 [(set regtype:$Rd, 4240 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 4241 (i32 imm:$cond), NZCV))]>, 4242 Sched<[WriteF]> { 4243 bits<5> Rd; 4244 bits<5> Rn; 4245 bits<5> Rm; 4246 bits<4> cond; 4247 4248 let Inst{31-24} = 0b00011110; 4249 let Inst{21} = 1; 4250 let Inst{20-16} = Rm; 4251 let Inst{15-12} = cond; 4252 let Inst{11-10} = 0b11; 4253 let Inst{9-5} = Rn; 4254 let Inst{4-0} = Rd; 4255} 4256 4257multiclass FPCondSelect<string asm> { 4258 let Uses = [NZCV] in { 4259 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> { 4260 let Inst{23-22} = 0b11; 4261 let Predicates = [HasFullFP16]; 4262 } 4263 4264 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 4265 let Inst{23-22} = 0b00; 4266 } 4267 4268 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 4269 let Inst{23-22} = 0b01; 4270 } 4271 } // Uses = [NZCV] 4272} 4273 4274//--- 4275// Floating move immediate 4276//--- 4277 4278class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 4279 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 4280 [(set regtype:$Rd, fpimmtype:$imm)]>, 4281 Sched<[WriteFImm]> { 4282 bits<5> Rd; 4283 bits<8> imm; 4284 let Inst{31-24} = 0b00011110; 4285 let Inst{21} = 1; 4286 let Inst{20-13} = imm; 4287 let Inst{12-5} = 0b10000000; 4288 let Inst{4-0} = Rd; 4289} 4290 4291multiclass FPMoveImmediate<string asm> { 4292 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> { 4293 let Inst{23-22} = 0b11; 4294 let Predicates = [HasFullFP16]; 4295 } 4296 4297 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 4298 let Inst{23-22} = 0b00; 4299 } 4300 4301 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 4302 let Inst{23-22} = 0b01; 4303 } 4304} 4305} // end of 'let Predicates = [HasFPARMv8]' 4306 4307//---------------------------------------------------------------------------- 4308// AdvSIMD 4309//---------------------------------------------------------------------------- 4310 4311let Predicates = [HasNEON] in { 4312 4313//---------------------------------------------------------------------------- 4314// AdvSIMD three register vector instructions 4315//---------------------------------------------------------------------------- 4316 4317let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4318class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode, 4319 RegisterOperand regtype, string asm, string kind, 4320 list<dag> pattern> 4321 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 4322 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 4323 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 4324 Sched<[WriteV]> { 4325 bits<5> Rd; 4326 bits<5> Rn; 4327 bits<5> Rm; 4328 let Inst{31} = 0; 4329 let Inst{30} = Q; 4330 let Inst{29} = U; 4331 let Inst{28-24} = 0b01110; 4332 let Inst{23-21} = size; 4333 let Inst{20-16} = Rm; 4334 let Inst{15-11} = opcode; 4335 let Inst{10} = 1; 4336 let Inst{9-5} = Rn; 4337 let Inst{4-0} = Rd; 4338} 4339 4340let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4341class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode, 4342 RegisterOperand regtype, string asm, string kind, 4343 list<dag> pattern> 4344 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 4345 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 4346 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 4347 Sched<[WriteV]> { 4348 bits<5> Rd; 4349 bits<5> Rn; 4350 bits<5> Rm; 4351 let Inst{31} = 0; 4352 let Inst{30} = Q; 4353 let Inst{29} = U; 4354 let Inst{28-24} = 0b01110; 4355 let Inst{23-21} = size; 4356 let Inst{20-16} = Rm; 4357 let Inst{15-11} = opcode; 4358 let Inst{10} = 1; 4359 let Inst{9-5} = Rn; 4360 let Inst{4-0} = Rd; 4361} 4362 4363// All operand sizes distinguished in the encoding. 4364multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 4365 SDPatternOperator OpNode> { 4366 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 4367 asm, ".8b", 4368 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4369 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 4370 asm, ".16b", 4371 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4372 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 4373 asm, ".4h", 4374 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4375 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 4376 asm, ".8h", 4377 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4378 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 4379 asm, ".2s", 4380 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4381 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 4382 asm, ".4s", 4383 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4384 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128, 4385 asm, ".2d", 4386 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 4387} 4388 4389// As above, but D sized elements unsupported. 4390multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 4391 SDPatternOperator OpNode> { 4392 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 4393 asm, ".8b", 4394 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 4395 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 4396 asm, ".16b", 4397 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 4398 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 4399 asm, ".4h", 4400 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 4401 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 4402 asm, ".8h", 4403 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 4404 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 4405 asm, ".2s", 4406 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 4407 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 4408 asm, ".4s", 4409 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 4410} 4411 4412multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 4413 SDPatternOperator OpNode> { 4414 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64, 4415 asm, ".8b", 4416 [(set (v8i8 V64:$dst), 4417 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4418 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128, 4419 asm, ".16b", 4420 [(set (v16i8 V128:$dst), 4421 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4422 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64, 4423 asm, ".4h", 4424 [(set (v4i16 V64:$dst), 4425 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4426 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128, 4427 asm, ".8h", 4428 [(set (v8i16 V128:$dst), 4429 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4430 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64, 4431 asm, ".2s", 4432 [(set (v2i32 V64:$dst), 4433 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4434 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128, 4435 asm, ".4s", 4436 [(set (v4i32 V128:$dst), 4437 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4438} 4439 4440// As above, but only B sized elements supported. 4441multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 4442 SDPatternOperator OpNode> { 4443 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64, 4444 asm, ".8b", 4445 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4446 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128, 4447 asm, ".16b", 4448 [(set (v16i8 V128:$Rd), 4449 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4450} 4451 4452// As above, but only floating point elements supported. 4453multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc, 4454 string asm, SDPatternOperator OpNode> { 4455 let Predicates = [HasNEON, HasFullFP16] in { 4456 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 4457 asm, ".4h", 4458 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 4459 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 4460 asm, ".8h", 4461 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 4462 } // Predicates = [HasNEON, HasFullFP16] 4463 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 4464 asm, ".2s", 4465 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4466 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 4467 asm, ".4s", 4468 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4469 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 4470 asm, ".2d", 4471 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4472} 4473 4474multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc, 4475 string asm, 4476 SDPatternOperator OpNode> { 4477 let Predicates = [HasNEON, HasFullFP16] in { 4478 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64, 4479 asm, ".4h", 4480 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 4481 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128, 4482 asm, ".8h", 4483 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 4484 } // Predicates = [HasNEON, HasFullFP16] 4485 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64, 4486 asm, ".2s", 4487 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4488 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128, 4489 asm, ".4s", 4490 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4491 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128, 4492 asm, ".2d", 4493 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4494} 4495 4496multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc, 4497 string asm, SDPatternOperator OpNode> { 4498 let Predicates = [HasNEON, HasFullFP16] in { 4499 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64, 4500 asm, ".4h", 4501 [(set (v4f16 V64:$dst), 4502 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>; 4503 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128, 4504 asm, ".8h", 4505 [(set (v8f16 V128:$dst), 4506 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>; 4507 } // Predicates = [HasNEON, HasFullFP16] 4508 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64, 4509 asm, ".2s", 4510 [(set (v2f32 V64:$dst), 4511 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4512 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128, 4513 asm, ".4s", 4514 [(set (v4f32 V128:$dst), 4515 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4516 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128, 4517 asm, ".2d", 4518 [(set (v2f64 V128:$dst), 4519 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4520} 4521 4522// As above, but D and B sized elements unsupported. 4523multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 4524 SDPatternOperator OpNode> { 4525 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64, 4526 asm, ".4h", 4527 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4528 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128, 4529 asm, ".8h", 4530 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4531 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64, 4532 asm, ".2s", 4533 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4534 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128, 4535 asm, ".4s", 4536 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4537} 4538 4539// Logical three vector ops share opcode bits, and only use B sized elements. 4540multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 4541 SDPatternOperator OpNode = null_frag> { 4542 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64, 4543 asm, ".8b", 4544 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 4545 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128, 4546 asm, ".16b", 4547 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 4548 4549 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 4550 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4551 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 4552 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4553 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 4554 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4555 4556 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 4557 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4558 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 4559 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4560 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 4561 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4562} 4563 4564multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 4565 string asm, SDPatternOperator OpNode> { 4566 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64, 4567 asm, ".8b", 4568 [(set (v8i8 V64:$dst), 4569 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4570 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128, 4571 asm, ".16b", 4572 [(set (v16i8 V128:$dst), 4573 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 4574 (v16i8 V128:$Rm)))]>; 4575 4576 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 4577 (v4i16 V64:$RHS))), 4578 (!cast<Instruction>(NAME#"v8i8") 4579 V64:$LHS, V64:$MHS, V64:$RHS)>; 4580 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 4581 (v2i32 V64:$RHS))), 4582 (!cast<Instruction>(NAME#"v8i8") 4583 V64:$LHS, V64:$MHS, V64:$RHS)>; 4584 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 4585 (v1i64 V64:$RHS))), 4586 (!cast<Instruction>(NAME#"v8i8") 4587 V64:$LHS, V64:$MHS, V64:$RHS)>; 4588 4589 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 4590 (v8i16 V128:$RHS))), 4591 (!cast<Instruction>(NAME#"v16i8") 4592 V128:$LHS, V128:$MHS, V128:$RHS)>; 4593 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 4594 (v4i32 V128:$RHS))), 4595 (!cast<Instruction>(NAME#"v16i8") 4596 V128:$LHS, V128:$MHS, V128:$RHS)>; 4597 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 4598 (v2i64 V128:$RHS))), 4599 (!cast<Instruction>(NAME#"v16i8") 4600 V128:$LHS, V128:$MHS, V128:$RHS)>; 4601} 4602 4603 4604//---------------------------------------------------------------------------- 4605// AdvSIMD two register vector instructions. 4606//---------------------------------------------------------------------------- 4607 4608let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4609class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4610 bits<2> size2, RegisterOperand regtype, string asm, 4611 string dstkind, string srckind, list<dag> pattern> 4612 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 4613 "{\t$Rd" # dstkind # ", $Rn" # srckind # 4614 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 4615 Sched<[WriteV]> { 4616 bits<5> Rd; 4617 bits<5> Rn; 4618 let Inst{31} = 0; 4619 let Inst{30} = Q; 4620 let Inst{29} = U; 4621 let Inst{28-24} = 0b01110; 4622 let Inst{23-22} = size; 4623 let Inst{21} = 0b1; 4624 let Inst{20-19} = size2; 4625 let Inst{18-17} = 0b00; 4626 let Inst{16-12} = opcode; 4627 let Inst{11-10} = 0b10; 4628 let Inst{9-5} = Rn; 4629 let Inst{4-0} = Rd; 4630} 4631 4632let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4633class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4634 bits<2> size2, RegisterOperand regtype, 4635 string asm, string dstkind, string srckind, 4636 list<dag> pattern> 4637 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 4638 "{\t$Rd" # dstkind # ", $Rn" # srckind # 4639 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 4640 Sched<[WriteV]> { 4641 bits<5> Rd; 4642 bits<5> Rn; 4643 let Inst{31} = 0; 4644 let Inst{30} = Q; 4645 let Inst{29} = U; 4646 let Inst{28-24} = 0b01110; 4647 let Inst{23-22} = size; 4648 let Inst{21} = 0b1; 4649 let Inst{20-19} = size2; 4650 let Inst{18-17} = 0b00; 4651 let Inst{16-12} = opcode; 4652 let Inst{11-10} = 0b10; 4653 let Inst{9-5} = Rn; 4654 let Inst{4-0} = Rd; 4655} 4656 4657// Supports B, H, and S element sizes. 4658multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 4659 SDPatternOperator OpNode> { 4660 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4661 asm, ".8b", ".8b", 4662 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4663 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4664 asm, ".16b", ".16b", 4665 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4666 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4667 asm, ".4h", ".4h", 4668 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4669 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4670 asm, ".8h", ".8h", 4671 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4672 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 4673 asm, ".2s", ".2s", 4674 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4675 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 4676 asm, ".4s", ".4s", 4677 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4678} 4679 4680class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 4681 RegisterOperand regtype, string asm, string dstkind, 4682 string srckind, string amount> 4683 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 4684 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 4685 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 4686 Sched<[WriteV]> { 4687 bits<5> Rd; 4688 bits<5> Rn; 4689 let Inst{31} = 0; 4690 let Inst{30} = Q; 4691 let Inst{29-24} = 0b101110; 4692 let Inst{23-22} = size; 4693 let Inst{21-10} = 0b100001001110; 4694 let Inst{9-5} = Rn; 4695 let Inst{4-0} = Rd; 4696} 4697 4698multiclass SIMDVectorLShiftLongBySizeBHS { 4699 let hasSideEffects = 0 in { 4700 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 4701 "shll", ".8h", ".8b", "8">; 4702 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 4703 "shll2", ".8h", ".16b", "8">; 4704 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 4705 "shll", ".4s", ".4h", "16">; 4706 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 4707 "shll2", ".4s", ".8h", "16">; 4708 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 4709 "shll", ".2d", ".2s", "32">; 4710 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 4711 "shll2", ".2d", ".4s", "32">; 4712 } 4713} 4714 4715// Supports all element sizes. 4716multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 4717 SDPatternOperator OpNode> { 4718 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4719 asm, ".4h", ".8b", 4720 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4721 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4722 asm, ".8h", ".16b", 4723 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4724 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4725 asm, ".2s", ".4h", 4726 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4727 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4728 asm, ".4s", ".8h", 4729 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4730 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 4731 asm, ".1d", ".2s", 4732 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4733 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 4734 asm, ".2d", ".4s", 4735 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4736} 4737 4738multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 4739 SDPatternOperator OpNode> { 4740 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 4741 asm, ".4h", ".8b", 4742 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 4743 (v8i8 V64:$Rn)))]>; 4744 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 4745 asm, ".8h", ".16b", 4746 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 4747 (v16i8 V128:$Rn)))]>; 4748 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 4749 asm, ".2s", ".4h", 4750 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 4751 (v4i16 V64:$Rn)))]>; 4752 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 4753 asm, ".4s", ".8h", 4754 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 4755 (v8i16 V128:$Rn)))]>; 4756 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 4757 asm, ".1d", ".2s", 4758 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 4759 (v2i32 V64:$Rn)))]>; 4760 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 4761 asm, ".2d", ".4s", 4762 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 4763 (v4i32 V128:$Rn)))]>; 4764} 4765 4766// Supports all element sizes, except 1xD. 4767multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 4768 SDPatternOperator OpNode> { 4769 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64, 4770 asm, ".8b", ".8b", 4771 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 4772 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128, 4773 asm, ".16b", ".16b", 4774 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 4775 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64, 4776 asm, ".4h", ".4h", 4777 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 4778 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128, 4779 asm, ".8h", ".8h", 4780 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 4781 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64, 4782 asm, ".2s", ".2s", 4783 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 4784 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128, 4785 asm, ".4s", ".4s", 4786 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 4787 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128, 4788 asm, ".2d", ".2d", 4789 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 4790} 4791 4792multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 4793 SDPatternOperator OpNode = null_frag> { 4794 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4795 asm, ".8b", ".8b", 4796 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4797 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4798 asm, ".16b", ".16b", 4799 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4800 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4801 asm, ".4h", ".4h", 4802 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4803 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4804 asm, ".8h", ".8h", 4805 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4806 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64, 4807 asm, ".2s", ".2s", 4808 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4809 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128, 4810 asm, ".4s", ".4s", 4811 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4812 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128, 4813 asm, ".2d", ".2d", 4814 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4815} 4816 4817 4818// Supports only B element sizes. 4819multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 4820 SDPatternOperator OpNode> { 4821 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64, 4822 asm, ".8b", ".8b", 4823 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4824 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128, 4825 asm, ".16b", ".16b", 4826 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4827 4828} 4829 4830// Supports only B and H element sizes. 4831multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 4832 SDPatternOperator OpNode> { 4833 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64, 4834 asm, ".8b", ".8b", 4835 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 4836 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128, 4837 asm, ".16b", ".16b", 4838 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 4839 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64, 4840 asm, ".4h", ".4h", 4841 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 4842 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128, 4843 asm, ".8h", ".8h", 4844 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 4845} 4846 4847// Supports only S and D element sizes, uses high bit of the size field 4848// as an extra opcode bit. 4849multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 4850 SDPatternOperator OpNode> { 4851 let Predicates = [HasNEON, HasFullFP16] in { 4852 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 4853 asm, ".4h", ".4h", 4854 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 4855 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 4856 asm, ".8h", ".8h", 4857 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 4858 } // Predicates = [HasNEON, HasFullFP16] 4859 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4860 asm, ".2s", ".2s", 4861 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 4862 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4863 asm, ".4s", ".4s", 4864 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 4865 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 4866 asm, ".2d", ".2d", 4867 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4868} 4869 4870// Supports only S element size. 4871multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 4872 SDPatternOperator OpNode> { 4873 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4874 asm, ".2s", ".2s", 4875 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4876 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4877 asm, ".4s", ".4s", 4878 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4879} 4880 4881 4882multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 4883 SDPatternOperator OpNode> { 4884 let Predicates = [HasNEON, HasFullFP16] in { 4885 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 4886 asm, ".4h", ".4h", 4887 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>; 4888 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 4889 asm, ".8h", ".8h", 4890 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>; 4891 } // Predicates = [HasNEON, HasFullFP16] 4892 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4893 asm, ".2s", ".2s", 4894 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 4895 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4896 asm, ".4s", ".4s", 4897 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 4898 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 4899 asm, ".2d", ".2d", 4900 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4901} 4902 4903multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 4904 SDPatternOperator OpNode> { 4905 let Predicates = [HasNEON, HasFullFP16] in { 4906 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64, 4907 asm, ".4h", ".4h", 4908 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4909 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128, 4910 asm, ".8h", ".8h", 4911 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4912 } // Predicates = [HasNEON, HasFullFP16] 4913 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64, 4914 asm, ".2s", ".2s", 4915 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4916 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128, 4917 asm, ".4s", ".4s", 4918 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4919 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128, 4920 asm, ".2d", ".2d", 4921 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4922} 4923 4924 4925class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4926 RegisterOperand inreg, RegisterOperand outreg, 4927 string asm, string outkind, string inkind, 4928 list<dag> pattern> 4929 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 4930 "{\t$Rd" # outkind # ", $Rn" # inkind # 4931 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 4932 Sched<[WriteV]> { 4933 bits<5> Rd; 4934 bits<5> Rn; 4935 let Inst{31} = 0; 4936 let Inst{30} = Q; 4937 let Inst{29} = U; 4938 let Inst{28-24} = 0b01110; 4939 let Inst{23-22} = size; 4940 let Inst{21-17} = 0b10000; 4941 let Inst{16-12} = opcode; 4942 let Inst{11-10} = 0b10; 4943 let Inst{9-5} = Rn; 4944 let Inst{4-0} = Rd; 4945} 4946 4947class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4948 RegisterOperand inreg, RegisterOperand outreg, 4949 string asm, string outkind, string inkind, 4950 list<dag> pattern> 4951 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 4952 "{\t$Rd" # outkind # ", $Rn" # inkind # 4953 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 4954 Sched<[WriteV]> { 4955 bits<5> Rd; 4956 bits<5> Rn; 4957 let Inst{31} = 0; 4958 let Inst{30} = Q; 4959 let Inst{29} = U; 4960 let Inst{28-24} = 0b01110; 4961 let Inst{23-22} = size; 4962 let Inst{21-17} = 0b10000; 4963 let Inst{16-12} = opcode; 4964 let Inst{11-10} = 0b10; 4965 let Inst{9-5} = Rn; 4966 let Inst{4-0} = Rd; 4967} 4968 4969multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 4970 SDPatternOperator OpNode> { 4971 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 4972 asm, ".8b", ".8h", 4973 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4974 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 4975 asm#"2", ".16b", ".8h", []>; 4976 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 4977 asm, ".4h", ".4s", 4978 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4979 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 4980 asm#"2", ".8h", ".4s", []>; 4981 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 4982 asm, ".2s", ".2d", 4983 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4984 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 4985 asm#"2", ".4s", ".2d", []>; 4986 4987 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 4988 (!cast<Instruction>(NAME # "v16i8") 4989 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4990 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 4991 (!cast<Instruction>(NAME # "v8i16") 4992 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4993 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 4994 (!cast<Instruction>(NAME # "v4i32") 4995 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4996} 4997 4998class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2, 4999 bits<5> opcode, RegisterOperand regtype, string asm, 5000 string kind, string zero, ValueType dty, 5001 ValueType sty, SDNode OpNode> 5002 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5003 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 5004 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 5005 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 5006 Sched<[WriteV]> { 5007 bits<5> Rd; 5008 bits<5> Rn; 5009 let Inst{31} = 0; 5010 let Inst{30} = Q; 5011 let Inst{29} = U; 5012 let Inst{28-24} = 0b01110; 5013 let Inst{23-22} = size; 5014 let Inst{21} = 0b1; 5015 let Inst{20-19} = size2; 5016 let Inst{18-17} = 0b00; 5017 let Inst{16-12} = opcode; 5018 let Inst{11-10} = 0b10; 5019 let Inst{9-5} = Rn; 5020 let Inst{4-0} = Rd; 5021} 5022 5023// Comparisons support all element sizes, except 1xD. 5024multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 5025 SDNode OpNode> { 5026 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64, 5027 asm, ".8b", "0", 5028 v8i8, v8i8, OpNode>; 5029 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128, 5030 asm, ".16b", "0", 5031 v16i8, v16i8, OpNode>; 5032 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64, 5033 asm, ".4h", "0", 5034 v4i16, v4i16, OpNode>; 5035 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128, 5036 asm, ".8h", "0", 5037 v8i16, v8i16, OpNode>; 5038 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64, 5039 asm, ".2s", "0", 5040 v2i32, v2i32, OpNode>; 5041 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128, 5042 asm, ".4s", "0", 5043 v4i32, v4i32, OpNode>; 5044 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128, 5045 asm, ".2d", "0", 5046 v2i64, v2i64, OpNode>; 5047} 5048 5049// FP Comparisons support only S and D element sizes (and H for v8.2a). 5050multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 5051 string asm, SDNode OpNode> { 5052 5053 let Predicates = [HasNEON, HasFullFP16] in { 5054 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64, 5055 asm, ".4h", "0.0", 5056 v4i16, v4f16, OpNode>; 5057 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128, 5058 asm, ".8h", "0.0", 5059 v8i16, v8f16, OpNode>; 5060 } // Predicates = [HasNEON, HasFullFP16] 5061 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64, 5062 asm, ".2s", "0.0", 5063 v2i32, v2f32, OpNode>; 5064 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128, 5065 asm, ".4s", "0.0", 5066 v4i32, v4f32, OpNode>; 5067 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128, 5068 asm, ".2d", "0.0", 5069 v2i64, v2f64, OpNode>; 5070 5071 let Predicates = [HasNEON, HasFullFP16] in { 5072 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0", 5073 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5074 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0", 5075 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5076 } 5077 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0", 5078 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5079 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0", 5080 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5081 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0", 5082 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5083 let Predicates = [HasNEON, HasFullFP16] in { 5084 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0", 5085 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>; 5086 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0", 5087 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>; 5088 } 5089 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0", 5090 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 5091 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0", 5092 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 5093 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0", 5094 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 5095} 5096 5097let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5098class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 5099 RegisterOperand outtype, RegisterOperand intype, 5100 string asm, string VdTy, string VnTy, 5101 list<dag> pattern> 5102 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 5103 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 5104 Sched<[WriteV]> { 5105 bits<5> Rd; 5106 bits<5> Rn; 5107 let Inst{31} = 0; 5108 let Inst{30} = Q; 5109 let Inst{29} = U; 5110 let Inst{28-24} = 0b01110; 5111 let Inst{23-22} = size; 5112 let Inst{21-17} = 0b10000; 5113 let Inst{16-12} = opcode; 5114 let Inst{11-10} = 0b10; 5115 let Inst{9-5} = Rn; 5116 let Inst{4-0} = Rd; 5117} 5118 5119class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 5120 RegisterOperand outtype, RegisterOperand intype, 5121 string asm, string VdTy, string VnTy, 5122 list<dag> pattern> 5123 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 5124 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 5125 Sched<[WriteV]> { 5126 bits<5> Rd; 5127 bits<5> Rn; 5128 let Inst{31} = 0; 5129 let Inst{30} = Q; 5130 let Inst{29} = U; 5131 let Inst{28-24} = 0b01110; 5132 let Inst{23-22} = size; 5133 let Inst{21-17} = 0b10000; 5134 let Inst{16-12} = opcode; 5135 let Inst{11-10} = 0b10; 5136 let Inst{9-5} = Rn; 5137 let Inst{4-0} = Rd; 5138} 5139 5140multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 5141 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 5142 asm, ".4s", ".4h", []>; 5143 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 5144 asm#"2", ".4s", ".8h", []>; 5145 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 5146 asm, ".2d", ".2s", []>; 5147 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 5148 asm#"2", ".2d", ".4s", []>; 5149} 5150 5151multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 5152 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 5153 asm, ".4h", ".4s", []>; 5154 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 5155 asm#"2", ".8h", ".4s", []>; 5156 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 5157 asm, ".2s", ".2d", []>; 5158 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 5159 asm#"2", ".4s", ".2d", []>; 5160} 5161 5162multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 5163 Intrinsic OpNode> { 5164 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 5165 asm, ".2s", ".2d", 5166 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 5167 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 5168 asm#"2", ".4s", ".2d", []>; 5169 5170 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 5171 (!cast<Instruction>(NAME # "v4f32") 5172 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 5173} 5174 5175//---------------------------------------------------------------------------- 5176// AdvSIMD three register different-size vector instructions. 5177//---------------------------------------------------------------------------- 5178 5179let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5180class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 5181 RegisterOperand outtype, RegisterOperand intype1, 5182 RegisterOperand intype2, string asm, 5183 string outkind, string inkind1, string inkind2, 5184 list<dag> pattern> 5185 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 5186 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 5187 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 5188 Sched<[WriteV]> { 5189 bits<5> Rd; 5190 bits<5> Rn; 5191 bits<5> Rm; 5192 let Inst{31} = 0; 5193 let Inst{30} = size{0}; 5194 let Inst{29} = U; 5195 let Inst{28-24} = 0b01110; 5196 let Inst{23-22} = size{2-1}; 5197 let Inst{21} = 1; 5198 let Inst{20-16} = Rm; 5199 let Inst{15-12} = opcode; 5200 let Inst{11-10} = 0b00; 5201 let Inst{9-5} = Rn; 5202 let Inst{4-0} = Rd; 5203} 5204 5205let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5206class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 5207 RegisterOperand outtype, RegisterOperand intype1, 5208 RegisterOperand intype2, string asm, 5209 string outkind, string inkind1, string inkind2, 5210 list<dag> pattern> 5211 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 5212 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 5213 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 5214 Sched<[WriteV]> { 5215 bits<5> Rd; 5216 bits<5> Rn; 5217 bits<5> Rm; 5218 let Inst{31} = 0; 5219 let Inst{30} = size{0}; 5220 let Inst{29} = U; 5221 let Inst{28-24} = 0b01110; 5222 let Inst{23-22} = size{2-1}; 5223 let Inst{21} = 1; 5224 let Inst{20-16} = Rm; 5225 let Inst{15-12} = opcode; 5226 let Inst{11-10} = 0b00; 5227 let Inst{9-5} = Rn; 5228 let Inst{4-0} = Rd; 5229} 5230 5231// FIXME: TableGen doesn't know how to deal with expanded types that also 5232// change the element count (in this case, placing the results in 5233// the high elements of the result register rather than the low 5234// elements). Until that's fixed, we can't code-gen those. 5235multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 5236 Intrinsic IntOp> { 5237 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5238 V64, V128, V128, 5239 asm, ".8b", ".8h", ".8h", 5240 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 5241 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5242 V128, V128, V128, 5243 asm#"2", ".16b", ".8h", ".8h", 5244 []>; 5245 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5246 V64, V128, V128, 5247 asm, ".4h", ".4s", ".4s", 5248 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 5249 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5250 V128, V128, V128, 5251 asm#"2", ".8h", ".4s", ".4s", 5252 []>; 5253 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5254 V64, V128, V128, 5255 asm, ".2s", ".2d", ".2d", 5256 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 5257 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5258 V128, V128, V128, 5259 asm#"2", ".4s", ".2d", ".2d", 5260 []>; 5261 5262 5263 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 5264 // a version attached to an instruction. 5265 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 5266 (v8i16 V128:$Rm))), 5267 (!cast<Instruction>(NAME # "v8i16_v16i8") 5268 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 5269 V128:$Rn, V128:$Rm)>; 5270 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 5271 (v4i32 V128:$Rm))), 5272 (!cast<Instruction>(NAME # "v4i32_v8i16") 5273 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 5274 V128:$Rn, V128:$Rm)>; 5275 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 5276 (v2i64 V128:$Rm))), 5277 (!cast<Instruction>(NAME # "v2i64_v4i32") 5278 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 5279 V128:$Rn, V128:$Rm)>; 5280} 5281 5282multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 5283 Intrinsic IntOp> { 5284 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5285 V128, V64, V64, 5286 asm, ".8h", ".8b", ".8b", 5287 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5288 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5289 V128, V128, V128, 5290 asm#"2", ".8h", ".16b", ".16b", []>; 5291 let Predicates = [HasCrypto] in { 5292 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 5293 V128, V64, V64, 5294 asm, ".1q", ".1d", ".1d", []>; 5295 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 5296 V128, V128, V128, 5297 asm#"2", ".1q", ".2d", ".2d", []>; 5298 } 5299 5300 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 5301 (v8i8 (extract_high_v16i8 V128:$Rm)))), 5302 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 5303} 5304 5305multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 5306 SDPatternOperator OpNode> { 5307 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5308 V128, V64, V64, 5309 asm, ".4s", ".4h", ".4h", 5310 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5311 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5312 V128, V128, V128, 5313 asm#"2", ".4s", ".8h", ".8h", 5314 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 5315 (extract_high_v8i16 V128:$Rm)))]>; 5316 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5317 V128, V64, V64, 5318 asm, ".2d", ".2s", ".2s", 5319 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5320 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5321 V128, V128, V128, 5322 asm#"2", ".2d", ".4s", ".4s", 5323 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 5324 (extract_high_v4i32 V128:$Rm)))]>; 5325} 5326 5327multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 5328 SDPatternOperator OpNode = null_frag> { 5329 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5330 V128, V64, V64, 5331 asm, ".8h", ".8b", ".8b", 5332 [(set (v8i16 V128:$Rd), 5333 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 5334 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5335 V128, V128, V128, 5336 asm#"2", ".8h", ".16b", ".16b", 5337 [(set (v8i16 V128:$Rd), 5338 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 5339 (extract_high_v16i8 V128:$Rm)))))]>; 5340 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5341 V128, V64, V64, 5342 asm, ".4s", ".4h", ".4h", 5343 [(set (v4i32 V128:$Rd), 5344 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 5345 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5346 V128, V128, V128, 5347 asm#"2", ".4s", ".8h", ".8h", 5348 [(set (v4i32 V128:$Rd), 5349 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 5350 (extract_high_v8i16 V128:$Rm)))))]>; 5351 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5352 V128, V64, V64, 5353 asm, ".2d", ".2s", ".2s", 5354 [(set (v2i64 V128:$Rd), 5355 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 5356 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5357 V128, V128, V128, 5358 asm#"2", ".2d", ".4s", ".4s", 5359 [(set (v2i64 V128:$Rd), 5360 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 5361 (extract_high_v4i32 V128:$Rm)))))]>; 5362} 5363 5364multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 5365 string asm, 5366 SDPatternOperator OpNode> { 5367 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 5368 V128, V64, V64, 5369 asm, ".8h", ".8b", ".8b", 5370 [(set (v8i16 V128:$dst), 5371 (add (v8i16 V128:$Rd), 5372 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 5373 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5374 V128, V128, V128, 5375 asm#"2", ".8h", ".16b", ".16b", 5376 [(set (v8i16 V128:$dst), 5377 (add (v8i16 V128:$Rd), 5378 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 5379 (extract_high_v16i8 V128:$Rm))))))]>; 5380 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5381 V128, V64, V64, 5382 asm, ".4s", ".4h", ".4h", 5383 [(set (v4i32 V128:$dst), 5384 (add (v4i32 V128:$Rd), 5385 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 5386 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5387 V128, V128, V128, 5388 asm#"2", ".4s", ".8h", ".8h", 5389 [(set (v4i32 V128:$dst), 5390 (add (v4i32 V128:$Rd), 5391 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 5392 (extract_high_v8i16 V128:$Rm))))))]>; 5393 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5394 V128, V64, V64, 5395 asm, ".2d", ".2s", ".2s", 5396 [(set (v2i64 V128:$dst), 5397 (add (v2i64 V128:$Rd), 5398 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 5399 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5400 V128, V128, V128, 5401 asm#"2", ".2d", ".4s", ".4s", 5402 [(set (v2i64 V128:$dst), 5403 (add (v2i64 V128:$Rd), 5404 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 5405 (extract_high_v4i32 V128:$Rm))))))]>; 5406} 5407 5408multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 5409 SDPatternOperator OpNode = null_frag> { 5410 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5411 V128, V64, V64, 5412 asm, ".8h", ".8b", ".8b", 5413 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5414 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5415 V128, V128, V128, 5416 asm#"2", ".8h", ".16b", ".16b", 5417 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 5418 (extract_high_v16i8 V128:$Rm)))]>; 5419 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5420 V128, V64, V64, 5421 asm, ".4s", ".4h", ".4h", 5422 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5423 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5424 V128, V128, V128, 5425 asm#"2", ".4s", ".8h", ".8h", 5426 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 5427 (extract_high_v8i16 V128:$Rm)))]>; 5428 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5429 V128, V64, V64, 5430 asm, ".2d", ".2s", ".2s", 5431 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5432 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5433 V128, V128, V128, 5434 asm#"2", ".2d", ".4s", ".4s", 5435 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 5436 (extract_high_v4i32 V128:$Rm)))]>; 5437} 5438 5439multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 5440 string asm, 5441 SDPatternOperator OpNode> { 5442 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 5443 V128, V64, V64, 5444 asm, ".8h", ".8b", ".8b", 5445 [(set (v8i16 V128:$dst), 5446 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5447 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5448 V128, V128, V128, 5449 asm#"2", ".8h", ".16b", ".16b", 5450 [(set (v8i16 V128:$dst), 5451 (OpNode (v8i16 V128:$Rd), 5452 (extract_high_v16i8 V128:$Rn), 5453 (extract_high_v16i8 V128:$Rm)))]>; 5454 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5455 V128, V64, V64, 5456 asm, ".4s", ".4h", ".4h", 5457 [(set (v4i32 V128:$dst), 5458 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5459 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5460 V128, V128, V128, 5461 asm#"2", ".4s", ".8h", ".8h", 5462 [(set (v4i32 V128:$dst), 5463 (OpNode (v4i32 V128:$Rd), 5464 (extract_high_v8i16 V128:$Rn), 5465 (extract_high_v8i16 V128:$Rm)))]>; 5466 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5467 V128, V64, V64, 5468 asm, ".2d", ".2s", ".2s", 5469 [(set (v2i64 V128:$dst), 5470 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5471 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5472 V128, V128, V128, 5473 asm#"2", ".2d", ".4s", ".4s", 5474 [(set (v2i64 V128:$dst), 5475 (OpNode (v2i64 V128:$Rd), 5476 (extract_high_v4i32 V128:$Rn), 5477 (extract_high_v4i32 V128:$Rm)))]>; 5478} 5479 5480multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 5481 SDPatternOperator Accum> { 5482 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5483 V128, V64, V64, 5484 asm, ".4s", ".4h", ".4h", 5485 [(set (v4i32 V128:$dst), 5486 (Accum (v4i32 V128:$Rd), 5487 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 5488 (v4i16 V64:$Rm)))))]>; 5489 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5490 V128, V128, V128, 5491 asm#"2", ".4s", ".8h", ".8h", 5492 [(set (v4i32 V128:$dst), 5493 (Accum (v4i32 V128:$Rd), 5494 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 5495 (extract_high_v8i16 V128:$Rm)))))]>; 5496 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5497 V128, V64, V64, 5498 asm, ".2d", ".2s", ".2s", 5499 [(set (v2i64 V128:$dst), 5500 (Accum (v2i64 V128:$Rd), 5501 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 5502 (v2i32 V64:$Rm)))))]>; 5503 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5504 V128, V128, V128, 5505 asm#"2", ".2d", ".4s", ".4s", 5506 [(set (v2i64 V128:$dst), 5507 (Accum (v2i64 V128:$Rd), 5508 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 5509 (extract_high_v4i32 V128:$Rm)))))]>; 5510} 5511 5512multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 5513 SDPatternOperator OpNode> { 5514 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5515 V128, V128, V64, 5516 asm, ".8h", ".8h", ".8b", 5517 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 5518 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5519 V128, V128, V128, 5520 asm#"2", ".8h", ".8h", ".16b", 5521 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 5522 (extract_high_v16i8 V128:$Rm)))]>; 5523 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5524 V128, V128, V64, 5525 asm, ".4s", ".4s", ".4h", 5526 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 5527 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5528 V128, V128, V128, 5529 asm#"2", ".4s", ".4s", ".8h", 5530 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 5531 (extract_high_v8i16 V128:$Rm)))]>; 5532 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5533 V128, V128, V64, 5534 asm, ".2d", ".2d", ".2s", 5535 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 5536 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5537 V128, V128, V128, 5538 asm#"2", ".2d", ".2d", ".4s", 5539 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 5540 (extract_high_v4i32 V128:$Rm)))]>; 5541} 5542 5543//---------------------------------------------------------------------------- 5544// AdvSIMD bitwise extract from vector 5545//---------------------------------------------------------------------------- 5546 5547class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 5548 string asm, string kind> 5549 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 5550 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 5551 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 5552 [(set (vty regtype:$Rd), 5553 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 5554 Sched<[WriteV]> { 5555 bits<5> Rd; 5556 bits<5> Rn; 5557 bits<5> Rm; 5558 bits<4> imm; 5559 let Inst{31} = 0; 5560 let Inst{30} = size; 5561 let Inst{29-21} = 0b101110000; 5562 let Inst{20-16} = Rm; 5563 let Inst{15} = 0; 5564 let Inst{14-11} = imm; 5565 let Inst{10} = 0; 5566 let Inst{9-5} = Rn; 5567 let Inst{4-0} = Rd; 5568} 5569 5570 5571multiclass SIMDBitwiseExtract<string asm> { 5572 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 5573 let imm{3} = 0; 5574 } 5575 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 5576} 5577 5578//---------------------------------------------------------------------------- 5579// AdvSIMD zip vector 5580//---------------------------------------------------------------------------- 5581 5582class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 5583 string asm, string kind, SDNode OpNode, ValueType valty> 5584 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5585 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5586 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 5587 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 5588 Sched<[WriteV]> { 5589 bits<5> Rd; 5590 bits<5> Rn; 5591 bits<5> Rm; 5592 let Inst{31} = 0; 5593 let Inst{30} = size{0}; 5594 let Inst{29-24} = 0b001110; 5595 let Inst{23-22} = size{2-1}; 5596 let Inst{21} = 0; 5597 let Inst{20-16} = Rm; 5598 let Inst{15} = 0; 5599 let Inst{14-12} = opc; 5600 let Inst{11-10} = 0b10; 5601 let Inst{9-5} = Rn; 5602 let Inst{4-0} = Rd; 5603} 5604 5605multiclass SIMDZipVector<bits<3>opc, string asm, 5606 SDNode OpNode> { 5607 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 5608 asm, ".8b", OpNode, v8i8>; 5609 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 5610 asm, ".16b", OpNode, v16i8>; 5611 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 5612 asm, ".4h", OpNode, v4i16>; 5613 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 5614 asm, ".8h", OpNode, v8i16>; 5615 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 5616 asm, ".2s", OpNode, v2i32>; 5617 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 5618 asm, ".4s", OpNode, v4i32>; 5619 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 5620 asm, ".2d", OpNode, v2i64>; 5621 5622 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 5623 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 5624 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 5625 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 5626 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 5627 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 5628 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 5629 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 5630 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 5631 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 5632} 5633 5634//---------------------------------------------------------------------------- 5635// AdvSIMD three register scalar instructions 5636//---------------------------------------------------------------------------- 5637 5638let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5639class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode, 5640 RegisterClass regtype, string asm, 5641 list<dag> pattern> 5642 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5643 "\t$Rd, $Rn, $Rm", "", pattern>, 5644 Sched<[WriteV]> { 5645 bits<5> Rd; 5646 bits<5> Rn; 5647 bits<5> Rm; 5648 let Inst{31-30} = 0b01; 5649 let Inst{29} = U; 5650 let Inst{28-24} = 0b11110; 5651 let Inst{23-21} = size; 5652 let Inst{20-16} = Rm; 5653 let Inst{15-11} = opcode; 5654 let Inst{10} = 1; 5655 let Inst{9-5} = Rn; 5656 let Inst{4-0} = Rd; 5657} 5658 5659let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5660class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode, 5661 dag oops, dag iops, string asm, 5662 list<dag> pattern> 5663 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>, 5664 Sched<[WriteV]> { 5665 bits<5> Rd; 5666 bits<5> Rn; 5667 bits<5> Rm; 5668 let Inst{31-30} = 0b01; 5669 let Inst{29} = U; 5670 let Inst{28-24} = 0b11110; 5671 let Inst{23-22} = size; 5672 let Inst{21} = R; 5673 let Inst{20-16} = Rm; 5674 let Inst{15-11} = opcode; 5675 let Inst{10} = 1; 5676 let Inst{9-5} = Rn; 5677 let Inst{4-0} = Rd; 5678} 5679 5680multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 5681 SDPatternOperator OpNode> { 5682 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 5683 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 5684} 5685 5686multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 5687 SDPatternOperator OpNode> { 5688 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm, 5689 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 5690 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>; 5691 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 5692 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>; 5693 5694 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 5695 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 5696 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 5697 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 5698} 5699 5700multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 5701 SDPatternOperator OpNode> { 5702 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, 5703 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 5704 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>; 5705} 5706 5707multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm, 5708 SDPatternOperator OpNode = null_frag> { 5709 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst), 5710 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 5711 asm, []>; 5712 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst), 5713 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 5714 asm, []>; 5715} 5716 5717multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm, 5718 SDPatternOperator OpNode = null_frag> { 5719 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5720 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 5721 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 5722 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 5723 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 5724 let Predicates = [HasNEON, HasFullFP16] in { 5725 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 5726 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>; 5727 } // Predicates = [HasNEON, HasFullFP16] 5728 } 5729 5730 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5731 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 5732} 5733 5734multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm, 5735 SDPatternOperator OpNode = null_frag> { 5736 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5737 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm, 5738 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 5739 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm, 5740 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 5741 let Predicates = [HasNEON, HasFullFP16] in { 5742 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm, 5743 []>; 5744 } // Predicates = [HasNEON, HasFullFP16] 5745 } 5746 5747 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5748 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 5749} 5750 5751class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 5752 dag oops, dag iops, string asm, string cstr, list<dag> pat> 5753 : I<oops, iops, asm, 5754 "\t$Rd, $Rn, $Rm", cstr, pat>, 5755 Sched<[WriteV]> { 5756 bits<5> Rd; 5757 bits<5> Rn; 5758 bits<5> Rm; 5759 let Inst{31-30} = 0b01; 5760 let Inst{29} = U; 5761 let Inst{28-24} = 0b11110; 5762 let Inst{23-22} = size; 5763 let Inst{21} = 1; 5764 let Inst{20-16} = Rm; 5765 let Inst{15-11} = opcode; 5766 let Inst{10} = 0; 5767 let Inst{9-5} = Rn; 5768 let Inst{4-0} = Rd; 5769} 5770 5771let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5772multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 5773 SDPatternOperator OpNode = null_frag> { 5774 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 5775 (outs FPR32:$Rd), 5776 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 5777 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 5778 (outs FPR64:$Rd), 5779 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 5780 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 5781} 5782 5783let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5784multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 5785 SDPatternOperator OpNode = null_frag> { 5786 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 5787 (outs FPR32:$dst), 5788 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 5789 asm, "$Rd = $dst", []>; 5790 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 5791 (outs FPR64:$dst), 5792 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 5793 asm, "$Rd = $dst", 5794 [(set (i64 FPR64:$dst), 5795 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 5796} 5797 5798//---------------------------------------------------------------------------- 5799// AdvSIMD two register scalar instructions 5800//---------------------------------------------------------------------------- 5801 5802let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5803class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 5804 RegisterClass regtype, RegisterClass regtype2, 5805 string asm, list<dag> pat> 5806 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 5807 "\t$Rd, $Rn", "", pat>, 5808 Sched<[WriteV]> { 5809 bits<5> Rd; 5810 bits<5> Rn; 5811 let Inst{31-30} = 0b01; 5812 let Inst{29} = U; 5813 let Inst{28-24} = 0b11110; 5814 let Inst{23-22} = size; 5815 let Inst{21} = 0b1; 5816 let Inst{20-19} = size2; 5817 let Inst{18-17} = 0b00; 5818 let Inst{16-12} = opcode; 5819 let Inst{11-10} = 0b10; 5820 let Inst{9-5} = Rn; 5821 let Inst{4-0} = Rd; 5822} 5823 5824let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5825class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 5826 RegisterClass regtype, RegisterClass regtype2, 5827 string asm, list<dag> pat> 5828 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 5829 "\t$Rd, $Rn", "$Rd = $dst", pat>, 5830 Sched<[WriteV]> { 5831 bits<5> Rd; 5832 bits<5> Rn; 5833 let Inst{31-30} = 0b01; 5834 let Inst{29} = U; 5835 let Inst{28-24} = 0b11110; 5836 let Inst{23-22} = size; 5837 let Inst{21-17} = 0b10000; 5838 let Inst{16-12} = opcode; 5839 let Inst{11-10} = 0b10; 5840 let Inst{9-5} = Rn; 5841 let Inst{4-0} = Rd; 5842} 5843 5844 5845let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5846class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode, 5847 RegisterClass regtype, string asm, string zero> 5848 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5849 "\t$Rd, $Rn, #" # zero, "", []>, 5850 Sched<[WriteV]> { 5851 bits<5> Rd; 5852 bits<5> Rn; 5853 let Inst{31-30} = 0b01; 5854 let Inst{29} = U; 5855 let Inst{28-24} = 0b11110; 5856 let Inst{23-22} = size; 5857 let Inst{21} = 0b1; 5858 let Inst{20-19} = size2; 5859 let Inst{18-17} = 0b00; 5860 let Inst{16-12} = opcode; 5861 let Inst{11-10} = 0b10; 5862 let Inst{9-5} = Rn; 5863 let Inst{4-0} = Rd; 5864} 5865 5866class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 5867 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 5868 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 5869 Sched<[WriteV]> { 5870 bits<5> Rd; 5871 bits<5> Rn; 5872 let Inst{31-17} = 0b011111100110000; 5873 let Inst{16-12} = opcode; 5874 let Inst{11-10} = 0b10; 5875 let Inst{9-5} = Rn; 5876 let Inst{4-0} = Rd; 5877} 5878 5879multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 5880 SDPatternOperator OpNode> { 5881 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">; 5882 5883 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 5884 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 5885} 5886 5887multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm, 5888 SDPatternOperator OpNode> { 5889 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">; 5890 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">; 5891 let Predicates = [HasNEON, HasFullFP16] in { 5892 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">; 5893 } 5894 5895 def : InstAlias<asm # "\t$Rd, $Rn, #0", 5896 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 5897 def : InstAlias<asm # "\t$Rd, $Rn, #0", 5898 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 5899 let Predicates = [HasNEON, HasFullFP16] in { 5900 def : InstAlias<asm # "\t$Rd, $Rn, #0", 5901 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>; 5902 } 5903 5904 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 5905 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 5906} 5907 5908multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 5909 SDPatternOperator OpNode = null_frag> { 5910 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 5911 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 5912 5913 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 5914 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 5915} 5916 5917multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> { 5918 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>; 5919 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>; 5920 let Predicates = [HasNEON, HasFullFP16] in { 5921 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>; 5922 } 5923} 5924 5925multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm, 5926 SDPatternOperator OpNode> { 5927 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm, 5928 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 5929 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm, 5930 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 5931 let Predicates = [HasNEON, HasFullFP16] in { 5932 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm, 5933 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>; 5934 } 5935} 5936 5937multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 5938 SDPatternOperator OpNode = null_frag> { 5939 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5940 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm, 5941 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 5942 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm, 5943 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 5944 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>; 5945 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>; 5946 } 5947 5948 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 5949 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 5950} 5951 5952multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 5953 Intrinsic OpNode> { 5954 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5955 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 5956 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 5957 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 5958 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 5959 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 5960 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 5961 } 5962 5963 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 5964 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 5965} 5966 5967 5968 5969let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5970multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 5971 SDPatternOperator OpNode = null_frag> { 5972 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm, 5973 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 5974 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>; 5975 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>; 5976} 5977 5978//---------------------------------------------------------------------------- 5979// AdvSIMD scalar pairwise instructions 5980//---------------------------------------------------------------------------- 5981 5982let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5983class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 5984 RegisterOperand regtype, RegisterOperand vectype, 5985 string asm, string kind> 5986 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 5987 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 5988 Sched<[WriteV]> { 5989 bits<5> Rd; 5990 bits<5> Rn; 5991 let Inst{31-30} = 0b01; 5992 let Inst{29} = U; 5993 let Inst{28-24} = 0b11110; 5994 let Inst{23-22} = size; 5995 let Inst{21-17} = 0b11000; 5996 let Inst{16-12} = opcode; 5997 let Inst{11-10} = 0b10; 5998 let Inst{9-5} = Rn; 5999 let Inst{4-0} = Rd; 6000} 6001 6002multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 6003 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 6004 asm, ".2d">; 6005} 6006 6007multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> { 6008 let Predicates = [HasNEON, HasFullFP16] in { 6009 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64, 6010 asm, ".2h">; 6011 } 6012 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64, 6013 asm, ".2s">; 6014 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128, 6015 asm, ".2d">; 6016} 6017 6018//---------------------------------------------------------------------------- 6019// AdvSIMD across lanes instructions 6020//---------------------------------------------------------------------------- 6021 6022let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6023class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 6024 RegisterClass regtype, RegisterOperand vectype, 6025 string asm, string kind, list<dag> pattern> 6026 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 6027 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 6028 Sched<[WriteV]> { 6029 bits<5> Rd; 6030 bits<5> Rn; 6031 let Inst{31} = 0; 6032 let Inst{30} = Q; 6033 let Inst{29} = U; 6034 let Inst{28-24} = 0b01110; 6035 let Inst{23-22} = size; 6036 let Inst{21-17} = 0b11000; 6037 let Inst{16-12} = opcode; 6038 let Inst{11-10} = 0b10; 6039 let Inst{9-5} = Rn; 6040 let Inst{4-0} = Rd; 6041} 6042 6043multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 6044 string asm> { 6045 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 6046 asm, ".8b", []>; 6047 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 6048 asm, ".16b", []>; 6049 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 6050 asm, ".4h", []>; 6051 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 6052 asm, ".8h", []>; 6053 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 6054 asm, ".4s", []>; 6055} 6056 6057multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 6058 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 6059 asm, ".8b", []>; 6060 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 6061 asm, ".16b", []>; 6062 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 6063 asm, ".4h", []>; 6064 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 6065 asm, ".8h", []>; 6066 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 6067 asm, ".4s", []>; 6068} 6069 6070multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm, 6071 Intrinsic intOp> { 6072 let Predicates = [HasNEON, HasFullFP16] in { 6073 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64, 6074 asm, ".4h", 6075 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>; 6076 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128, 6077 asm, ".8h", 6078 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>; 6079 } // Predicates = [HasNEON, HasFullFP16] 6080 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 6081 asm, ".4s", 6082 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 6083} 6084 6085//---------------------------------------------------------------------------- 6086// AdvSIMD INS/DUP instructions 6087//---------------------------------------------------------------------------- 6088 6089// FIXME: There has got to be a better way to factor these. ugh. 6090 6091class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 6092 string operands, string constraints, list<dag> pattern> 6093 : I<outs, ins, asm, operands, constraints, pattern>, 6094 Sched<[WriteV]> { 6095 bits<5> Rd; 6096 bits<5> Rn; 6097 let Inst{31} = 0; 6098 let Inst{30} = Q; 6099 let Inst{29} = op; 6100 let Inst{28-21} = 0b01110000; 6101 let Inst{15} = 0; 6102 let Inst{10} = 1; 6103 let Inst{9-5} = Rn; 6104 let Inst{4-0} = Rd; 6105} 6106 6107class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 6108 RegisterOperand vecreg, RegisterClass regtype> 6109 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 6110 "{\t$Rd" # size # ", $Rn" # 6111 "|" # size # "\t$Rd, $Rn}", "", 6112 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 6113 let Inst{20-16} = imm5; 6114 let Inst{14-11} = 0b0001; 6115} 6116 6117class SIMDDupFromElement<bit Q, string dstkind, string srckind, 6118 ValueType vectype, ValueType insreg, 6119 RegisterOperand vecreg, Operand idxtype, 6120 ValueType elttype, SDNode OpNode> 6121 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 6122 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 6123 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 6124 [(set (vectype vecreg:$Rd), 6125 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 6126 let Inst{14-11} = 0b0000; 6127} 6128 6129class SIMDDup64FromElement 6130 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 6131 VectorIndexD, i64, AArch64duplane64> { 6132 bits<1> idx; 6133 let Inst{20} = idx; 6134 let Inst{19-16} = 0b1000; 6135} 6136 6137class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 6138 RegisterOperand vecreg> 6139 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 6140 VectorIndexS, i64, AArch64duplane32> { 6141 bits<2> idx; 6142 let Inst{20-19} = idx; 6143 let Inst{18-16} = 0b100; 6144} 6145 6146class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 6147 RegisterOperand vecreg> 6148 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 6149 VectorIndexH, i64, AArch64duplane16> { 6150 bits<3> idx; 6151 let Inst{20-18} = idx; 6152 let Inst{17-16} = 0b10; 6153} 6154 6155class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 6156 RegisterOperand vecreg> 6157 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 6158 VectorIndexB, i64, AArch64duplane8> { 6159 bits<4> idx; 6160 let Inst{20-17} = idx; 6161 let Inst{16} = 1; 6162} 6163 6164class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 6165 Operand idxtype, string asm, list<dag> pattern> 6166 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 6167 "{\t$Rd, $Rn" # size # "$idx" # 6168 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 6169 let Inst{14-11} = imm4; 6170} 6171 6172class SIMDSMov<bit Q, string size, RegisterClass regtype, 6173 Operand idxtype> 6174 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 6175class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 6176 Operand idxtype> 6177 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 6178 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 6179 6180class SIMDMovAlias<string asm, string size, Instruction inst, 6181 RegisterClass regtype, Operand idxtype> 6182 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 6183 "|" # size # "\t$dst, $src$idx}", 6184 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 6185 6186multiclass SMov { 6187 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 6188 bits<4> idx; 6189 let Inst{20-17} = idx; 6190 let Inst{16} = 1; 6191 } 6192 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 6193 bits<4> idx; 6194 let Inst{20-17} = idx; 6195 let Inst{16} = 1; 6196 } 6197 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 6198 bits<3> idx; 6199 let Inst{20-18} = idx; 6200 let Inst{17-16} = 0b10; 6201 } 6202 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 6203 bits<3> idx; 6204 let Inst{20-18} = idx; 6205 let Inst{17-16} = 0b10; 6206 } 6207 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 6208 bits<2> idx; 6209 let Inst{20-19} = idx; 6210 let Inst{18-16} = 0b100; 6211 } 6212} 6213 6214multiclass UMov { 6215 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 6216 bits<4> idx; 6217 let Inst{20-17} = idx; 6218 let Inst{16} = 1; 6219 } 6220 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 6221 bits<3> idx; 6222 let Inst{20-18} = idx; 6223 let Inst{17-16} = 0b10; 6224 } 6225 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 6226 bits<2> idx; 6227 let Inst{20-19} = idx; 6228 let Inst{18-16} = 0b100; 6229 } 6230 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 6231 bits<1> idx; 6232 let Inst{20} = idx; 6233 let Inst{19-16} = 0b1000; 6234 } 6235 def : SIMDMovAlias<"mov", ".s", 6236 !cast<Instruction>(NAME#"vi32"), 6237 GPR32, VectorIndexS>; 6238 def : SIMDMovAlias<"mov", ".d", 6239 !cast<Instruction>(NAME#"vi64"), 6240 GPR64, VectorIndexD>; 6241} 6242 6243class SIMDInsFromMain<string size, ValueType vectype, 6244 RegisterClass regtype, Operand idxtype> 6245 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 6246 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 6247 "{\t$Rd" # size # "$idx, $Rn" # 6248 "|" # size # "\t$Rd$idx, $Rn}", 6249 "$Rd = $dst", 6250 [(set V128:$dst, 6251 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 6252 let Inst{14-11} = 0b0011; 6253} 6254 6255class SIMDInsFromElement<string size, ValueType vectype, 6256 ValueType elttype, Operand idxtype> 6257 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 6258 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 6259 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 6260 "|" # size # "\t$Rd$idx, $Rn$idx2}", 6261 "$Rd = $dst", 6262 [(set V128:$dst, 6263 (vector_insert 6264 (vectype V128:$Rd), 6265 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 6266 idxtype:$idx))]>; 6267 6268class SIMDInsMainMovAlias<string size, Instruction inst, 6269 RegisterClass regtype, Operand idxtype> 6270 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 6271 "|" # size #"\t$dst$idx, $src}", 6272 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 6273class SIMDInsElementMovAlias<string size, Instruction inst, 6274 Operand idxtype> 6275 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" # 6276 # "|" # size #"\t$dst$idx, $src$idx2}", 6277 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 6278 6279 6280multiclass SIMDIns { 6281 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 6282 bits<4> idx; 6283 let Inst{20-17} = idx; 6284 let Inst{16} = 1; 6285 } 6286 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 6287 bits<3> idx; 6288 let Inst{20-18} = idx; 6289 let Inst{17-16} = 0b10; 6290 } 6291 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 6292 bits<2> idx; 6293 let Inst{20-19} = idx; 6294 let Inst{18-16} = 0b100; 6295 } 6296 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 6297 bits<1> idx; 6298 let Inst{20} = idx; 6299 let Inst{19-16} = 0b1000; 6300 } 6301 6302 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 6303 bits<4> idx; 6304 bits<4> idx2; 6305 let Inst{20-17} = idx; 6306 let Inst{16} = 1; 6307 let Inst{14-11} = idx2; 6308 } 6309 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 6310 bits<3> idx; 6311 bits<3> idx2; 6312 let Inst{20-18} = idx; 6313 let Inst{17-16} = 0b10; 6314 let Inst{14-12} = idx2; 6315 let Inst{11} = {?}; 6316 } 6317 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 6318 bits<2> idx; 6319 bits<2> idx2; 6320 let Inst{20-19} = idx; 6321 let Inst{18-16} = 0b100; 6322 let Inst{14-13} = idx2; 6323 let Inst{12-11} = {?,?}; 6324 } 6325 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 6326 bits<1> idx; 6327 bits<1> idx2; 6328 let Inst{20} = idx; 6329 let Inst{19-16} = 0b1000; 6330 let Inst{14} = idx2; 6331 let Inst{13-11} = {?,?,?}; 6332 } 6333 6334 // For all forms of the INS instruction, the "mov" mnemonic is the 6335 // preferred alias. Why they didn't just call the instruction "mov" in 6336 // the first place is a very good question indeed... 6337 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 6338 GPR32, VectorIndexB>; 6339 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 6340 GPR32, VectorIndexH>; 6341 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 6342 GPR32, VectorIndexS>; 6343 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 6344 GPR64, VectorIndexD>; 6345 6346 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 6347 VectorIndexB>; 6348 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 6349 VectorIndexH>; 6350 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 6351 VectorIndexS>; 6352 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 6353 VectorIndexD>; 6354} 6355 6356//---------------------------------------------------------------------------- 6357// AdvSIMD TBL/TBX 6358//---------------------------------------------------------------------------- 6359 6360let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6361class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 6362 RegisterOperand listtype, string asm, string kind> 6363 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 6364 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 6365 Sched<[WriteV]> { 6366 bits<5> Vd; 6367 bits<5> Vn; 6368 bits<5> Vm; 6369 let Inst{31} = 0; 6370 let Inst{30} = Q; 6371 let Inst{29-21} = 0b001110000; 6372 let Inst{20-16} = Vm; 6373 let Inst{15} = 0; 6374 let Inst{14-13} = len; 6375 let Inst{12} = op; 6376 let Inst{11-10} = 0b00; 6377 let Inst{9-5} = Vn; 6378 let Inst{4-0} = Vd; 6379} 6380 6381let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 6382class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 6383 RegisterOperand listtype, string asm, string kind> 6384 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 6385 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 6386 Sched<[WriteV]> { 6387 bits<5> Vd; 6388 bits<5> Vn; 6389 bits<5> Vm; 6390 let Inst{31} = 0; 6391 let Inst{30} = Q; 6392 let Inst{29-21} = 0b001110000; 6393 let Inst{20-16} = Vm; 6394 let Inst{15} = 0; 6395 let Inst{14-13} = len; 6396 let Inst{12} = op; 6397 let Inst{11-10} = 0b00; 6398 let Inst{9-5} = Vn; 6399 let Inst{4-0} = Vd; 6400} 6401 6402class SIMDTableLookupAlias<string asm, Instruction inst, 6403 RegisterOperand vectype, RegisterOperand listtype> 6404 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 6405 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 6406 6407multiclass SIMDTableLookup<bit op, string asm> { 6408 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 6409 asm, ".8b">; 6410 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 6411 asm, ".8b">; 6412 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 6413 asm, ".8b">; 6414 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 6415 asm, ".8b">; 6416 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 6417 asm, ".16b">; 6418 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 6419 asm, ".16b">; 6420 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 6421 asm, ".16b">; 6422 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 6423 asm, ".16b">; 6424 6425 def : SIMDTableLookupAlias<asm # ".8b", 6426 !cast<Instruction>(NAME#"v8i8One"), 6427 V64, VecListOne128>; 6428 def : SIMDTableLookupAlias<asm # ".8b", 6429 !cast<Instruction>(NAME#"v8i8Two"), 6430 V64, VecListTwo128>; 6431 def : SIMDTableLookupAlias<asm # ".8b", 6432 !cast<Instruction>(NAME#"v8i8Three"), 6433 V64, VecListThree128>; 6434 def : SIMDTableLookupAlias<asm # ".8b", 6435 !cast<Instruction>(NAME#"v8i8Four"), 6436 V64, VecListFour128>; 6437 def : SIMDTableLookupAlias<asm # ".16b", 6438 !cast<Instruction>(NAME#"v16i8One"), 6439 V128, VecListOne128>; 6440 def : SIMDTableLookupAlias<asm # ".16b", 6441 !cast<Instruction>(NAME#"v16i8Two"), 6442 V128, VecListTwo128>; 6443 def : SIMDTableLookupAlias<asm # ".16b", 6444 !cast<Instruction>(NAME#"v16i8Three"), 6445 V128, VecListThree128>; 6446 def : SIMDTableLookupAlias<asm # ".16b", 6447 !cast<Instruction>(NAME#"v16i8Four"), 6448 V128, VecListFour128>; 6449} 6450 6451multiclass SIMDTableLookupTied<bit op, string asm> { 6452 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 6453 asm, ".8b">; 6454 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 6455 asm, ".8b">; 6456 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 6457 asm, ".8b">; 6458 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 6459 asm, ".8b">; 6460 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 6461 asm, ".16b">; 6462 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 6463 asm, ".16b">; 6464 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 6465 asm, ".16b">; 6466 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 6467 asm, ".16b">; 6468 6469 def : SIMDTableLookupAlias<asm # ".8b", 6470 !cast<Instruction>(NAME#"v8i8One"), 6471 V64, VecListOne128>; 6472 def : SIMDTableLookupAlias<asm # ".8b", 6473 !cast<Instruction>(NAME#"v8i8Two"), 6474 V64, VecListTwo128>; 6475 def : SIMDTableLookupAlias<asm # ".8b", 6476 !cast<Instruction>(NAME#"v8i8Three"), 6477 V64, VecListThree128>; 6478 def : SIMDTableLookupAlias<asm # ".8b", 6479 !cast<Instruction>(NAME#"v8i8Four"), 6480 V64, VecListFour128>; 6481 def : SIMDTableLookupAlias<asm # ".16b", 6482 !cast<Instruction>(NAME#"v16i8One"), 6483 V128, VecListOne128>; 6484 def : SIMDTableLookupAlias<asm # ".16b", 6485 !cast<Instruction>(NAME#"v16i8Two"), 6486 V128, VecListTwo128>; 6487 def : SIMDTableLookupAlias<asm # ".16b", 6488 !cast<Instruction>(NAME#"v16i8Three"), 6489 V128, VecListThree128>; 6490 def : SIMDTableLookupAlias<asm # ".16b", 6491 !cast<Instruction>(NAME#"v16i8Four"), 6492 V128, VecListFour128>; 6493} 6494 6495 6496//---------------------------------------------------------------------------- 6497// AdvSIMD scalar CPY 6498//---------------------------------------------------------------------------- 6499let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6500class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 6501 string kind, Operand idxtype> 6502 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 6503 "{\t$dst, $src" # kind # "$idx" # 6504 "|\t$dst, $src$idx}", "", []>, 6505 Sched<[WriteV]> { 6506 bits<5> dst; 6507 bits<5> src; 6508 let Inst{31-21} = 0b01011110000; 6509 let Inst{15-10} = 0b000001; 6510 let Inst{9-5} = src; 6511 let Inst{4-0} = dst; 6512} 6513 6514class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 6515 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 6516 : InstAlias<asm # "{\t$dst, $src" # size # "$index" # 6517 # "|\t$dst, $src$index}", 6518 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 6519 6520 6521multiclass SIMDScalarCPY<string asm> { 6522 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 6523 bits<4> idx; 6524 let Inst{20-17} = idx; 6525 let Inst{16} = 1; 6526 } 6527 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 6528 bits<3> idx; 6529 let Inst{20-18} = idx; 6530 let Inst{17-16} = 0b10; 6531 } 6532 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 6533 bits<2> idx; 6534 let Inst{20-19} = idx; 6535 let Inst{18-16} = 0b100; 6536 } 6537 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 6538 bits<1> idx; 6539 let Inst{20} = idx; 6540 let Inst{19-16} = 0b1000; 6541 } 6542 6543 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 6544 VectorIndexD:$idx)))), 6545 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 6546 6547 // 'DUP' mnemonic aliases. 6548 def : SIMDScalarCPYAlias<"dup", ".b", 6549 !cast<Instruction>(NAME#"i8"), 6550 FPR8, V128, VectorIndexB>; 6551 def : SIMDScalarCPYAlias<"dup", ".h", 6552 !cast<Instruction>(NAME#"i16"), 6553 FPR16, V128, VectorIndexH>; 6554 def : SIMDScalarCPYAlias<"dup", ".s", 6555 !cast<Instruction>(NAME#"i32"), 6556 FPR32, V128, VectorIndexS>; 6557 def : SIMDScalarCPYAlias<"dup", ".d", 6558 !cast<Instruction>(NAME#"i64"), 6559 FPR64, V128, VectorIndexD>; 6560} 6561 6562//---------------------------------------------------------------------------- 6563// AdvSIMD modified immediate instructions 6564//---------------------------------------------------------------------------- 6565 6566class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops, 6567 string asm, string op_string, 6568 string cstr, list<dag> pattern> 6569 : I<oops, iops, asm, op_string, cstr, pattern>, 6570 Sched<[WriteV]> { 6571 bits<5> Rd; 6572 bits<8> imm8; 6573 let Inst{31} = 0; 6574 let Inst{30} = Q; 6575 let Inst{29} = op; 6576 let Inst{28-19} = 0b0111100000; 6577 let Inst{18-16} = imm8{7-5}; 6578 let Inst{11} = op2; 6579 let Inst{10} = 1; 6580 let Inst{9-5} = imm8{4-0}; 6581 let Inst{4-0} = Rd; 6582} 6583 6584class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype, 6585 Operand immtype, dag opt_shift_iop, 6586 string opt_shift, string asm, string kind, 6587 list<dag> pattern> 6588 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd), 6589 !con((ins immtype:$imm8), opt_shift_iop), asm, 6590 "{\t$Rd" # kind # ", $imm8" # opt_shift # 6591 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 6592 "", pattern> { 6593 let DecoderMethod = "DecodeModImmInstruction"; 6594} 6595 6596class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 6597 Operand immtype, dag opt_shift_iop, 6598 string opt_shift, string asm, string kind, 6599 list<dag> pattern> 6600 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst), 6601 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 6602 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 6603 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 6604 "$Rd = $dst", pattern> { 6605 let DecoderMethod = "DecodeModImmTiedInstruction"; 6606} 6607 6608class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 6609 RegisterOperand vectype, string asm, 6610 string kind, list<dag> pattern> 6611 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 6612 (ins logical_vec_shift:$shift), 6613 "$shift", asm, kind, pattern> { 6614 bits<2> shift; 6615 let Inst{15} = b15_b12{1}; 6616 let Inst{14-13} = shift; 6617 let Inst{12} = b15_b12{0}; 6618} 6619 6620class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 6621 RegisterOperand vectype, string asm, 6622 string kind, list<dag> pattern> 6623 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 6624 (ins logical_vec_shift:$shift), 6625 "$shift", asm, kind, pattern> { 6626 bits<2> shift; 6627 let Inst{15} = b15_b12{1}; 6628 let Inst{14-13} = shift; 6629 let Inst{12} = b15_b12{0}; 6630} 6631 6632 6633class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 6634 RegisterOperand vectype, string asm, 6635 string kind, list<dag> pattern> 6636 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 6637 (ins logical_vec_hw_shift:$shift), 6638 "$shift", asm, kind, pattern> { 6639 bits<2> shift; 6640 let Inst{15} = b15_b12{1}; 6641 let Inst{14} = 0; 6642 let Inst{13} = shift{0}; 6643 let Inst{12} = b15_b12{0}; 6644} 6645 6646class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 6647 RegisterOperand vectype, string asm, 6648 string kind, list<dag> pattern> 6649 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 6650 (ins logical_vec_hw_shift:$shift), 6651 "$shift", asm, kind, pattern> { 6652 bits<2> shift; 6653 let Inst{15} = b15_b12{1}; 6654 let Inst{14} = 0; 6655 let Inst{13} = shift{0}; 6656 let Inst{12} = b15_b12{0}; 6657} 6658 6659multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 6660 string asm> { 6661 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 6662 asm, ".4h", []>; 6663 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 6664 asm, ".8h", []>; 6665 6666 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 6667 asm, ".2s", []>; 6668 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 6669 asm, ".4s", []>; 6670} 6671 6672multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 6673 bits<2> w_cmode, string asm, 6674 SDNode OpNode> { 6675 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 6676 asm, ".4h", 6677 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 6678 imm0_255:$imm8, 6679 (i32 imm:$shift)))]>; 6680 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 6681 asm, ".8h", 6682 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 6683 imm0_255:$imm8, 6684 (i32 imm:$shift)))]>; 6685 6686 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 6687 asm, ".2s", 6688 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 6689 imm0_255:$imm8, 6690 (i32 imm:$shift)))]>; 6691 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 6692 asm, ".4s", 6693 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 6694 imm0_255:$imm8, 6695 (i32 imm:$shift)))]>; 6696} 6697 6698class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 6699 RegisterOperand vectype, string asm, 6700 string kind, list<dag> pattern> 6701 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255, 6702 (ins move_vec_shift:$shift), 6703 "$shift", asm, kind, pattern> { 6704 bits<1> shift; 6705 let Inst{15-13} = cmode{3-1}; 6706 let Inst{12} = shift; 6707} 6708 6709class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode, 6710 RegisterOperand vectype, 6711 Operand imm_type, string asm, 6712 string kind, list<dag> pattern> 6713 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "", 6714 asm, kind, pattern> { 6715 let Inst{15-12} = cmode; 6716} 6717 6718class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 6719 list<dag> pattern> 6720 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 6721 "\t$Rd, $imm8", "", pattern> { 6722 let Inst{15-12} = cmode; 6723 let DecoderMethod = "DecodeModImmInstruction"; 6724} 6725 6726//---------------------------------------------------------------------------- 6727// AdvSIMD indexed element 6728//---------------------------------------------------------------------------- 6729 6730let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6731class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 6732 RegisterOperand dst_reg, RegisterOperand lhs_reg, 6733 RegisterOperand rhs_reg, Operand vec_idx, string asm, 6734 string apple_kind, string dst_kind, string lhs_kind, 6735 string rhs_kind, list<dag> pattern> 6736 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 6737 asm, 6738 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 6739 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 6740 Sched<[WriteV]> { 6741 bits<5> Rd; 6742 bits<5> Rn; 6743 bits<5> Rm; 6744 6745 let Inst{31} = 0; 6746 let Inst{30} = Q; 6747 let Inst{29} = U; 6748 let Inst{28} = Scalar; 6749 let Inst{27-24} = 0b1111; 6750 let Inst{23-22} = size; 6751 // Bit 21 must be set by the derived class. 6752 let Inst{20-16} = Rm; 6753 let Inst{15-12} = opc; 6754 // Bit 11 must be set by the derived class. 6755 let Inst{10} = 0; 6756 let Inst{9-5} = Rn; 6757 let Inst{4-0} = Rd; 6758} 6759 6760let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6761class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 6762 RegisterOperand dst_reg, RegisterOperand lhs_reg, 6763 RegisterOperand rhs_reg, Operand vec_idx, string asm, 6764 string apple_kind, string dst_kind, string lhs_kind, 6765 string rhs_kind, list<dag> pattern> 6766 : I<(outs dst_reg:$dst), 6767 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 6768 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 6769 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 6770 Sched<[WriteV]> { 6771 bits<5> Rd; 6772 bits<5> Rn; 6773 bits<5> Rm; 6774 6775 let Inst{31} = 0; 6776 let Inst{30} = Q; 6777 let Inst{29} = U; 6778 let Inst{28} = Scalar; 6779 let Inst{27-24} = 0b1111; 6780 let Inst{23-22} = size; 6781 // Bit 21 must be set by the derived class. 6782 let Inst{20-16} = Rm; 6783 let Inst{15-12} = opc; 6784 // Bit 11 must be set by the derived class. 6785 let Inst{10} = 0; 6786 let Inst{9-5} = Rn; 6787 let Inst{4-0} = Rd; 6788} 6789 6790multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm, 6791 SDPatternOperator OpNode> { 6792 let Predicates = [HasNEON, HasFullFP16] in { 6793 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc, 6794 V64, V64, 6795 V128_lo, VectorIndexH, 6796 asm, ".4h", ".4h", ".4h", ".h", 6797 [(set (v4f16 V64:$Rd), 6798 (OpNode (v4f16 V64:$Rn), 6799 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6800 bits<3> idx; 6801 let Inst{11} = idx{2}; 6802 let Inst{21} = idx{1}; 6803 let Inst{20} = idx{0}; 6804 } 6805 6806 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc, 6807 V128, V128, 6808 V128_lo, VectorIndexH, 6809 asm, ".8h", ".8h", ".8h", ".h", 6810 [(set (v8f16 V128:$Rd), 6811 (OpNode (v8f16 V128:$Rn), 6812 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6813 bits<3> idx; 6814 let Inst{11} = idx{2}; 6815 let Inst{21} = idx{1}; 6816 let Inst{20} = idx{0}; 6817 } 6818 } // Predicates = [HasNEON, HasFullFP16] 6819 6820 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6821 V64, V64, 6822 V128, VectorIndexS, 6823 asm, ".2s", ".2s", ".2s", ".s", 6824 [(set (v2f32 V64:$Rd), 6825 (OpNode (v2f32 V64:$Rn), 6826 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 6827 bits<2> idx; 6828 let Inst{11} = idx{1}; 6829 let Inst{21} = idx{0}; 6830 } 6831 6832 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6833 V128, V128, 6834 V128, VectorIndexS, 6835 asm, ".4s", ".4s", ".4s", ".s", 6836 [(set (v4f32 V128:$Rd), 6837 (OpNode (v4f32 V128:$Rn), 6838 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 6839 bits<2> idx; 6840 let Inst{11} = idx{1}; 6841 let Inst{21} = idx{0}; 6842 } 6843 6844 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 6845 V128, V128, 6846 V128, VectorIndexD, 6847 asm, ".2d", ".2d", ".2d", ".d", 6848 [(set (v2f64 V128:$Rd), 6849 (OpNode (v2f64 V128:$Rn), 6850 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 6851 bits<1> idx; 6852 let Inst{11} = idx{0}; 6853 let Inst{21} = 0; 6854 } 6855 6856 let Predicates = [HasNEON, HasFullFP16] in { 6857 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc, 6858 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 6859 asm, ".h", "", "", ".h", 6860 [(set (f16 FPR16Op:$Rd), 6861 (OpNode (f16 FPR16Op:$Rn), 6862 (f16 (vector_extract (v8f16 V128_lo:$Rm), 6863 VectorIndexH:$idx))))]> { 6864 bits<3> idx; 6865 let Inst{11} = idx{2}; 6866 let Inst{21} = idx{1}; 6867 let Inst{20} = idx{0}; 6868 } 6869 } // Predicates = [HasNEON, HasFullFP16] 6870 6871 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 6872 FPR32Op, FPR32Op, V128, VectorIndexS, 6873 asm, ".s", "", "", ".s", 6874 [(set (f32 FPR32Op:$Rd), 6875 (OpNode (f32 FPR32Op:$Rn), 6876 (f32 (vector_extract (v4f32 V128:$Rm), 6877 VectorIndexS:$idx))))]> { 6878 bits<2> idx; 6879 let Inst{11} = idx{1}; 6880 let Inst{21} = idx{0}; 6881 } 6882 6883 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 6884 FPR64Op, FPR64Op, V128, VectorIndexD, 6885 asm, ".d", "", "", ".d", 6886 [(set (f64 FPR64Op:$Rd), 6887 (OpNode (f64 FPR64Op:$Rn), 6888 (f64 (vector_extract (v2f64 V128:$Rm), 6889 VectorIndexD:$idx))))]> { 6890 bits<1> idx; 6891 let Inst{11} = idx{0}; 6892 let Inst{21} = 0; 6893 } 6894} 6895 6896multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> { 6897 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 6898 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 6899 (AArch64duplane32 (v4f32 V128:$Rm), 6900 VectorIndexS:$idx))), 6901 (!cast<Instruction>(INST # v2i32_indexed) 6902 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6903 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 6904 (AArch64dup (f32 FPR32Op:$Rm)))), 6905 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 6906 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 6907 6908 6909 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 6910 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 6911 (AArch64duplane32 (v4f32 V128:$Rm), 6912 VectorIndexS:$idx))), 6913 (!cast<Instruction>(INST # "v4i32_indexed") 6914 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6915 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 6916 (AArch64dup (f32 FPR32Op:$Rm)))), 6917 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 6918 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 6919 6920 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 6921 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 6922 (AArch64duplane64 (v2f64 V128:$Rm), 6923 VectorIndexD:$idx))), 6924 (!cast<Instruction>(INST # "v2i64_indexed") 6925 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6926 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 6927 (AArch64dup (f64 FPR64Op:$Rm)))), 6928 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 6929 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 6930 6931 // 2 variants for 32-bit scalar version: extract from .2s or from .4s 6932 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 6933 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 6934 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 6935 V128:$Rm, VectorIndexS:$idx)>; 6936 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 6937 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))), 6938 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 6939 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>; 6940 6941 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 6942 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 6943 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 6944 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 6945 V128:$Rm, VectorIndexD:$idx)>; 6946} 6947 6948multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> { 6949 let Predicates = [HasNEON, HasFullFP16] in { 6950 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64, 6951 V128_lo, VectorIndexH, 6952 asm, ".4h", ".4h", ".4h", ".h", []> { 6953 bits<3> idx; 6954 let Inst{11} = idx{2}; 6955 let Inst{21} = idx{1}; 6956 let Inst{20} = idx{0}; 6957 } 6958 6959 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc, 6960 V128, V128, 6961 V128_lo, VectorIndexH, 6962 asm, ".8h", ".8h", ".8h", ".h", []> { 6963 bits<3> idx; 6964 let Inst{11} = idx{2}; 6965 let Inst{21} = idx{1}; 6966 let Inst{20} = idx{0}; 6967 } 6968 } // Predicates = [HasNEON, HasFullFP16] 6969 6970 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 6971 V128, VectorIndexS, 6972 asm, ".2s", ".2s", ".2s", ".s", []> { 6973 bits<2> idx; 6974 let Inst{11} = idx{1}; 6975 let Inst{21} = idx{0}; 6976 } 6977 6978 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 6979 V128, V128, 6980 V128, VectorIndexS, 6981 asm, ".4s", ".4s", ".4s", ".s", []> { 6982 bits<2> idx; 6983 let Inst{11} = idx{1}; 6984 let Inst{21} = idx{0}; 6985 } 6986 6987 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 6988 V128, V128, 6989 V128, VectorIndexD, 6990 asm, ".2d", ".2d", ".2d", ".d", []> { 6991 bits<1> idx; 6992 let Inst{11} = idx{0}; 6993 let Inst{21} = 0; 6994 } 6995 6996 let Predicates = [HasNEON, HasFullFP16] in { 6997 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc, 6998 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 6999 asm, ".h", "", "", ".h", []> { 7000 bits<3> idx; 7001 let Inst{11} = idx{2}; 7002 let Inst{21} = idx{1}; 7003 let Inst{20} = idx{0}; 7004 } 7005 } // Predicates = [HasNEON, HasFullFP16] 7006 7007 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 7008 FPR32Op, FPR32Op, V128, VectorIndexS, 7009 asm, ".s", "", "", ".s", []> { 7010 bits<2> idx; 7011 let Inst{11} = idx{1}; 7012 let Inst{21} = idx{0}; 7013 } 7014 7015 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 7016 FPR64Op, FPR64Op, V128, VectorIndexD, 7017 asm, ".d", "", "", ".d", []> { 7018 bits<1> idx; 7019 let Inst{11} = idx{0}; 7020 let Inst{21} = 0; 7021 } 7022} 7023 7024multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 7025 SDPatternOperator OpNode> { 7026 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 7027 V128_lo, VectorIndexH, 7028 asm, ".4h", ".4h", ".4h", ".h", 7029 [(set (v4i16 V64:$Rd), 7030 (OpNode (v4i16 V64:$Rn), 7031 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7032 bits<3> idx; 7033 let Inst{11} = idx{2}; 7034 let Inst{21} = idx{1}; 7035 let Inst{20} = idx{0}; 7036 } 7037 7038 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7039 V128, V128, 7040 V128_lo, VectorIndexH, 7041 asm, ".8h", ".8h", ".8h", ".h", 7042 [(set (v8i16 V128:$Rd), 7043 (OpNode (v8i16 V128:$Rn), 7044 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7045 bits<3> idx; 7046 let Inst{11} = idx{2}; 7047 let Inst{21} = idx{1}; 7048 let Inst{20} = idx{0}; 7049 } 7050 7051 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7052 V64, V64, 7053 V128, VectorIndexS, 7054 asm, ".2s", ".2s", ".2s", ".s", 7055 [(set (v2i32 V64:$Rd), 7056 (OpNode (v2i32 V64:$Rn), 7057 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7058 bits<2> idx; 7059 let Inst{11} = idx{1}; 7060 let Inst{21} = idx{0}; 7061 } 7062 7063 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7064 V128, V128, 7065 V128, VectorIndexS, 7066 asm, ".4s", ".4s", ".4s", ".s", 7067 [(set (v4i32 V128:$Rd), 7068 (OpNode (v4i32 V128:$Rn), 7069 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7070 bits<2> idx; 7071 let Inst{11} = idx{1}; 7072 let Inst{21} = idx{0}; 7073 } 7074 7075 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 7076 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 7077 asm, ".h", "", "", ".h", []> { 7078 bits<3> idx; 7079 let Inst{11} = idx{2}; 7080 let Inst{21} = idx{1}; 7081 let Inst{20} = idx{0}; 7082 } 7083 7084 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7085 FPR32Op, FPR32Op, V128, VectorIndexS, 7086 asm, ".s", "", "", ".s", 7087 [(set (i32 FPR32Op:$Rd), 7088 (OpNode FPR32Op:$Rn, 7089 (i32 (vector_extract (v4i32 V128:$Rm), 7090 VectorIndexS:$idx))))]> { 7091 bits<2> idx; 7092 let Inst{11} = idx{1}; 7093 let Inst{21} = idx{0}; 7094 } 7095} 7096 7097multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 7098 SDPatternOperator OpNode> { 7099 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7100 V64, V64, 7101 V128_lo, VectorIndexH, 7102 asm, ".4h", ".4h", ".4h", ".h", 7103 [(set (v4i16 V64:$Rd), 7104 (OpNode (v4i16 V64:$Rn), 7105 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7106 bits<3> idx; 7107 let Inst{11} = idx{2}; 7108 let Inst{21} = idx{1}; 7109 let Inst{20} = idx{0}; 7110 } 7111 7112 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7113 V128, V128, 7114 V128_lo, VectorIndexH, 7115 asm, ".8h", ".8h", ".8h", ".h", 7116 [(set (v8i16 V128:$Rd), 7117 (OpNode (v8i16 V128:$Rn), 7118 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7119 bits<3> idx; 7120 let Inst{11} = idx{2}; 7121 let Inst{21} = idx{1}; 7122 let Inst{20} = idx{0}; 7123 } 7124 7125 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7126 V64, V64, 7127 V128, VectorIndexS, 7128 asm, ".2s", ".2s", ".2s", ".s", 7129 [(set (v2i32 V64:$Rd), 7130 (OpNode (v2i32 V64:$Rn), 7131 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7132 bits<2> idx; 7133 let Inst{11} = idx{1}; 7134 let Inst{21} = idx{0}; 7135 } 7136 7137 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7138 V128, V128, 7139 V128, VectorIndexS, 7140 asm, ".4s", ".4s", ".4s", ".s", 7141 [(set (v4i32 V128:$Rd), 7142 (OpNode (v4i32 V128:$Rn), 7143 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7144 bits<2> idx; 7145 let Inst{11} = idx{1}; 7146 let Inst{21} = idx{0}; 7147 } 7148} 7149 7150multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 7151 SDPatternOperator OpNode> { 7152 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 7153 V128_lo, VectorIndexH, 7154 asm, ".4h", ".4h", ".4h", ".h", 7155 [(set (v4i16 V64:$dst), 7156 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 7157 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7158 bits<3> idx; 7159 let Inst{11} = idx{2}; 7160 let Inst{21} = idx{1}; 7161 let Inst{20} = idx{0}; 7162 } 7163 7164 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7165 V128, V128, 7166 V128_lo, VectorIndexH, 7167 asm, ".8h", ".8h", ".8h", ".h", 7168 [(set (v8i16 V128:$dst), 7169 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 7170 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7171 bits<3> idx; 7172 let Inst{11} = idx{2}; 7173 let Inst{21} = idx{1}; 7174 let Inst{20} = idx{0}; 7175 } 7176 7177 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7178 V64, V64, 7179 V128, VectorIndexS, 7180 asm, ".2s", ".2s", ".2s", ".s", 7181 [(set (v2i32 V64:$dst), 7182 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 7183 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7184 bits<2> idx; 7185 let Inst{11} = idx{1}; 7186 let Inst{21} = idx{0}; 7187 } 7188 7189 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7190 V128, V128, 7191 V128, VectorIndexS, 7192 asm, ".4s", ".4s", ".4s", ".s", 7193 [(set (v4i32 V128:$dst), 7194 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 7195 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7196 bits<2> idx; 7197 let Inst{11} = idx{1}; 7198 let Inst{21} = idx{0}; 7199 } 7200} 7201 7202multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 7203 SDPatternOperator OpNode> { 7204 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7205 V128, V64, 7206 V128_lo, VectorIndexH, 7207 asm, ".4s", ".4s", ".4h", ".h", 7208 [(set (v4i32 V128:$Rd), 7209 (OpNode (v4i16 V64:$Rn), 7210 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7211 bits<3> idx; 7212 let Inst{11} = idx{2}; 7213 let Inst{21} = idx{1}; 7214 let Inst{20} = idx{0}; 7215 } 7216 7217 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7218 V128, V128, 7219 V128_lo, VectorIndexH, 7220 asm#"2", ".4s", ".4s", ".8h", ".h", 7221 [(set (v4i32 V128:$Rd), 7222 (OpNode (extract_high_v8i16 V128:$Rn), 7223 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7224 VectorIndexH:$idx))))]> { 7225 7226 bits<3> idx; 7227 let Inst{11} = idx{2}; 7228 let Inst{21} = idx{1}; 7229 let Inst{20} = idx{0}; 7230 } 7231 7232 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7233 V128, V64, 7234 V128, VectorIndexS, 7235 asm, ".2d", ".2d", ".2s", ".s", 7236 [(set (v2i64 V128:$Rd), 7237 (OpNode (v2i32 V64:$Rn), 7238 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7239 bits<2> idx; 7240 let Inst{11} = idx{1}; 7241 let Inst{21} = idx{0}; 7242 } 7243 7244 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7245 V128, V128, 7246 V128, VectorIndexS, 7247 asm#"2", ".2d", ".2d", ".4s", ".s", 7248 [(set (v2i64 V128:$Rd), 7249 (OpNode (extract_high_v4i32 V128:$Rn), 7250 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 7251 VectorIndexS:$idx))))]> { 7252 bits<2> idx; 7253 let Inst{11} = idx{1}; 7254 let Inst{21} = idx{0}; 7255 } 7256 7257 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 7258 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 7259 asm, ".h", "", "", ".h", []> { 7260 bits<3> idx; 7261 let Inst{11} = idx{2}; 7262 let Inst{21} = idx{1}; 7263 let Inst{20} = idx{0}; 7264 } 7265 7266 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 7267 FPR64Op, FPR32Op, V128, VectorIndexS, 7268 asm, ".s", "", "", ".s", []> { 7269 bits<2> idx; 7270 let Inst{11} = idx{1}; 7271 let Inst{21} = idx{0}; 7272 } 7273} 7274 7275multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 7276 SDPatternOperator Accum> { 7277 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 7278 V128, V64, 7279 V128_lo, VectorIndexH, 7280 asm, ".4s", ".4s", ".4h", ".h", 7281 [(set (v4i32 V128:$dst), 7282 (Accum (v4i32 V128:$Rd), 7283 (v4i32 (int_aarch64_neon_sqdmull 7284 (v4i16 V64:$Rn), 7285 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7286 VectorIndexH:$idx))))))]> { 7287 bits<3> idx; 7288 let Inst{11} = idx{2}; 7289 let Inst{21} = idx{1}; 7290 let Inst{20} = idx{0}; 7291 } 7292 7293 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 7294 // intermediate EXTRACT_SUBREG would be untyped. 7295 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 7296 (i32 (vector_extract (v4i32 7297 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 7298 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7299 VectorIndexH:$idx)))), 7300 (i64 0))))), 7301 (EXTRACT_SUBREG 7302 (!cast<Instruction>(NAME # v4i16_indexed) 7303 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 7304 V128_lo:$Rm, VectorIndexH:$idx), 7305 ssub)>; 7306 7307 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7308 V128, V128, 7309 V128_lo, VectorIndexH, 7310 asm#"2", ".4s", ".4s", ".8h", ".h", 7311 [(set (v4i32 V128:$dst), 7312 (Accum (v4i32 V128:$Rd), 7313 (v4i32 (int_aarch64_neon_sqdmull 7314 (extract_high_v8i16 V128:$Rn), 7315 (extract_high_v8i16 7316 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7317 VectorIndexH:$idx))))))]> { 7318 bits<3> idx; 7319 let Inst{11} = idx{2}; 7320 let Inst{21} = idx{1}; 7321 let Inst{20} = idx{0}; 7322 } 7323 7324 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7325 V128, V64, 7326 V128, VectorIndexS, 7327 asm, ".2d", ".2d", ".2s", ".s", 7328 [(set (v2i64 V128:$dst), 7329 (Accum (v2i64 V128:$Rd), 7330 (v2i64 (int_aarch64_neon_sqdmull 7331 (v2i32 V64:$Rn), 7332 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 7333 VectorIndexS:$idx))))))]> { 7334 bits<2> idx; 7335 let Inst{11} = idx{1}; 7336 let Inst{21} = idx{0}; 7337 } 7338 7339 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7340 V128, V128, 7341 V128, VectorIndexS, 7342 asm#"2", ".2d", ".2d", ".4s", ".s", 7343 [(set (v2i64 V128:$dst), 7344 (Accum (v2i64 V128:$Rd), 7345 (v2i64 (int_aarch64_neon_sqdmull 7346 (extract_high_v4i32 V128:$Rn), 7347 (extract_high_v4i32 7348 (AArch64duplane32 (v4i32 V128:$Rm), 7349 VectorIndexS:$idx))))))]> { 7350 bits<2> idx; 7351 let Inst{11} = idx{1}; 7352 let Inst{21} = idx{0}; 7353 } 7354 7355 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 7356 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 7357 asm, ".h", "", "", ".h", []> { 7358 bits<3> idx; 7359 let Inst{11} = idx{2}; 7360 let Inst{21} = idx{1}; 7361 let Inst{20} = idx{0}; 7362 } 7363 7364 7365 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 7366 FPR64Op, FPR32Op, V128, VectorIndexS, 7367 asm, ".s", "", "", ".s", 7368 [(set (i64 FPR64Op:$dst), 7369 (Accum (i64 FPR64Op:$Rd), 7370 (i64 (int_aarch64_neon_sqdmulls_scalar 7371 (i32 FPR32Op:$Rn), 7372 (i32 (vector_extract (v4i32 V128:$Rm), 7373 VectorIndexS:$idx))))))]> { 7374 7375 bits<2> idx; 7376 let Inst{11} = idx{1}; 7377 let Inst{21} = idx{0}; 7378 } 7379} 7380 7381multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 7382 SDPatternOperator OpNode> { 7383 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7384 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 7385 V128, V64, 7386 V128_lo, VectorIndexH, 7387 asm, ".4s", ".4s", ".4h", ".h", 7388 [(set (v4i32 V128:$Rd), 7389 (OpNode (v4i16 V64:$Rn), 7390 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7391 bits<3> idx; 7392 let Inst{11} = idx{2}; 7393 let Inst{21} = idx{1}; 7394 let Inst{20} = idx{0}; 7395 } 7396 7397 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 7398 V128, V128, 7399 V128_lo, VectorIndexH, 7400 asm#"2", ".4s", ".4s", ".8h", ".h", 7401 [(set (v4i32 V128:$Rd), 7402 (OpNode (extract_high_v8i16 V128:$Rn), 7403 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7404 VectorIndexH:$idx))))]> { 7405 7406 bits<3> idx; 7407 let Inst{11} = idx{2}; 7408 let Inst{21} = idx{1}; 7409 let Inst{20} = idx{0}; 7410 } 7411 7412 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 7413 V128, V64, 7414 V128, VectorIndexS, 7415 asm, ".2d", ".2d", ".2s", ".s", 7416 [(set (v2i64 V128:$Rd), 7417 (OpNode (v2i32 V64:$Rn), 7418 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7419 bits<2> idx; 7420 let Inst{11} = idx{1}; 7421 let Inst{21} = idx{0}; 7422 } 7423 7424 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 7425 V128, V128, 7426 V128, VectorIndexS, 7427 asm#"2", ".2d", ".2d", ".4s", ".s", 7428 [(set (v2i64 V128:$Rd), 7429 (OpNode (extract_high_v4i32 V128:$Rn), 7430 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 7431 VectorIndexS:$idx))))]> { 7432 bits<2> idx; 7433 let Inst{11} = idx{1}; 7434 let Inst{21} = idx{0}; 7435 } 7436 } 7437} 7438 7439multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 7440 SDPatternOperator OpNode> { 7441 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 7442 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 7443 V128, V64, 7444 V128_lo, VectorIndexH, 7445 asm, ".4s", ".4s", ".4h", ".h", 7446 [(set (v4i32 V128:$dst), 7447 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 7448 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 7449 bits<3> idx; 7450 let Inst{11} = idx{2}; 7451 let Inst{21} = idx{1}; 7452 let Inst{20} = idx{0}; 7453 } 7454 7455 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 7456 V128, V128, 7457 V128_lo, VectorIndexH, 7458 asm#"2", ".4s", ".4s", ".8h", ".h", 7459 [(set (v4i32 V128:$dst), 7460 (OpNode (v4i32 V128:$Rd), 7461 (extract_high_v8i16 V128:$Rn), 7462 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 7463 VectorIndexH:$idx))))]> { 7464 bits<3> idx; 7465 let Inst{11} = idx{2}; 7466 let Inst{21} = idx{1}; 7467 let Inst{20} = idx{0}; 7468 } 7469 7470 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 7471 V128, V64, 7472 V128, VectorIndexS, 7473 asm, ".2d", ".2d", ".2s", ".s", 7474 [(set (v2i64 V128:$dst), 7475 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 7476 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 7477 bits<2> idx; 7478 let Inst{11} = idx{1}; 7479 let Inst{21} = idx{0}; 7480 } 7481 7482 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 7483 V128, V128, 7484 V128, VectorIndexS, 7485 asm#"2", ".2d", ".2d", ".4s", ".s", 7486 [(set (v2i64 V128:$dst), 7487 (OpNode (v2i64 V128:$Rd), 7488 (extract_high_v4i32 V128:$Rn), 7489 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 7490 VectorIndexS:$idx))))]> { 7491 bits<2> idx; 7492 let Inst{11} = idx{1}; 7493 let Inst{21} = idx{0}; 7494 } 7495 } 7496} 7497 7498//---------------------------------------------------------------------------- 7499// AdvSIMD scalar shift by immediate 7500//---------------------------------------------------------------------------- 7501 7502let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7503class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 7504 RegisterClass regtype1, RegisterClass regtype2, 7505 Operand immtype, string asm, list<dag> pattern> 7506 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 7507 asm, "\t$Rd, $Rn, $imm", "", pattern>, 7508 Sched<[WriteV]> { 7509 bits<5> Rd; 7510 bits<5> Rn; 7511 bits<7> imm; 7512 let Inst{31-30} = 0b01; 7513 let Inst{29} = U; 7514 let Inst{28-23} = 0b111110; 7515 let Inst{22-16} = fixed_imm; 7516 let Inst{15-11} = opc; 7517 let Inst{10} = 1; 7518 let Inst{9-5} = Rn; 7519 let Inst{4-0} = Rd; 7520} 7521 7522let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7523class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 7524 RegisterClass regtype1, RegisterClass regtype2, 7525 Operand immtype, string asm, list<dag> pattern> 7526 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 7527 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 7528 Sched<[WriteV]> { 7529 bits<5> Rd; 7530 bits<5> Rn; 7531 bits<7> imm; 7532 let Inst{31-30} = 0b01; 7533 let Inst{29} = U; 7534 let Inst{28-23} = 0b111110; 7535 let Inst{22-16} = fixed_imm; 7536 let Inst{15-11} = opc; 7537 let Inst{10} = 1; 7538 let Inst{9-5} = Rn; 7539 let Inst{4-0} = Rd; 7540} 7541 7542 7543multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> { 7544 let Predicates = [HasNEON, HasFullFP16] in { 7545 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7546 FPR16, FPR16, vecshiftR16, asm, []> { 7547 let Inst{19-16} = imm{3-0}; 7548 } 7549 } // Predicates = [HasNEON, HasFullFP16] 7550 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7551 FPR32, FPR32, vecshiftR32, asm, []> { 7552 let Inst{20-16} = imm{4-0}; 7553 } 7554 7555 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7556 FPR64, FPR64, vecshiftR64, asm, []> { 7557 let Inst{21-16} = imm{5-0}; 7558 } 7559} 7560 7561multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 7562 SDPatternOperator OpNode> { 7563 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7564 FPR64, FPR64, vecshiftR64, asm, 7565 [(set (i64 FPR64:$Rd), 7566 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 7567 let Inst{21-16} = imm{5-0}; 7568 } 7569 7570 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 7571 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 7572} 7573 7574multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 7575 SDPatternOperator OpNode = null_frag> { 7576 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 7577 FPR64, FPR64, vecshiftR64, asm, 7578 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 7579 (i32 vecshiftR64:$imm)))]> { 7580 let Inst{21-16} = imm{5-0}; 7581 } 7582 7583 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 7584 (i32 vecshiftR64:$imm))), 7585 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 7586 vecshiftR64:$imm)>; 7587} 7588 7589multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 7590 SDPatternOperator OpNode> { 7591 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7592 FPR64, FPR64, vecshiftL64, asm, 7593 [(set (v1i64 FPR64:$Rd), 7594 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 7595 let Inst{21-16} = imm{5-0}; 7596 } 7597} 7598 7599let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7600multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 7601 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 7602 FPR64, FPR64, vecshiftL64, asm, []> { 7603 let Inst{21-16} = imm{5-0}; 7604 } 7605} 7606 7607let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7608multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 7609 SDPatternOperator OpNode = null_frag> { 7610 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7611 FPR8, FPR16, vecshiftR8, asm, []> { 7612 let Inst{18-16} = imm{2-0}; 7613 } 7614 7615 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7616 FPR16, FPR32, vecshiftR16, asm, []> { 7617 let Inst{19-16} = imm{3-0}; 7618 } 7619 7620 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7621 FPR32, FPR64, vecshiftR32, asm, 7622 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 7623 let Inst{20-16} = imm{4-0}; 7624 } 7625} 7626 7627multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 7628 SDPatternOperator OpNode> { 7629 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7630 FPR8, FPR8, vecshiftL8, asm, []> { 7631 let Inst{18-16} = imm{2-0}; 7632 } 7633 7634 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7635 FPR16, FPR16, vecshiftL16, asm, []> { 7636 let Inst{19-16} = imm{3-0}; 7637 } 7638 7639 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7640 FPR32, FPR32, vecshiftL32, asm, 7641 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 7642 let Inst{20-16} = imm{4-0}; 7643 } 7644 7645 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7646 FPR64, FPR64, vecshiftL64, asm, 7647 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 7648 let Inst{21-16} = imm{5-0}; 7649 } 7650 7651 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 7652 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 7653} 7654 7655multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 7656 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7657 FPR8, FPR8, vecshiftR8, asm, []> { 7658 let Inst{18-16} = imm{2-0}; 7659 } 7660 7661 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7662 FPR16, FPR16, vecshiftR16, asm, []> { 7663 let Inst{19-16} = imm{3-0}; 7664 } 7665 7666 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7667 FPR32, FPR32, vecshiftR32, asm, []> { 7668 let Inst{20-16} = imm{4-0}; 7669 } 7670 7671 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7672 FPR64, FPR64, vecshiftR64, asm, []> { 7673 let Inst{21-16} = imm{5-0}; 7674 } 7675} 7676 7677//---------------------------------------------------------------------------- 7678// AdvSIMD vector x indexed element 7679//---------------------------------------------------------------------------- 7680 7681let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7682class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 7683 RegisterOperand dst_reg, RegisterOperand src_reg, 7684 Operand immtype, 7685 string asm, string dst_kind, string src_kind, 7686 list<dag> pattern> 7687 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 7688 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 7689 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 7690 Sched<[WriteV]> { 7691 bits<5> Rd; 7692 bits<5> Rn; 7693 let Inst{31} = 0; 7694 let Inst{30} = Q; 7695 let Inst{29} = U; 7696 let Inst{28-23} = 0b011110; 7697 let Inst{22-16} = fixed_imm; 7698 let Inst{15-11} = opc; 7699 let Inst{10} = 1; 7700 let Inst{9-5} = Rn; 7701 let Inst{4-0} = Rd; 7702} 7703 7704let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7705class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 7706 RegisterOperand vectype1, RegisterOperand vectype2, 7707 Operand immtype, 7708 string asm, string dst_kind, string src_kind, 7709 list<dag> pattern> 7710 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 7711 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 7712 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 7713 Sched<[WriteV]> { 7714 bits<5> Rd; 7715 bits<5> Rn; 7716 let Inst{31} = 0; 7717 let Inst{30} = Q; 7718 let Inst{29} = U; 7719 let Inst{28-23} = 0b011110; 7720 let Inst{22-16} = fixed_imm; 7721 let Inst{15-11} = opc; 7722 let Inst{10} = 1; 7723 let Inst{9-5} = Rn; 7724 let Inst{4-0} = Rd; 7725} 7726 7727multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 7728 Intrinsic OpNode> { 7729 let Predicates = [HasNEON, HasFullFP16] in { 7730 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7731 V64, V64, vecshiftR16, 7732 asm, ".4h", ".4h", 7733 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> { 7734 bits<4> imm; 7735 let Inst{19-16} = imm; 7736 } 7737 7738 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7739 V128, V128, vecshiftR16, 7740 asm, ".8h", ".8h", 7741 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> { 7742 bits<4> imm; 7743 let Inst{19-16} = imm; 7744 } 7745 } // Predicates = [HasNEON, HasFullFP16] 7746 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7747 V64, V64, vecshiftR32, 7748 asm, ".2s", ".2s", 7749 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 7750 bits<5> imm; 7751 let Inst{20-16} = imm; 7752 } 7753 7754 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7755 V128, V128, vecshiftR32, 7756 asm, ".4s", ".4s", 7757 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 7758 bits<5> imm; 7759 let Inst{20-16} = imm; 7760 } 7761 7762 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7763 V128, V128, vecshiftR64, 7764 asm, ".2d", ".2d", 7765 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 7766 bits<6> imm; 7767 let Inst{21-16} = imm; 7768 } 7769} 7770 7771multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm, 7772 Intrinsic OpNode> { 7773 let Predicates = [HasNEON, HasFullFP16] in { 7774 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7775 V64, V64, vecshiftR16, 7776 asm, ".4h", ".4h", 7777 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> { 7778 bits<4> imm; 7779 let Inst{19-16} = imm; 7780 } 7781 7782 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7783 V128, V128, vecshiftR16, 7784 asm, ".8h", ".8h", 7785 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> { 7786 bits<4> imm; 7787 let Inst{19-16} = imm; 7788 } 7789 } // Predicates = [HasNEON, HasFullFP16] 7790 7791 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7792 V64, V64, vecshiftR32, 7793 asm, ".2s", ".2s", 7794 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 7795 bits<5> imm; 7796 let Inst{20-16} = imm; 7797 } 7798 7799 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7800 V128, V128, vecshiftR32, 7801 asm, ".4s", ".4s", 7802 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 7803 bits<5> imm; 7804 let Inst{20-16} = imm; 7805 } 7806 7807 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7808 V128, V128, vecshiftR64, 7809 asm, ".2d", ".2d", 7810 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 7811 bits<6> imm; 7812 let Inst{21-16} = imm; 7813 } 7814} 7815 7816multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 7817 SDPatternOperator OpNode> { 7818 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7819 V64, V128, vecshiftR16Narrow, 7820 asm, ".8b", ".8h", 7821 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 7822 bits<3> imm; 7823 let Inst{18-16} = imm; 7824 } 7825 7826 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 7827 V128, V128, vecshiftR16Narrow, 7828 asm#"2", ".16b", ".8h", []> { 7829 bits<3> imm; 7830 let Inst{18-16} = imm; 7831 let hasSideEffects = 0; 7832 } 7833 7834 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7835 V64, V128, vecshiftR32Narrow, 7836 asm, ".4h", ".4s", 7837 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 7838 bits<4> imm; 7839 let Inst{19-16} = imm; 7840 } 7841 7842 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 7843 V128, V128, vecshiftR32Narrow, 7844 asm#"2", ".8h", ".4s", []> { 7845 bits<4> imm; 7846 let Inst{19-16} = imm; 7847 let hasSideEffects = 0; 7848 } 7849 7850 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7851 V64, V128, vecshiftR64Narrow, 7852 asm, ".2s", ".2d", 7853 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 7854 bits<5> imm; 7855 let Inst{20-16} = imm; 7856 } 7857 7858 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 7859 V128, V128, vecshiftR64Narrow, 7860 asm#"2", ".4s", ".2d", []> { 7861 bits<5> imm; 7862 let Inst{20-16} = imm; 7863 let hasSideEffects = 0; 7864 } 7865 7866 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 7867 // themselves, so put them here instead. 7868 7869 // Patterns involving what's effectively an insert high and a normal 7870 // intrinsic, represented by CONCAT_VECTORS. 7871 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 7872 vecshiftR16Narrow:$imm)), 7873 (!cast<Instruction>(NAME # "v16i8_shift") 7874 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7875 V128:$Rn, vecshiftR16Narrow:$imm)>; 7876 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 7877 vecshiftR32Narrow:$imm)), 7878 (!cast<Instruction>(NAME # "v8i16_shift") 7879 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7880 V128:$Rn, vecshiftR32Narrow:$imm)>; 7881 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 7882 vecshiftR64Narrow:$imm)), 7883 (!cast<Instruction>(NAME # "v4i32_shift") 7884 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7885 V128:$Rn, vecshiftR64Narrow:$imm)>; 7886} 7887 7888multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 7889 SDPatternOperator OpNode> { 7890 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7891 V64, V64, vecshiftL8, 7892 asm, ".8b", ".8b", 7893 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 7894 (i32 vecshiftL8:$imm)))]> { 7895 bits<3> imm; 7896 let Inst{18-16} = imm; 7897 } 7898 7899 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7900 V128, V128, vecshiftL8, 7901 asm, ".16b", ".16b", 7902 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 7903 (i32 vecshiftL8:$imm)))]> { 7904 bits<3> imm; 7905 let Inst{18-16} = imm; 7906 } 7907 7908 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7909 V64, V64, vecshiftL16, 7910 asm, ".4h", ".4h", 7911 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 7912 (i32 vecshiftL16:$imm)))]> { 7913 bits<4> imm; 7914 let Inst{19-16} = imm; 7915 } 7916 7917 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7918 V128, V128, vecshiftL16, 7919 asm, ".8h", ".8h", 7920 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7921 (i32 vecshiftL16:$imm)))]> { 7922 bits<4> imm; 7923 let Inst{19-16} = imm; 7924 } 7925 7926 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7927 V64, V64, vecshiftL32, 7928 asm, ".2s", ".2s", 7929 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 7930 (i32 vecshiftL32:$imm)))]> { 7931 bits<5> imm; 7932 let Inst{20-16} = imm; 7933 } 7934 7935 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7936 V128, V128, vecshiftL32, 7937 asm, ".4s", ".4s", 7938 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7939 (i32 vecshiftL32:$imm)))]> { 7940 bits<5> imm; 7941 let Inst{20-16} = imm; 7942 } 7943 7944 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7945 V128, V128, vecshiftL64, 7946 asm, ".2d", ".2d", 7947 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7948 (i32 vecshiftL64:$imm)))]> { 7949 bits<6> imm; 7950 let Inst{21-16} = imm; 7951 } 7952} 7953 7954multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 7955 SDPatternOperator OpNode> { 7956 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7957 V64, V64, vecshiftR8, 7958 asm, ".8b", ".8b", 7959 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 7960 (i32 vecshiftR8:$imm)))]> { 7961 bits<3> imm; 7962 let Inst{18-16} = imm; 7963 } 7964 7965 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7966 V128, V128, vecshiftR8, 7967 asm, ".16b", ".16b", 7968 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 7969 (i32 vecshiftR8:$imm)))]> { 7970 bits<3> imm; 7971 let Inst{18-16} = imm; 7972 } 7973 7974 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7975 V64, V64, vecshiftR16, 7976 asm, ".4h", ".4h", 7977 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 7978 (i32 vecshiftR16:$imm)))]> { 7979 bits<4> imm; 7980 let Inst{19-16} = imm; 7981 } 7982 7983 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7984 V128, V128, vecshiftR16, 7985 asm, ".8h", ".8h", 7986 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7987 (i32 vecshiftR16:$imm)))]> { 7988 bits<4> imm; 7989 let Inst{19-16} = imm; 7990 } 7991 7992 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7993 V64, V64, vecshiftR32, 7994 asm, ".2s", ".2s", 7995 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 7996 (i32 vecshiftR32:$imm)))]> { 7997 bits<5> imm; 7998 let Inst{20-16} = imm; 7999 } 8000 8001 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8002 V128, V128, vecshiftR32, 8003 asm, ".4s", ".4s", 8004 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 8005 (i32 vecshiftR32:$imm)))]> { 8006 bits<5> imm; 8007 let Inst{20-16} = imm; 8008 } 8009 8010 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 8011 V128, V128, vecshiftR64, 8012 asm, ".2d", ".2d", 8013 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 8014 (i32 vecshiftR64:$imm)))]> { 8015 bits<6> imm; 8016 let Inst{21-16} = imm; 8017 } 8018} 8019 8020let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8021multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 8022 SDPatternOperator OpNode = null_frag> { 8023 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8024 V64, V64, vecshiftR8, asm, ".8b", ".8b", 8025 [(set (v8i8 V64:$dst), 8026 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8027 (i32 vecshiftR8:$imm)))]> { 8028 bits<3> imm; 8029 let Inst{18-16} = imm; 8030 } 8031 8032 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8033 V128, V128, vecshiftR8, asm, ".16b", ".16b", 8034 [(set (v16i8 V128:$dst), 8035 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8036 (i32 vecshiftR8:$imm)))]> { 8037 bits<3> imm; 8038 let Inst{18-16} = imm; 8039 } 8040 8041 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8042 V64, V64, vecshiftR16, asm, ".4h", ".4h", 8043 [(set (v4i16 V64:$dst), 8044 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8045 (i32 vecshiftR16:$imm)))]> { 8046 bits<4> imm; 8047 let Inst{19-16} = imm; 8048 } 8049 8050 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8051 V128, V128, vecshiftR16, asm, ".8h", ".8h", 8052 [(set (v8i16 V128:$dst), 8053 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8054 (i32 vecshiftR16:$imm)))]> { 8055 bits<4> imm; 8056 let Inst{19-16} = imm; 8057 } 8058 8059 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8060 V64, V64, vecshiftR32, asm, ".2s", ".2s", 8061 [(set (v2i32 V64:$dst), 8062 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8063 (i32 vecshiftR32:$imm)))]> { 8064 bits<5> imm; 8065 let Inst{20-16} = imm; 8066 } 8067 8068 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8069 V128, V128, vecshiftR32, asm, ".4s", ".4s", 8070 [(set (v4i32 V128:$dst), 8071 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8072 (i32 vecshiftR32:$imm)))]> { 8073 bits<5> imm; 8074 let Inst{20-16} = imm; 8075 } 8076 8077 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8078 V128, V128, vecshiftR64, 8079 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 8080 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8081 (i32 vecshiftR64:$imm)))]> { 8082 bits<6> imm; 8083 let Inst{21-16} = imm; 8084 } 8085} 8086 8087multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 8088 SDPatternOperator OpNode = null_frag> { 8089 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 8090 V64, V64, vecshiftL8, 8091 asm, ".8b", ".8b", 8092 [(set (v8i8 V64:$dst), 8093 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 8094 (i32 vecshiftL8:$imm)))]> { 8095 bits<3> imm; 8096 let Inst{18-16} = imm; 8097 } 8098 8099 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 8100 V128, V128, vecshiftL8, 8101 asm, ".16b", ".16b", 8102 [(set (v16i8 V128:$dst), 8103 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 8104 (i32 vecshiftL8:$imm)))]> { 8105 bits<3> imm; 8106 let Inst{18-16} = imm; 8107 } 8108 8109 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 8110 V64, V64, vecshiftL16, 8111 asm, ".4h", ".4h", 8112 [(set (v4i16 V64:$dst), 8113 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 8114 (i32 vecshiftL16:$imm)))]> { 8115 bits<4> imm; 8116 let Inst{19-16} = imm; 8117 } 8118 8119 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 8120 V128, V128, vecshiftL16, 8121 asm, ".8h", ".8h", 8122 [(set (v8i16 V128:$dst), 8123 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 8124 (i32 vecshiftL16:$imm)))]> { 8125 bits<4> imm; 8126 let Inst{19-16} = imm; 8127 } 8128 8129 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 8130 V64, V64, vecshiftL32, 8131 asm, ".2s", ".2s", 8132 [(set (v2i32 V64:$dst), 8133 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 8134 (i32 vecshiftL32:$imm)))]> { 8135 bits<5> imm; 8136 let Inst{20-16} = imm; 8137 } 8138 8139 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 8140 V128, V128, vecshiftL32, 8141 asm, ".4s", ".4s", 8142 [(set (v4i32 V128:$dst), 8143 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8144 (i32 vecshiftL32:$imm)))]> { 8145 bits<5> imm; 8146 let Inst{20-16} = imm; 8147 } 8148 8149 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 8150 V128, V128, vecshiftL64, 8151 asm, ".2d", ".2d", 8152 [(set (v2i64 V128:$dst), 8153 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 8154 (i32 vecshiftL64:$imm)))]> { 8155 bits<6> imm; 8156 let Inst{21-16} = imm; 8157 } 8158} 8159 8160multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 8161 SDPatternOperator OpNode> { 8162 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 8163 V128, V64, vecshiftL8, asm, ".8h", ".8b", 8164 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 8165 bits<3> imm; 8166 let Inst{18-16} = imm; 8167 } 8168 8169 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 8170 V128, V128, vecshiftL8, 8171 asm#"2", ".8h", ".16b", 8172 [(set (v8i16 V128:$Rd), 8173 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 8174 bits<3> imm; 8175 let Inst{18-16} = imm; 8176 } 8177 8178 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 8179 V128, V64, vecshiftL16, asm, ".4s", ".4h", 8180 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 8181 bits<4> imm; 8182 let Inst{19-16} = imm; 8183 } 8184 8185 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 8186 V128, V128, vecshiftL16, 8187 asm#"2", ".4s", ".8h", 8188 [(set (v4i32 V128:$Rd), 8189 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 8190 8191 bits<4> imm; 8192 let Inst{19-16} = imm; 8193 } 8194 8195 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 8196 V128, V64, vecshiftL32, asm, ".2d", ".2s", 8197 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 8198 bits<5> imm; 8199 let Inst{20-16} = imm; 8200 } 8201 8202 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 8203 V128, V128, vecshiftL32, 8204 asm#"2", ".2d", ".4s", 8205 [(set (v2i64 V128:$Rd), 8206 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 8207 bits<5> imm; 8208 let Inst{20-16} = imm; 8209 } 8210} 8211 8212 8213//--- 8214// Vector load/store 8215//--- 8216// SIMD ldX/stX no-index memory references don't allow the optional 8217// ", #0" constant and handle post-indexing explicitly, so we use 8218// a more specialized parse method for them. Otherwise, it's the same as 8219// the general GPR64sp handling. 8220 8221class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 8222 string asm, dag oops, dag iops, list<dag> pattern> 8223 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 8224 bits<5> Vt; 8225 bits<5> Rn; 8226 let Inst{31} = 0; 8227 let Inst{30} = Q; 8228 let Inst{29-23} = 0b0011000; 8229 let Inst{22} = L; 8230 let Inst{21-16} = 0b000000; 8231 let Inst{15-12} = opcode; 8232 let Inst{11-10} = size; 8233 let Inst{9-5} = Rn; 8234 let Inst{4-0} = Vt; 8235} 8236 8237class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 8238 string asm, dag oops, dag iops> 8239 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 8240 bits<5> Vt; 8241 bits<5> Rn; 8242 bits<5> Xm; 8243 let Inst{31} = 0; 8244 let Inst{30} = Q; 8245 let Inst{29-23} = 0b0011001; 8246 let Inst{22} = L; 8247 let Inst{21} = 0; 8248 let Inst{20-16} = Xm; 8249 let Inst{15-12} = opcode; 8250 let Inst{11-10} = size; 8251 let Inst{9-5} = Rn; 8252 let Inst{4-0} = Vt; 8253} 8254 8255// The immediate form of AdvSIMD post-indexed addressing is encoded with 8256// register post-index addressing from the zero register. 8257multiclass SIMDLdStAliases<string asm, string layout, string Count, 8258 int Offset, int Size> { 8259 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 8260 // "ld1\t$Vt, [$Rn], #16" 8261 // may get mapped to 8262 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 8263 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 8264 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 8265 GPR64sp:$Rn, 8266 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8267 XZR), 1>; 8268 8269 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 8270 // "ld1.8b\t$Vt, [$Rn], #16" 8271 // may get mapped to 8272 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 8273 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 8274 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 8275 GPR64sp:$Rn, 8276 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8277 XZR), 0>; 8278 8279 // E.g. "ld1.8b { v0, v1 }, [x1]" 8280 // "ld1\t$Vt, [$Rn]" 8281 // may get mapped to 8282 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 8283 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 8284 (!cast<Instruction>(NAME # Count # "v" # layout) 8285 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8286 GPR64sp:$Rn), 0>; 8287 8288 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 8289 // "ld1\t$Vt, [$Rn], $Xm" 8290 // may get mapped to 8291 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 8292 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 8293 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 8294 GPR64sp:$Rn, 8295 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8296 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 8297} 8298 8299multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128, 8300 int Offset64, bits<4> opcode> { 8301 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 8302 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 8303 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 8304 (ins GPR64sp:$Rn), []>; 8305 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 8306 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 8307 (ins GPR64sp:$Rn), []>; 8308 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 8309 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 8310 (ins GPR64sp:$Rn), []>; 8311 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 8312 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 8313 (ins GPR64sp:$Rn), []>; 8314 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 8315 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 8316 (ins GPR64sp:$Rn), []>; 8317 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 8318 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 8319 (ins GPR64sp:$Rn), []>; 8320 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 8321 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 8322 (ins GPR64sp:$Rn), []>; 8323 8324 8325 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 8326 (outs GPR64sp:$wback, 8327 !cast<RegisterOperand>(veclist # "16b"):$Vt), 8328 (ins GPR64sp:$Rn, 8329 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8330 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 8331 (outs GPR64sp:$wback, 8332 !cast<RegisterOperand>(veclist # "8h"):$Vt), 8333 (ins GPR64sp:$Rn, 8334 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8335 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 8336 (outs GPR64sp:$wback, 8337 !cast<RegisterOperand>(veclist # "4s"):$Vt), 8338 (ins GPR64sp:$Rn, 8339 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8340 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 8341 (outs GPR64sp:$wback, 8342 !cast<RegisterOperand>(veclist # "2d"):$Vt), 8343 (ins GPR64sp:$Rn, 8344 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8345 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 8346 (outs GPR64sp:$wback, 8347 !cast<RegisterOperand>(veclist # "8b"):$Vt), 8348 (ins GPR64sp:$Rn, 8349 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8350 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 8351 (outs GPR64sp:$wback, 8352 !cast<RegisterOperand>(veclist # "4h"):$Vt), 8353 (ins GPR64sp:$Rn, 8354 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8355 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 8356 (outs GPR64sp:$wback, 8357 !cast<RegisterOperand>(veclist # "2s"):$Vt), 8358 (ins GPR64sp:$Rn, 8359 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8360 } 8361 8362 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>; 8363 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>; 8364 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>; 8365 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>; 8366 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>; 8367 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>; 8368 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>; 8369} 8370 8371// Only ld1/st1 has a v1d version. 8372multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128, 8373 int Offset64, bits<4> opcode> { 8374 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 8375 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 8376 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 8377 GPR64sp:$Rn), []>; 8378 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 8379 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 8380 GPR64sp:$Rn), []>; 8381 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 8382 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 8383 GPR64sp:$Rn), []>; 8384 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 8385 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 8386 GPR64sp:$Rn), []>; 8387 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 8388 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 8389 GPR64sp:$Rn), []>; 8390 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 8391 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 8392 GPR64sp:$Rn), []>; 8393 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 8394 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 8395 GPR64sp:$Rn), []>; 8396 8397 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 8398 (outs GPR64sp:$wback), 8399 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 8400 GPR64sp:$Rn, 8401 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8402 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 8403 (outs GPR64sp:$wback), 8404 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 8405 GPR64sp:$Rn, 8406 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8407 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 8408 (outs GPR64sp:$wback), 8409 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 8410 GPR64sp:$Rn, 8411 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8412 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 8413 (outs GPR64sp:$wback), 8414 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 8415 GPR64sp:$Rn, 8416 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 8417 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 8418 (outs GPR64sp:$wback), 8419 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 8420 GPR64sp:$Rn, 8421 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8422 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 8423 (outs GPR64sp:$wback), 8424 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 8425 GPR64sp:$Rn, 8426 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8427 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 8428 (outs GPR64sp:$wback), 8429 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 8430 GPR64sp:$Rn, 8431 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8432 } 8433 8434 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>; 8435 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>; 8436 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>; 8437 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>; 8438 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>; 8439 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>; 8440 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>; 8441} 8442 8443multiclass BaseSIMDLd1<string Count, string asm, string veclist, 8444 int Offset128, int Offset64, bits<4> opcode> 8445 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> { 8446 8447 // LD1 instructions have extra "1d" variants. 8448 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 8449 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 8450 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 8451 (ins GPR64sp:$Rn), []>; 8452 8453 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 8454 (outs GPR64sp:$wback, 8455 !cast<RegisterOperand>(veclist # "1d"):$Vt), 8456 (ins GPR64sp:$Rn, 8457 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8458 } 8459 8460 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>; 8461} 8462 8463multiclass BaseSIMDSt1<string Count, string asm, string veclist, 8464 int Offset128, int Offset64, bits<4> opcode> 8465 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> { 8466 8467 // ST1 instructions have extra "1d" variants. 8468 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 8469 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 8470 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 8471 GPR64sp:$Rn), []>; 8472 8473 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 8474 (outs GPR64sp:$wback), 8475 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 8476 GPR64sp:$Rn, 8477 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 8478 } 8479 8480 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>; 8481} 8482 8483multiclass SIMDLd1Multiple<string asm> { 8484 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>; 8485 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; 8486 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>; 8487 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>; 8488} 8489 8490multiclass SIMDSt1Multiple<string asm> { 8491 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>; 8492 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; 8493 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>; 8494 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>; 8495} 8496 8497multiclass SIMDLd2Multiple<string asm> { 8498 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; 8499} 8500 8501multiclass SIMDSt2Multiple<string asm> { 8502 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; 8503} 8504 8505multiclass SIMDLd3Multiple<string asm> { 8506 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>; 8507} 8508 8509multiclass SIMDSt3Multiple<string asm> { 8510 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>; 8511} 8512 8513multiclass SIMDLd4Multiple<string asm> { 8514 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>; 8515} 8516 8517multiclass SIMDSt4Multiple<string asm> { 8518 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>; 8519} 8520 8521//--- 8522// AdvSIMD Load/store single-element 8523//--- 8524 8525class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 8526 string asm, string operands, string cst, 8527 dag oops, dag iops, list<dag> pattern> 8528 : I<oops, iops, asm, operands, cst, pattern> { 8529 bits<5> Vt; 8530 bits<5> Rn; 8531 let Inst{31} = 0; 8532 let Inst{29-24} = 0b001101; 8533 let Inst{22} = L; 8534 let Inst{21} = R; 8535 let Inst{15-13} = opcode; 8536 let Inst{9-5} = Rn; 8537 let Inst{4-0} = Vt; 8538} 8539 8540class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 8541 string asm, string operands, string cst, 8542 dag oops, dag iops, list<dag> pattern> 8543 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 8544 bits<5> Vt; 8545 bits<5> Rn; 8546 let Inst{31} = 0; 8547 let Inst{29-24} = 0b001101; 8548 let Inst{22} = L; 8549 let Inst{21} = R; 8550 let Inst{15-13} = opcode; 8551 let Inst{9-5} = Rn; 8552 let Inst{4-0} = Vt; 8553} 8554 8555 8556let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8557class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 8558 Operand listtype> 8559 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 8560 (outs listtype:$Vt), (ins GPR64sp:$Rn), 8561 []> { 8562 let Inst{30} = Q; 8563 let Inst{23} = 0; 8564 let Inst{20-16} = 0b00000; 8565 let Inst{12} = S; 8566 let Inst{11-10} = size; 8567} 8568let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8569class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 8570 string asm, Operand listtype, Operand GPR64pi> 8571 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 8572 "$Rn = $wback", 8573 (outs GPR64sp:$wback, listtype:$Vt), 8574 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 8575 bits<5> Xm; 8576 let Inst{30} = Q; 8577 let Inst{23} = 1; 8578 let Inst{20-16} = Xm; 8579 let Inst{12} = S; 8580 let Inst{11-10} = size; 8581} 8582 8583multiclass SIMDLdrAliases<string asm, string layout, string Count, 8584 int Offset, int Size> { 8585 // E.g. "ld1r { v0.8b }, [x1], #1" 8586 // "ld1r.8b\t$Vt, [$Rn], #1" 8587 // may get mapped to 8588 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 8589 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 8590 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8591 GPR64sp:$Rn, 8592 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8593 XZR), 1>; 8594 8595 // E.g. "ld1r.8b { v0 }, [x1], #1" 8596 // "ld1r.8b\t$Vt, [$Rn], #1" 8597 // may get mapped to 8598 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 8599 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 8600 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8601 GPR64sp:$Rn, 8602 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8603 XZR), 0>; 8604 8605 // E.g. "ld1r.8b { v0 }, [x1]" 8606 // "ld1r.8b\t$Vt, [$Rn]" 8607 // may get mapped to 8608 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 8609 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 8610 (!cast<Instruction>(NAME # "v" # layout) 8611 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8612 GPR64sp:$Rn), 0>; 8613 8614 // E.g. "ld1r.8b { v0 }, [x1], x2" 8615 // "ld1r.8b\t$Vt, [$Rn], $Xm" 8616 // may get mapped to 8617 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 8618 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 8619 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8620 GPR64sp:$Rn, 8621 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8622 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 8623} 8624 8625multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 8626 int Offset1, int Offset2, int Offset4, int Offset8> { 8627 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 8628 !cast<Operand>("VecList" # Count # "8b")>; 8629 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 8630 !cast<Operand>("VecList" # Count #"16b")>; 8631 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 8632 !cast<Operand>("VecList" # Count #"4h")>; 8633 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 8634 !cast<Operand>("VecList" # Count #"8h")>; 8635 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 8636 !cast<Operand>("VecList" # Count #"2s")>; 8637 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 8638 !cast<Operand>("VecList" # Count #"4s")>; 8639 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 8640 !cast<Operand>("VecList" # Count #"1d")>; 8641 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 8642 !cast<Operand>("VecList" # Count #"2d")>; 8643 8644 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 8645 !cast<Operand>("VecList" # Count # "8b"), 8646 !cast<Operand>("GPR64pi" # Offset1)>; 8647 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 8648 !cast<Operand>("VecList" # Count # "16b"), 8649 !cast<Operand>("GPR64pi" # Offset1)>; 8650 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 8651 !cast<Operand>("VecList" # Count # "4h"), 8652 !cast<Operand>("GPR64pi" # Offset2)>; 8653 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 8654 !cast<Operand>("VecList" # Count # "8h"), 8655 !cast<Operand>("GPR64pi" # Offset2)>; 8656 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 8657 !cast<Operand>("VecList" # Count # "2s"), 8658 !cast<Operand>("GPR64pi" # Offset4)>; 8659 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 8660 !cast<Operand>("VecList" # Count # "4s"), 8661 !cast<Operand>("GPR64pi" # Offset4)>; 8662 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 8663 !cast<Operand>("VecList" # Count # "1d"), 8664 !cast<Operand>("GPR64pi" # Offset8)>; 8665 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 8666 !cast<Operand>("VecList" # Count # "2d"), 8667 !cast<Operand>("GPR64pi" # Offset8)>; 8668 8669 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>; 8670 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>; 8671 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>; 8672 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>; 8673 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>; 8674 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>; 8675 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>; 8676 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>; 8677} 8678 8679class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 8680 dag oops, dag iops, list<dag> pattern> 8681 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8682 pattern> { 8683 // idx encoded in Q:S:size fields. 8684 bits<4> idx; 8685 let Inst{30} = idx{3}; 8686 let Inst{23} = 0; 8687 let Inst{20-16} = 0b00000; 8688 let Inst{12} = idx{2}; 8689 let Inst{11-10} = idx{1-0}; 8690} 8691class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 8692 dag oops, dag iops, list<dag> pattern> 8693 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8694 oops, iops, pattern> { 8695 // idx encoded in Q:S:size fields. 8696 bits<4> idx; 8697 let Inst{30} = idx{3}; 8698 let Inst{23} = 0; 8699 let Inst{20-16} = 0b00000; 8700 let Inst{12} = idx{2}; 8701 let Inst{11-10} = idx{1-0}; 8702} 8703class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 8704 dag oops, dag iops> 8705 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8706 "$Rn = $wback", oops, iops, []> { 8707 // idx encoded in Q:S:size fields. 8708 bits<4> idx; 8709 bits<5> Xm; 8710 let Inst{30} = idx{3}; 8711 let Inst{23} = 1; 8712 let Inst{20-16} = Xm; 8713 let Inst{12} = idx{2}; 8714 let Inst{11-10} = idx{1-0}; 8715} 8716class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 8717 dag oops, dag iops> 8718 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8719 "$Rn = $wback", oops, iops, []> { 8720 // idx encoded in Q:S:size fields. 8721 bits<4> idx; 8722 bits<5> Xm; 8723 let Inst{30} = idx{3}; 8724 let Inst{23} = 1; 8725 let Inst{20-16} = Xm; 8726 let Inst{12} = idx{2}; 8727 let Inst{11-10} = idx{1-0}; 8728} 8729 8730class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 8731 dag oops, dag iops, list<dag> pattern> 8732 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8733 pattern> { 8734 // idx encoded in Q:S:size<1> fields. 8735 bits<3> idx; 8736 let Inst{30} = idx{2}; 8737 let Inst{23} = 0; 8738 let Inst{20-16} = 0b00000; 8739 let Inst{12} = idx{1}; 8740 let Inst{11} = idx{0}; 8741 let Inst{10} = size; 8742} 8743class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 8744 dag oops, dag iops, list<dag> pattern> 8745 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8746 oops, iops, pattern> { 8747 // idx encoded in Q:S:size<1> fields. 8748 bits<3> idx; 8749 let Inst{30} = idx{2}; 8750 let Inst{23} = 0; 8751 let Inst{20-16} = 0b00000; 8752 let Inst{12} = idx{1}; 8753 let Inst{11} = idx{0}; 8754 let Inst{10} = size; 8755} 8756 8757class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 8758 dag oops, dag iops> 8759 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8760 "$Rn = $wback", oops, iops, []> { 8761 // idx encoded in Q:S:size<1> fields. 8762 bits<3> idx; 8763 bits<5> Xm; 8764 let Inst{30} = idx{2}; 8765 let Inst{23} = 1; 8766 let Inst{20-16} = Xm; 8767 let Inst{12} = idx{1}; 8768 let Inst{11} = idx{0}; 8769 let Inst{10} = size; 8770} 8771class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 8772 dag oops, dag iops> 8773 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8774 "$Rn = $wback", oops, iops, []> { 8775 // idx encoded in Q:S:size<1> fields. 8776 bits<3> idx; 8777 bits<5> Xm; 8778 let Inst{30} = idx{2}; 8779 let Inst{23} = 1; 8780 let Inst{20-16} = Xm; 8781 let Inst{12} = idx{1}; 8782 let Inst{11} = idx{0}; 8783 let Inst{10} = size; 8784} 8785class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8786 dag oops, dag iops, list<dag> pattern> 8787 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8788 pattern> { 8789 // idx encoded in Q:S fields. 8790 bits<2> idx; 8791 let Inst{30} = idx{1}; 8792 let Inst{23} = 0; 8793 let Inst{20-16} = 0b00000; 8794 let Inst{12} = idx{0}; 8795 let Inst{11-10} = size; 8796} 8797class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8798 dag oops, dag iops, list<dag> pattern> 8799 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8800 oops, iops, pattern> { 8801 // idx encoded in Q:S fields. 8802 bits<2> idx; 8803 let Inst{30} = idx{1}; 8804 let Inst{23} = 0; 8805 let Inst{20-16} = 0b00000; 8806 let Inst{12} = idx{0}; 8807 let Inst{11-10} = size; 8808} 8809class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 8810 string asm, dag oops, dag iops> 8811 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8812 "$Rn = $wback", oops, iops, []> { 8813 // idx encoded in Q:S fields. 8814 bits<2> idx; 8815 bits<5> Xm; 8816 let Inst{30} = idx{1}; 8817 let Inst{23} = 1; 8818 let Inst{20-16} = Xm; 8819 let Inst{12} = idx{0}; 8820 let Inst{11-10} = size; 8821} 8822class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 8823 string asm, dag oops, dag iops> 8824 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8825 "$Rn = $wback", oops, iops, []> { 8826 // idx encoded in Q:S fields. 8827 bits<2> idx; 8828 bits<5> Xm; 8829 let Inst{30} = idx{1}; 8830 let Inst{23} = 1; 8831 let Inst{20-16} = Xm; 8832 let Inst{12} = idx{0}; 8833 let Inst{11-10} = size; 8834} 8835class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8836 dag oops, dag iops, list<dag> pattern> 8837 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8838 pattern> { 8839 // idx encoded in Q field. 8840 bits<1> idx; 8841 let Inst{30} = idx; 8842 let Inst{23} = 0; 8843 let Inst{20-16} = 0b00000; 8844 let Inst{12} = 0; 8845 let Inst{11-10} = size; 8846} 8847class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8848 dag oops, dag iops, list<dag> pattern> 8849 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8850 oops, iops, pattern> { 8851 // idx encoded in Q field. 8852 bits<1> idx; 8853 let Inst{30} = idx; 8854 let Inst{23} = 0; 8855 let Inst{20-16} = 0b00000; 8856 let Inst{12} = 0; 8857 let Inst{11-10} = size; 8858} 8859class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 8860 string asm, dag oops, dag iops> 8861 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8862 "$Rn = $wback", oops, iops, []> { 8863 // idx encoded in Q field. 8864 bits<1> idx; 8865 bits<5> Xm; 8866 let Inst{30} = idx; 8867 let Inst{23} = 1; 8868 let Inst{20-16} = Xm; 8869 let Inst{12} = 0; 8870 let Inst{11-10} = size; 8871} 8872class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 8873 string asm, dag oops, dag iops> 8874 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8875 "$Rn = $wback", oops, iops, []> { 8876 // idx encoded in Q field. 8877 bits<1> idx; 8878 bits<5> Xm; 8879 let Inst{30} = idx; 8880 let Inst{23} = 1; 8881 let Inst{20-16} = Xm; 8882 let Inst{12} = 0; 8883 let Inst{11-10} = size; 8884} 8885 8886let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8887multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 8888 RegisterOperand listtype, 8889 RegisterOperand GPR64pi> { 8890 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 8891 (outs listtype:$dst), 8892 (ins listtype:$Vt, VectorIndexB:$idx, 8893 GPR64sp:$Rn), []>; 8894 8895 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 8896 (outs GPR64sp:$wback, listtype:$dst), 8897 (ins listtype:$Vt, VectorIndexB:$idx, 8898 GPR64sp:$Rn, GPR64pi:$Xm)>; 8899} 8900let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8901multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 8902 RegisterOperand listtype, 8903 RegisterOperand GPR64pi> { 8904 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 8905 (outs listtype:$dst), 8906 (ins listtype:$Vt, VectorIndexH:$idx, 8907 GPR64sp:$Rn), []>; 8908 8909 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 8910 (outs GPR64sp:$wback, listtype:$dst), 8911 (ins listtype:$Vt, VectorIndexH:$idx, 8912 GPR64sp:$Rn, GPR64pi:$Xm)>; 8913} 8914let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8915multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 8916 RegisterOperand listtype, 8917 RegisterOperand GPR64pi> { 8918 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 8919 (outs listtype:$dst), 8920 (ins listtype:$Vt, VectorIndexS:$idx, 8921 GPR64sp:$Rn), []>; 8922 8923 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 8924 (outs GPR64sp:$wback, listtype:$dst), 8925 (ins listtype:$Vt, VectorIndexS:$idx, 8926 GPR64sp:$Rn, GPR64pi:$Xm)>; 8927} 8928let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8929multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 8930 RegisterOperand listtype, RegisterOperand GPR64pi> { 8931 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 8932 (outs listtype:$dst), 8933 (ins listtype:$Vt, VectorIndexD:$idx, 8934 GPR64sp:$Rn), []>; 8935 8936 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 8937 (outs GPR64sp:$wback, listtype:$dst), 8938 (ins listtype:$Vt, VectorIndexD:$idx, 8939 GPR64sp:$Rn, GPR64pi:$Xm)>; 8940} 8941let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8942multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 8943 RegisterOperand listtype, RegisterOperand GPR64pi> { 8944 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 8945 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 8946 GPR64sp:$Rn), []>; 8947 8948 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 8949 (outs GPR64sp:$wback), 8950 (ins listtype:$Vt, VectorIndexB:$idx, 8951 GPR64sp:$Rn, GPR64pi:$Xm)>; 8952} 8953let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8954multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 8955 RegisterOperand listtype, RegisterOperand GPR64pi> { 8956 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 8957 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 8958 GPR64sp:$Rn), []>; 8959 8960 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 8961 (outs GPR64sp:$wback), 8962 (ins listtype:$Vt, VectorIndexH:$idx, 8963 GPR64sp:$Rn, GPR64pi:$Xm)>; 8964} 8965let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8966multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 8967 RegisterOperand listtype, RegisterOperand GPR64pi> { 8968 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 8969 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 8970 GPR64sp:$Rn), []>; 8971 8972 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 8973 (outs GPR64sp:$wback), 8974 (ins listtype:$Vt, VectorIndexS:$idx, 8975 GPR64sp:$Rn, GPR64pi:$Xm)>; 8976} 8977let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8978multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 8979 RegisterOperand listtype, RegisterOperand GPR64pi> { 8980 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 8981 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 8982 GPR64sp:$Rn), []>; 8983 8984 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 8985 (outs GPR64sp:$wback), 8986 (ins listtype:$Vt, VectorIndexD:$idx, 8987 GPR64sp:$Rn, GPR64pi:$Xm)>; 8988} 8989 8990multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 8991 string Count, int Offset, Operand idxtype> { 8992 // E.g. "ld1 { v0.8b }[0], [x1], #1" 8993 // "ld1\t$Vt, [$Rn], #1" 8994 // may get mapped to 8995 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 8996 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 8997 (!cast<Instruction>(NAME # Type # "_POST") 8998 GPR64sp:$Rn, 8999 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 9000 idxtype:$idx, XZR), 1>; 9001 9002 // E.g. "ld1.8b { v0 }[0], [x1], #1" 9003 // "ld1.8b\t$Vt, [$Rn], #1" 9004 // may get mapped to 9005 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 9006 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 9007 (!cast<Instruction>(NAME # Type # "_POST") 9008 GPR64sp:$Rn, 9009 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9010 idxtype:$idx, XZR), 0>; 9011 9012 // E.g. "ld1.8b { v0 }[0], [x1]" 9013 // "ld1.8b\t$Vt, [$Rn]" 9014 // may get mapped to 9015 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 9016 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 9017 (!cast<Instruction>(NAME # Type) 9018 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9019 idxtype:$idx, GPR64sp:$Rn), 0>; 9020 9021 // E.g. "ld1.8b { v0 }[0], [x1], x2" 9022 // "ld1.8b\t$Vt, [$Rn], $Xm" 9023 // may get mapped to 9024 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 9025 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 9026 (!cast<Instruction>(NAME # Type # "_POST") 9027 GPR64sp:$Rn, 9028 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 9029 idxtype:$idx, 9030 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 9031} 9032 9033multiclass SIMDLdSt1SingleAliases<string asm> { 9034 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 9035 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 9036 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 9037 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 9038} 9039 9040multiclass SIMDLdSt2SingleAliases<string asm> { 9041 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 9042 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 9043 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 9044 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 9045} 9046 9047multiclass SIMDLdSt3SingleAliases<string asm> { 9048 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 9049 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 9050 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 9051 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 9052} 9053 9054multiclass SIMDLdSt4SingleAliases<string asm> { 9055 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 9056 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 9057 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 9058 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 9059} 9060} // end of 'let Predicates = [HasNEON]' 9061 9062//---------------------------------------------------------------------------- 9063// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract 9064//---------------------------------------------------------------------------- 9065 9066let Predicates = [HasNEON, HasV8_1a] in { 9067 9068class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode, 9069 RegisterOperand regtype, string asm, 9070 string kind, list<dag> pattern> 9071 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 9072 pattern> { 9073} 9074multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm, 9075 SDPatternOperator Accum> { 9076 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h", 9077 [(set (v4i16 V64:$dst), 9078 (Accum (v4i16 V64:$Rd), 9079 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn), 9080 (v4i16 V64:$Rm)))))]>; 9081 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h", 9082 [(set (v8i16 V128:$dst), 9083 (Accum (v8i16 V128:$Rd), 9084 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn), 9085 (v8i16 V128:$Rm)))))]>; 9086 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s", 9087 [(set (v2i32 V64:$dst), 9088 (Accum (v2i32 V64:$Rd), 9089 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn), 9090 (v2i32 V64:$Rm)))))]>; 9091 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s", 9092 [(set (v4i32 V128:$dst), 9093 (Accum (v4i32 V128:$Rd), 9094 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn), 9095 (v4i32 V128:$Rm)))))]>; 9096} 9097 9098multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm, 9099 SDPatternOperator Accum> { 9100 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 9101 V64, V64, V128_lo, VectorIndexH, 9102 asm, ".4h", ".4h", ".4h", ".h", 9103 [(set (v4i16 V64:$dst), 9104 (Accum (v4i16 V64:$Rd), 9105 (v4i16 (int_aarch64_neon_sqrdmulh 9106 (v4i16 V64:$Rn), 9107 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9108 VectorIndexH:$idx))))))]> { 9109 bits<3> idx; 9110 let Inst{11} = idx{2}; 9111 let Inst{21} = idx{1}; 9112 let Inst{20} = idx{0}; 9113 } 9114 9115 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 9116 V128, V128, V128_lo, VectorIndexH, 9117 asm, ".8h", ".8h", ".8h", ".h", 9118 [(set (v8i16 V128:$dst), 9119 (Accum (v8i16 V128:$Rd), 9120 (v8i16 (int_aarch64_neon_sqrdmulh 9121 (v8i16 V128:$Rn), 9122 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 9123 VectorIndexH:$idx))))))]> { 9124 bits<3> idx; 9125 let Inst{11} = idx{2}; 9126 let Inst{21} = idx{1}; 9127 let Inst{20} = idx{0}; 9128 } 9129 9130 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 9131 V64, V64, V128, VectorIndexS, 9132 asm, ".2s", ".2s", ".2s", ".s", 9133 [(set (v2i32 V64:$dst), 9134 (Accum (v2i32 V64:$Rd), 9135 (v2i32 (int_aarch64_neon_sqrdmulh 9136 (v2i32 V64:$Rn), 9137 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 9138 VectorIndexS:$idx))))))]> { 9139 bits<2> idx; 9140 let Inst{11} = idx{1}; 9141 let Inst{21} = idx{0}; 9142 } 9143 9144 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 9145 // an intermediate EXTRACT_SUBREG would be untyped. 9146 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 9147 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..))) 9148 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9149 (i32 (vector_extract 9150 (v4i32 (insert_subvector 9151 (undef), 9152 (v2i32 (int_aarch64_neon_sqrdmulh 9153 (v2i32 V64:$Rn), 9154 (v2i32 (AArch64duplane32 9155 (v4i32 V128:$Rm), 9156 VectorIndexS:$idx)))), 9157 (i32 0))), 9158 (i64 0))))), 9159 (EXTRACT_SUBREG 9160 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed) 9161 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 9162 FPR32Op:$Rd, 9163 ssub)), 9164 V64:$Rn, 9165 V128:$Rm, 9166 VectorIndexS:$idx)), 9167 ssub)>; 9168 9169 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 9170 V128, V128, V128, VectorIndexS, 9171 asm, ".4s", ".4s", ".4s", ".s", 9172 [(set (v4i32 V128:$dst), 9173 (Accum (v4i32 V128:$Rd), 9174 (v4i32 (int_aarch64_neon_sqrdmulh 9175 (v4i32 V128:$Rn), 9176 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 9177 VectorIndexS:$idx))))))]> { 9178 bits<2> idx; 9179 let Inst{11} = idx{1}; 9180 let Inst{21} = idx{0}; 9181 } 9182 9183 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 9184 // an intermediate EXTRACT_SUBREG would be untyped. 9185 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 9186 (i32 (vector_extract 9187 (v4i32 (int_aarch64_neon_sqrdmulh 9188 (v4i32 V128:$Rn), 9189 (v4i32 (AArch64duplane32 9190 (v4i32 V128:$Rm), 9191 VectorIndexS:$idx)))), 9192 (i64 0))))), 9193 (EXTRACT_SUBREG 9194 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed) 9195 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 9196 FPR32Op:$Rd, 9197 ssub)), 9198 V128:$Rn, 9199 V128:$Rm, 9200 VectorIndexS:$idx)), 9201 ssub)>; 9202 9203 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 9204 FPR16Op, FPR16Op, V128_lo, 9205 VectorIndexH, asm, ".h", "", "", ".h", 9206 []> { 9207 bits<3> idx; 9208 let Inst{11} = idx{2}; 9209 let Inst{21} = idx{1}; 9210 let Inst{20} = idx{0}; 9211 } 9212 9213 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 9214 FPR32Op, FPR32Op, V128, VectorIndexS, 9215 asm, ".s", "", "", ".s", 9216 [(set (i32 FPR32Op:$dst), 9217 (Accum (i32 FPR32Op:$Rd), 9218 (i32 (int_aarch64_neon_sqrdmulh 9219 (i32 FPR32Op:$Rn), 9220 (i32 (vector_extract (v4i32 V128:$Rm), 9221 VectorIndexS:$idx))))))]> { 9222 bits<2> idx; 9223 let Inst{11} = idx{1}; 9224 let Inst{21} = idx{0}; 9225 } 9226} 9227} // let Predicates = [HasNeon, HasV8_1a] 9228 9229//---------------------------------------------------------------------------- 9230// Crypto extensions 9231//---------------------------------------------------------------------------- 9232 9233let Predicates = [HasCrypto] in { 9234let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9235class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 9236 list<dag> pat> 9237 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 9238 Sched<[WriteV]>{ 9239 bits<5> Rd; 9240 bits<5> Rn; 9241 let Inst{31-16} = 0b0100111000101000; 9242 let Inst{15-12} = opc; 9243 let Inst{11-10} = 0b10; 9244 let Inst{9-5} = Rn; 9245 let Inst{4-0} = Rd; 9246} 9247 9248class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 9249 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 9250 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 9251 9252class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 9253 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 9254 "$Rd = $dst", 9255 [(set (v16i8 V128:$dst), 9256 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 9257 9258let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9259class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 9260 dag oops, dag iops, list<dag> pat> 9261 : I<oops, iops, asm, 9262 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 9263 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 9264 Sched<[WriteV]>{ 9265 bits<5> Rd; 9266 bits<5> Rn; 9267 bits<5> Rm; 9268 let Inst{31-21} = 0b01011110000; 9269 let Inst{20-16} = Rm; 9270 let Inst{15} = 0; 9271 let Inst{14-12} = opc; 9272 let Inst{11-10} = 0b00; 9273 let Inst{9-5} = Rn; 9274 let Inst{4-0} = Rd; 9275} 9276 9277class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 9278 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 9279 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 9280 [(set (v4i32 FPR128:$dst), 9281 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 9282 (v4i32 V128:$Rm)))]>; 9283 9284class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 9285 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 9286 (ins V128:$Rd, V128:$Rn, V128:$Rm), 9287 [(set (v4i32 V128:$dst), 9288 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 9289 (v4i32 V128:$Rm)))]>; 9290 9291class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 9292 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 9293 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 9294 [(set (v4i32 FPR128:$dst), 9295 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 9296 (v4i32 V128:$Rm)))]>; 9297 9298let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 9299class SHA2OpInst<bits<4> opc, string asm, string kind, 9300 string cstr, dag oops, dag iops, 9301 list<dag> pat> 9302 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 9303 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 9304 Sched<[WriteV]>{ 9305 bits<5> Rd; 9306 bits<5> Rn; 9307 let Inst{31-16} = 0b0101111000101000; 9308 let Inst{15-12} = opc; 9309 let Inst{11-10} = 0b10; 9310 let Inst{9-5} = Rn; 9311 let Inst{4-0} = Rd; 9312} 9313 9314class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 9315 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 9316 (ins V128:$Rd, V128:$Rn), 9317 [(set (v4i32 V128:$dst), 9318 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 9319 9320class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 9321 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 9322 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 9323} // end of 'let Predicates = [HasCrypto]' 9324 9325//---------------------------------------------------------------------------- 9326// v8.1 atomic instructions extension: 9327// * CAS 9328// * CASP 9329// * SWP 9330// * LDOPregister<OP>, and aliases STOPregister<OP> 9331 9332// Instruction encodings: 9333// 9334// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0 9335// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt 9336// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt 9337// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt 9338// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt 9339// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111 9340 9341// Instruction syntax: 9342// 9343// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 9344// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>] 9345// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>] 9346// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>] 9347// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 9348// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>] 9349// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>] 9350// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>] 9351// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>] 9352// ST<OP>{<order>} <Xs>, [<Xn|SP>] 9353 9354let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in 9355class BaseCASEncoding<dag oops, dag iops, string asm, string operands, 9356 string cstr, list<dag> pattern> 9357 : I<oops, iops, asm, operands, cstr, pattern> { 9358 bits<2> Sz; 9359 bit NP; 9360 bit Acq; 9361 bit Rel; 9362 bits<5> Rs; 9363 bits<5> Rn; 9364 bits<5> Rt; 9365 let Inst{31-30} = Sz; 9366 let Inst{29-24} = 0b001000; 9367 let Inst{23} = NP; 9368 let Inst{22} = Acq; 9369 let Inst{21} = 0b1; 9370 let Inst{20-16} = Rs; 9371 let Inst{15} = Rel; 9372 let Inst{14-10} = 0b11111; 9373 let Inst{9-5} = Rn; 9374 let Inst{4-0} = Rt; 9375} 9376 9377class BaseCAS<string order, string size, RegisterClass RC> 9378 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 9379 "cas" # order # size, "\t$Rs, $Rt, [$Rn]", 9380 "$out = $Rs",[]> { 9381 let NP = 1; 9382} 9383 9384multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> { 9385 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>; 9386 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>; 9387 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>; 9388 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>; 9389} 9390 9391class BaseCASP<string order, string size, RegisterOperand RC> 9392 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn), 9393 "casp" # order # size, "\t$Rs, $Rt, [$Rn]", 9394 "$out = $Rs",[]> { 9395 let NP = 0; 9396} 9397 9398multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> { 9399 let Sz = 0b00, Acq = Acq, Rel = Rel in 9400 def s : BaseCASP<order, "", WSeqPairClassOperand>; 9401 let Sz = 0b01, Acq = Acq, Rel = Rel in 9402 def d : BaseCASP<order, "", XSeqPairClassOperand>; 9403} 9404 9405let Predicates = [HasV8_1a] in 9406class BaseSWP<string order, string size, RegisterClass RC> 9407 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size, 9408 "\t$Rs, $Rt, [$Rn]","",[]> { 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 bits<2> Sz; 9441 bit Acq; 9442 bit Rel; 9443 bits<5> Rs; 9444 bits<3> opc; 9445 bits<5> Rn; 9446 bits<5> Rt; 9447 let Inst{31-30} = Sz; 9448 let Inst{29-24} = 0b111000; 9449 let Inst{23} = Acq; 9450 let Inst{22} = Rel; 9451 let Inst{21} = 0b1; 9452 let Inst{20-16} = Rs; 9453 let Inst{15} = 0b0; 9454 let Inst{14-12} = opc; 9455 let Inst{11-10} = 0b00; 9456 let Inst{9-5} = Rn; 9457 let Inst{4-0} = Rt; 9458} 9459 9460multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 9461 string order> { 9462 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 9463 def b : BaseLDOPregister<op, order, "b", GPR32>; 9464 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 9465 def h : BaseLDOPregister<op, order, "h", GPR32>; 9466 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 9467 def s : BaseLDOPregister<op, order, "", GPR32>; 9468 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 9469 def d : BaseLDOPregister<op, order, "", GPR64>; 9470} 9471 9472let Predicates = [HasV8_1a] in 9473class BaseSTOPregister<string asm, RegisterClass OP, Register Reg, 9474 Instruction inst> : 9475 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>; 9476 9477multiclass STOPregister<string asm, string instr> { 9478 def : BaseSTOPregister<asm # "lb", GPR32, WZR, 9479 !cast<Instruction>(instr # "Lb")>; 9480 def : BaseSTOPregister<asm # "lh", GPR32, WZR, 9481 !cast<Instruction>(instr # "Lh")>; 9482 def : BaseSTOPregister<asm # "l", GPR32, WZR, 9483 !cast<Instruction>(instr # "Ls")>; 9484 def : BaseSTOPregister<asm # "l", GPR64, XZR, 9485 !cast<Instruction>(instr # "Ld")>; 9486 def : BaseSTOPregister<asm # "b", GPR32, WZR, 9487 !cast<Instruction>(instr # "b")>; 9488 def : BaseSTOPregister<asm # "h", GPR32, WZR, 9489 !cast<Instruction>(instr # "h")>; 9490 def : BaseSTOPregister<asm, GPR32, WZR, 9491 !cast<Instruction>(instr # "s")>; 9492 def : BaseSTOPregister<asm, GPR64, XZR, 9493 !cast<Instruction>(instr # "d")>; 9494} 9495 9496//---------------------------------------------------------------------------- 9497// Allow the size specifier tokens to be upper case, not just lower. 9498def : TokenAlias<".8B", ".8b">; 9499def : TokenAlias<".4H", ".4h">; 9500def : TokenAlias<".2S", ".2s">; 9501def : TokenAlias<".1D", ".1d">; 9502def : TokenAlias<".16B", ".16b">; 9503def : TokenAlias<".8H", ".8h">; 9504def : TokenAlias<".4S", ".4s">; 9505def : TokenAlias<".2D", ".2d">; 9506def : TokenAlias<".1Q", ".1q">; 9507def : TokenAlias<".2H", ".2h">; 9508def : TokenAlias<".B", ".b">; 9509def : TokenAlias<".H", ".h">; 9510def : TokenAlias<".S", ".s">; 9511def : TokenAlias<".D", ".d">; 9512def : TokenAlias<".Q", ".q">; 9513