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 251class AsmImmRange<int Low, int High> : AsmOperandClass { 252 let Name = "Imm" # Low # "_" # High; 253 let DiagnosticType = "InvalidImm" # Low # "_" # High; 254} 255 256def Imm1_8Operand : AsmImmRange<1, 8>; 257def Imm1_16Operand : AsmImmRange<1, 16>; 258def Imm1_32Operand : AsmImmRange<1, 32>; 259def Imm1_64Operand : AsmImmRange<1, 64>; 260 261def MovZSymbolG3AsmOperand : AsmOperandClass { 262 let Name = "MovZSymbolG3"; 263 let RenderMethod = "addImmOperands"; 264} 265 266def movz_symbol_g3 : Operand<i32> { 267 let ParserMatchClass = MovZSymbolG3AsmOperand; 268} 269 270def MovZSymbolG2AsmOperand : AsmOperandClass { 271 let Name = "MovZSymbolG2"; 272 let RenderMethod = "addImmOperands"; 273} 274 275def movz_symbol_g2 : Operand<i32> { 276 let ParserMatchClass = MovZSymbolG2AsmOperand; 277} 278 279def MovZSymbolG1AsmOperand : AsmOperandClass { 280 let Name = "MovZSymbolG1"; 281 let RenderMethod = "addImmOperands"; 282} 283 284def movz_symbol_g1 : Operand<i32> { 285 let ParserMatchClass = MovZSymbolG1AsmOperand; 286} 287 288def MovZSymbolG0AsmOperand : AsmOperandClass { 289 let Name = "MovZSymbolG0"; 290 let RenderMethod = "addImmOperands"; 291} 292 293def movz_symbol_g0 : Operand<i32> { 294 let ParserMatchClass = MovZSymbolG0AsmOperand; 295} 296 297def MovKSymbolG3AsmOperand : AsmOperandClass { 298 let Name = "MovKSymbolG3"; 299 let RenderMethod = "addImmOperands"; 300} 301 302def movk_symbol_g3 : Operand<i32> { 303 let ParserMatchClass = MovKSymbolG3AsmOperand; 304} 305 306def MovKSymbolG2AsmOperand : AsmOperandClass { 307 let Name = "MovKSymbolG2"; 308 let RenderMethod = "addImmOperands"; 309} 310 311def movk_symbol_g2 : Operand<i32> { 312 let ParserMatchClass = MovKSymbolG2AsmOperand; 313} 314 315def MovKSymbolG1AsmOperand : AsmOperandClass { 316 let Name = "MovKSymbolG1"; 317 let RenderMethod = "addImmOperands"; 318} 319 320def movk_symbol_g1 : Operand<i32> { 321 let ParserMatchClass = MovKSymbolG1AsmOperand; 322} 323 324def MovKSymbolG0AsmOperand : AsmOperandClass { 325 let Name = "MovKSymbolG0"; 326 let RenderMethod = "addImmOperands"; 327} 328 329def movk_symbol_g0 : Operand<i32> { 330 let ParserMatchClass = MovKSymbolG0AsmOperand; 331} 332 333class fixedpoint_i32<ValueType FloatVT> 334 : Operand<FloatVT>, 335 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> { 336 let EncoderMethod = "getFixedPointScaleOpValue"; 337 let DecoderMethod = "DecodeFixedPointScaleImm32"; 338 let ParserMatchClass = Imm1_32Operand; 339} 340 341class fixedpoint_i64<ValueType FloatVT> 342 : Operand<FloatVT>, 343 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> { 344 let EncoderMethod = "getFixedPointScaleOpValue"; 345 let DecoderMethod = "DecodeFixedPointScaleImm64"; 346 let ParserMatchClass = Imm1_64Operand; 347} 348 349def fixedpoint_f32_i32 : fixedpoint_i32<f32>; 350def fixedpoint_f64_i32 : fixedpoint_i32<f64>; 351 352def fixedpoint_f32_i64 : fixedpoint_i64<f32>; 353def fixedpoint_f64_i64 : fixedpoint_i64<f64>; 354 355def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{ 356 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 357}]> { 358 let EncoderMethod = "getVecShiftR8OpValue"; 359 let DecoderMethod = "DecodeVecShiftR8Imm"; 360 let ParserMatchClass = Imm1_8Operand; 361} 362def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{ 363 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 364}]> { 365 let EncoderMethod = "getVecShiftR16OpValue"; 366 let DecoderMethod = "DecodeVecShiftR16Imm"; 367 let ParserMatchClass = Imm1_16Operand; 368} 369def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{ 370 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9); 371}]> { 372 let EncoderMethod = "getVecShiftR16OpValue"; 373 let DecoderMethod = "DecodeVecShiftR16ImmNarrow"; 374 let ParserMatchClass = Imm1_8Operand; 375} 376def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{ 377 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 378}]> { 379 let EncoderMethod = "getVecShiftR32OpValue"; 380 let DecoderMethod = "DecodeVecShiftR32Imm"; 381 let ParserMatchClass = Imm1_32Operand; 382} 383def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{ 384 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17); 385}]> { 386 let EncoderMethod = "getVecShiftR32OpValue"; 387 let DecoderMethod = "DecodeVecShiftR32ImmNarrow"; 388 let ParserMatchClass = Imm1_16Operand; 389} 390def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{ 391 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65); 392}]> { 393 let EncoderMethod = "getVecShiftR64OpValue"; 394 let DecoderMethod = "DecodeVecShiftR64Imm"; 395 let ParserMatchClass = Imm1_64Operand; 396} 397def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{ 398 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33); 399}]> { 400 let EncoderMethod = "getVecShiftR64OpValue"; 401 let DecoderMethod = "DecodeVecShiftR64ImmNarrow"; 402 let ParserMatchClass = Imm1_32Operand; 403} 404 405def Imm0_7Operand : AsmImmRange<0, 7>; 406def Imm0_15Operand : AsmImmRange<0, 15>; 407def Imm0_31Operand : AsmImmRange<0, 31>; 408def Imm0_63Operand : AsmImmRange<0, 63>; 409 410def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{ 411 return (((uint32_t)Imm) < 8); 412}]> { 413 let EncoderMethod = "getVecShiftL8OpValue"; 414 let DecoderMethod = "DecodeVecShiftL8Imm"; 415 let ParserMatchClass = Imm0_7Operand; 416} 417def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{ 418 return (((uint32_t)Imm) < 16); 419}]> { 420 let EncoderMethod = "getVecShiftL16OpValue"; 421 let DecoderMethod = "DecodeVecShiftL16Imm"; 422 let ParserMatchClass = Imm0_15Operand; 423} 424def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{ 425 return (((uint32_t)Imm) < 32); 426}]> { 427 let EncoderMethod = "getVecShiftL32OpValue"; 428 let DecoderMethod = "DecodeVecShiftL32Imm"; 429 let ParserMatchClass = Imm0_31Operand; 430} 431def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{ 432 return (((uint32_t)Imm) < 64); 433}]> { 434 let EncoderMethod = "getVecShiftL64OpValue"; 435 let DecoderMethod = "DecodeVecShiftL64Imm"; 436 let ParserMatchClass = Imm0_63Operand; 437} 438 439 440// Crazy immediate formats used by 32-bit and 64-bit logical immediate 441// instructions for splatting repeating bit patterns across the immediate. 442def logical_imm32_XFORM : SDNodeXForm<imm, [{ 443 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32); 444 return CurDAG->getTargetConstant(enc, MVT::i32); 445}]>; 446def logical_imm64_XFORM : SDNodeXForm<imm, [{ 447 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64); 448 return CurDAG->getTargetConstant(enc, MVT::i32); 449}]>; 450 451let DiagnosticType = "LogicalSecondSource" in { 452 def LogicalImm32Operand : AsmOperandClass { 453 let Name = "LogicalImm32"; 454 } 455 def LogicalImm64Operand : AsmOperandClass { 456 let Name = "LogicalImm64"; 457 } 458 def LogicalImm32NotOperand : AsmOperandClass { 459 let Name = "LogicalImm32Not"; 460 } 461 def LogicalImm64NotOperand : AsmOperandClass { 462 let Name = "LogicalImm64Not"; 463 } 464} 465def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{ 466 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32); 467}], logical_imm32_XFORM> { 468 let PrintMethod = "printLogicalImm32"; 469 let ParserMatchClass = LogicalImm32Operand; 470} 471def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{ 472 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64); 473}], logical_imm64_XFORM> { 474 let PrintMethod = "printLogicalImm64"; 475 let ParserMatchClass = LogicalImm64Operand; 476} 477def logical_imm32_not : Operand<i32> { 478 let ParserMatchClass = LogicalImm32NotOperand; 479} 480def logical_imm64_not : Operand<i64> { 481 let ParserMatchClass = LogicalImm64NotOperand; 482} 483 484// imm0_65535 predicate - True if the immediate is in the range [0,65535]. 485def Imm0_65535Operand : AsmImmRange<0, 65535>; 486def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{ 487 return ((uint32_t)Imm) < 65536; 488}]> { 489 let ParserMatchClass = Imm0_65535Operand; 490 let PrintMethod = "printHexImm"; 491} 492 493// imm0_255 predicate - True if the immediate is in the range [0,255]. 494def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; } 495def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ 496 return ((uint32_t)Imm) < 256; 497}]> { 498 let ParserMatchClass = Imm0_255Operand; 499 let PrintMethod = "printHexImm"; 500} 501 502// imm0_127 predicate - True if the immediate is in the range [0,127] 503def Imm0_127Operand : AsmImmRange<0, 127>; 504def imm0_127 : Operand<i32>, ImmLeaf<i32, [{ 505 return ((uint32_t)Imm) < 128; 506}]> { 507 let ParserMatchClass = Imm0_127Operand; 508 let PrintMethod = "printHexImm"; 509} 510 511// NOTE: These imm0_N operands have to be of type i64 because i64 is the size 512// for all shift-amounts. 513 514// imm0_63 predicate - True if the immediate is in the range [0,63] 515def imm0_63 : Operand<i64>, ImmLeaf<i64, [{ 516 return ((uint64_t)Imm) < 64; 517}]> { 518 let ParserMatchClass = Imm0_63Operand; 519} 520 521// imm0_31 predicate - True if the immediate is in the range [0,31] 522def imm0_31 : Operand<i64>, ImmLeaf<i64, [{ 523 return ((uint64_t)Imm) < 32; 524}]> { 525 let ParserMatchClass = Imm0_31Operand; 526} 527 528// imm0_15 predicate - True if the immediate is in the range [0,15] 529def imm0_15 : Operand<i64>, ImmLeaf<i64, [{ 530 return ((uint64_t)Imm) < 16; 531}]> { 532 let ParserMatchClass = Imm0_15Operand; 533} 534 535// imm0_7 predicate - True if the immediate is in the range [0,7] 536def imm0_7 : Operand<i64>, ImmLeaf<i64, [{ 537 return ((uint64_t)Imm) < 8; 538}]> { 539 let ParserMatchClass = Imm0_7Operand; 540} 541 542// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15] 543def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{ 544 return ((uint32_t)Imm) < 16; 545}]>; 546 547// An arithmetic shifter operand: 548// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr 549// {5-0} - imm6 550class arith_shift<ValueType Ty, int width> : Operand<Ty> { 551 let PrintMethod = "printShifter"; 552 let ParserMatchClass = !cast<AsmOperandClass>( 553 "ArithmeticShifterOperand" # width); 554} 555 556def arith_shift32 : arith_shift<i32, 32>; 557def arith_shift64 : arith_shift<i64, 64>; 558 559class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width> 560 : Operand<Ty>, 561 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> { 562 let PrintMethod = "printShiftedRegister"; 563 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width)); 564} 565 566def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>; 567def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>; 568 569// An arithmetic shifter operand: 570// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror 571// {5-0} - imm6 572class logical_shift<int width> : Operand<i32> { 573 let PrintMethod = "printShifter"; 574 let ParserMatchClass = !cast<AsmOperandClass>( 575 "LogicalShifterOperand" # width); 576} 577 578def logical_shift32 : logical_shift<32>; 579def logical_shift64 : logical_shift<64>; 580 581class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop> 582 : Operand<Ty>, 583 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> { 584 let PrintMethod = "printShiftedRegister"; 585 let MIOperandInfo = (ops regclass, shiftop); 586} 587 588def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>; 589def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>; 590 591// A logical vector shifter operand: 592// {7-6} - shift type: 00 = lsl 593// {5-0} - imm6: #0, #8, #16, or #24 594def logical_vec_shift : Operand<i32> { 595 let PrintMethod = "printShifter"; 596 let EncoderMethod = "getVecShifterOpValue"; 597 let ParserMatchClass = LogicalVecShifterOperand; 598} 599 600// A logical vector half-word shifter operand: 601// {7-6} - shift type: 00 = lsl 602// {5-0} - imm6: #0 or #8 603def logical_vec_hw_shift : Operand<i32> { 604 let PrintMethod = "printShifter"; 605 let EncoderMethod = "getVecShifterOpValue"; 606 let ParserMatchClass = LogicalVecHalfWordShifterOperand; 607} 608 609// A vector move shifter operand: 610// {0} - imm1: #8 or #16 611def move_vec_shift : Operand<i32> { 612 let PrintMethod = "printShifter"; 613 let EncoderMethod = "getMoveVecShifterOpValue"; 614 let ParserMatchClass = MoveVecShifterOperand; 615} 616 617def AddSubImmOperand : AsmOperandClass { 618 let Name = "AddSubImm"; 619 let ParserMethod = "tryParseAddSubImm"; 620 let DiagnosticType = "AddSubSecondSource"; 621} 622// An ADD/SUB immediate shifter operand: 623// second operand: 624// {7-6} - shift type: 00 = lsl 625// {5-0} - imm6: #0 or #12 626class addsub_shifted_imm<ValueType Ty> 627 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> { 628 let PrintMethod = "printAddSubImm"; 629 let EncoderMethod = "getAddSubImmOpValue"; 630 let ParserMatchClass = AddSubImmOperand; 631 let MIOperandInfo = (ops i32imm, i32imm); 632} 633 634def addsub_shifted_imm32 : addsub_shifted_imm<i32>; 635def addsub_shifted_imm64 : addsub_shifted_imm<i64>; 636 637class neg_addsub_shifted_imm<ValueType Ty> 638 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> { 639 let PrintMethod = "printAddSubImm"; 640 let EncoderMethod = "getAddSubImmOpValue"; 641 let ParserMatchClass = AddSubImmOperand; 642 let MIOperandInfo = (ops i32imm, i32imm); 643} 644 645def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>; 646def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>; 647 648// An extend operand: 649// {5-3} - extend type 650// {2-0} - imm3 651def arith_extend : Operand<i32> { 652 let PrintMethod = "printArithExtend"; 653 let ParserMatchClass = ExtendOperand; 654} 655def arith_extend64 : Operand<i32> { 656 let PrintMethod = "printArithExtend"; 657 let ParserMatchClass = ExtendOperand64; 658} 659 660// 'extend' that's a lsl of a 64-bit register. 661def arith_extendlsl64 : Operand<i32> { 662 let PrintMethod = "printArithExtend"; 663 let ParserMatchClass = ExtendOperandLSL64; 664} 665 666class arith_extended_reg32<ValueType Ty> : Operand<Ty>, 667 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 668 let PrintMethod = "printExtendedRegister"; 669 let MIOperandInfo = (ops GPR32, arith_extend); 670} 671 672class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>, 673 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> { 674 let PrintMethod = "printExtendedRegister"; 675 let MIOperandInfo = (ops GPR32, arith_extend64); 676} 677 678// Floating-point immediate. 679def fpimm32 : Operand<f32>, 680 PatLeaf<(f32 fpimm), [{ 681 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1; 682 }], SDNodeXForm<fpimm, [{ 683 APFloat InVal = N->getValueAPF(); 684 uint32_t enc = AArch64_AM::getFP32Imm(InVal); 685 return CurDAG->getTargetConstant(enc, MVT::i32); 686 }]>> { 687 let ParserMatchClass = FPImmOperand; 688 let PrintMethod = "printFPImmOperand"; 689} 690def fpimm64 : Operand<f64>, 691 PatLeaf<(f64 fpimm), [{ 692 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1; 693 }], SDNodeXForm<fpimm, [{ 694 APFloat InVal = N->getValueAPF(); 695 uint32_t enc = AArch64_AM::getFP64Imm(InVal); 696 return CurDAG->getTargetConstant(enc, MVT::i32); 697 }]>> { 698 let ParserMatchClass = FPImmOperand; 699 let PrintMethod = "printFPImmOperand"; 700} 701 702def fpimm8 : Operand<i32> { 703 let ParserMatchClass = FPImmOperand; 704 let PrintMethod = "printFPImmOperand"; 705} 706 707def fpimm0 : PatLeaf<(fpimm), [{ 708 return N->isExactlyValue(+0.0); 709}]>; 710 711// Vector lane operands 712class AsmVectorIndex<string Suffix> : AsmOperandClass { 713 let Name = "VectorIndex" # Suffix; 714 let DiagnosticType = "InvalidIndex" # Suffix; 715} 716def VectorIndex1Operand : AsmVectorIndex<"1">; 717def VectorIndexBOperand : AsmVectorIndex<"B">; 718def VectorIndexHOperand : AsmVectorIndex<"H">; 719def VectorIndexSOperand : AsmVectorIndex<"S">; 720def VectorIndexDOperand : AsmVectorIndex<"D">; 721 722def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{ 723 return ((uint64_t)Imm) == 1; 724}]> { 725 let ParserMatchClass = VectorIndex1Operand; 726 let PrintMethod = "printVectorIndex"; 727 let MIOperandInfo = (ops i64imm); 728} 729def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{ 730 return ((uint64_t)Imm) < 16; 731}]> { 732 let ParserMatchClass = VectorIndexBOperand; 733 let PrintMethod = "printVectorIndex"; 734 let MIOperandInfo = (ops i64imm); 735} 736def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{ 737 return ((uint64_t)Imm) < 8; 738}]> { 739 let ParserMatchClass = VectorIndexHOperand; 740 let PrintMethod = "printVectorIndex"; 741 let MIOperandInfo = (ops i64imm); 742} 743def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{ 744 return ((uint64_t)Imm) < 4; 745}]> { 746 let ParserMatchClass = VectorIndexSOperand; 747 let PrintMethod = "printVectorIndex"; 748 let MIOperandInfo = (ops i64imm); 749} 750def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{ 751 return ((uint64_t)Imm) < 2; 752}]> { 753 let ParserMatchClass = VectorIndexDOperand; 754 let PrintMethod = "printVectorIndex"; 755 let MIOperandInfo = (ops i64imm); 756} 757 758// 8-bit immediate for AdvSIMD where 64-bit values of the form: 759// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh 760// are encoded as the eight bit value 'abcdefgh'. 761def simdimmtype10 : Operand<i32>, 762 PatLeaf<(f64 fpimm), [{ 763 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF() 764 .bitcastToAPInt() 765 .getZExtValue()); 766 }], SDNodeXForm<fpimm, [{ 767 APFloat InVal = N->getValueAPF(); 768 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF() 769 .bitcastToAPInt() 770 .getZExtValue()); 771 return CurDAG->getTargetConstant(enc, MVT::i32); 772 }]>> { 773 let ParserMatchClass = SIMDImmType10Operand; 774 let PrintMethod = "printSIMDType10Operand"; 775} 776 777 778//--- 779// System management 780//--- 781 782// Base encoding for system instruction operands. 783let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 784class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands, 785 list<dag> pattern = []> 786 : I<oops, iops, asm, operands, "", pattern> { 787 let Inst{31-22} = 0b1101010100; 788 let Inst{21} = L; 789} 790 791// System instructions which do not have an Rt register. 792class SimpleSystemI<bit L, dag iops, string asm, string operands, 793 list<dag> pattern = []> 794 : BaseSystemI<L, (outs), iops, asm, operands, pattern> { 795 let Inst{4-0} = 0b11111; 796} 797 798// System instructions which have an Rt register. 799class RtSystemI<bit L, dag oops, dag iops, string asm, string operands> 800 : BaseSystemI<L, oops, iops, asm, operands>, 801 Sched<[WriteSys]> { 802 bits<5> Rt; 803 let Inst{4-0} = Rt; 804} 805 806// Hint instructions that take both a CRm and a 3-bit immediate. 807// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot 808// model patterns with sufficiently fine granularity 809let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in 810 class HintI<string mnemonic> 811 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "", 812 [(int_aarch64_hint imm0_127:$imm)]>, 813 Sched<[WriteHint]> { 814 bits <7> imm; 815 let Inst{20-12} = 0b000110010; 816 let Inst{11-5} = imm; 817 } 818 819// System instructions taking a single literal operand which encodes into 820// CRm. op2 differentiates the opcodes. 821def BarrierAsmOperand : AsmOperandClass { 822 let Name = "Barrier"; 823 let ParserMethod = "tryParseBarrierOperand"; 824} 825def barrier_op : Operand<i32> { 826 let PrintMethod = "printBarrierOption"; 827 let ParserMatchClass = BarrierAsmOperand; 828} 829class CRmSystemI<Operand crmtype, bits<3> opc, string asm, 830 list<dag> pattern = []> 831 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>, 832 Sched<[WriteBarrier]> { 833 bits<4> CRm; 834 let Inst{20-12} = 0b000110011; 835 let Inst{11-8} = CRm; 836 let Inst{7-5} = opc; 837} 838 839// MRS/MSR system instructions. These have different operand classes because 840// a different subset of registers can be accessed through each instruction. 841def MRSSystemRegisterOperand : AsmOperandClass { 842 let Name = "MRSSystemRegister"; 843 let ParserMethod = "tryParseSysReg"; 844 let DiagnosticType = "MRS"; 845} 846// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate. 847def mrs_sysreg_op : Operand<i32> { 848 let ParserMatchClass = MRSSystemRegisterOperand; 849 let DecoderMethod = "DecodeMRSSystemRegister"; 850 let PrintMethod = "printMRSSystemRegister"; 851} 852 853def MSRSystemRegisterOperand : AsmOperandClass { 854 let Name = "MSRSystemRegister"; 855 let ParserMethod = "tryParseSysReg"; 856 let DiagnosticType = "MSR"; 857} 858def msr_sysreg_op : Operand<i32> { 859 let ParserMatchClass = MSRSystemRegisterOperand; 860 let DecoderMethod = "DecodeMSRSystemRegister"; 861 let PrintMethod = "printMSRSystemRegister"; 862} 863 864class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), 865 "mrs", "\t$Rt, $systemreg"> { 866 bits<16> systemreg; 867 let Inst{20-5} = systemreg; 868} 869 870// FIXME: Some of these def NZCV, others don't. Best way to model that? 871// Explicitly modeling each of the system register as a register class 872// would do it, but feels like overkill at this point. 873class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), 874 "msr", "\t$systemreg, $Rt"> { 875 bits<16> systemreg; 876 let Inst{20-5} = systemreg; 877} 878 879def SystemPStateFieldOperand : AsmOperandClass { 880 let Name = "SystemPStateField"; 881 let ParserMethod = "tryParseSysReg"; 882} 883def pstatefield_op : Operand<i32> { 884 let ParserMatchClass = SystemPStateFieldOperand; 885 let PrintMethod = "printSystemPStateField"; 886} 887 888let Defs = [NZCV] in 889class MSRpstateI 890 : SimpleSystemI<0, (ins pstatefield_op:$pstate_field, imm0_15:$imm), 891 "msr", "\t$pstate_field, $imm">, 892 Sched<[WriteSys]> { 893 bits<6> pstatefield; 894 bits<4> imm; 895 let Inst{20-19} = 0b00; 896 let Inst{18-16} = pstatefield{5-3}; 897 let Inst{15-12} = 0b0100; 898 let Inst{11-8} = imm; 899 let Inst{7-5} = pstatefield{2-0}; 900 901 let DecoderMethod = "DecodeSystemPStateInstruction"; 902} 903 904// SYS and SYSL generic system instructions. 905def SysCRAsmOperand : AsmOperandClass { 906 let Name = "SysCR"; 907 let ParserMethod = "tryParseSysCROperand"; 908} 909 910def sys_cr_op : Operand<i32> { 911 let PrintMethod = "printSysCROperand"; 912 let ParserMatchClass = SysCRAsmOperand; 913} 914 915class SystemXtI<bit L, string asm> 916 : RtSystemI<L, (outs), 917 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt), 918 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> { 919 bits<3> op1; 920 bits<4> Cn; 921 bits<4> Cm; 922 bits<3> op2; 923 let Inst{20-19} = 0b01; 924 let Inst{18-16} = op1; 925 let Inst{15-12} = Cn; 926 let Inst{11-8} = Cm; 927 let Inst{7-5} = op2; 928} 929 930class SystemLXtI<bit L, string asm> 931 : RtSystemI<L, (outs), 932 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2), 933 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> { 934 bits<3> op1; 935 bits<4> Cn; 936 bits<4> Cm; 937 bits<3> op2; 938 let Inst{20-19} = 0b01; 939 let Inst{18-16} = op1; 940 let Inst{15-12} = Cn; 941 let Inst{11-8} = Cm; 942 let Inst{7-5} = op2; 943} 944 945 946// Branch (register) instructions: 947// 948// case opc of 949// 0001 blr 950// 0000 br 951// 0101 dret 952// 0100 eret 953// 0010 ret 954// otherwise UNDEFINED 955class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm, 956 string operands, list<dag> pattern> 957 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> { 958 let Inst{31-25} = 0b1101011; 959 let Inst{24-21} = opc; 960 let Inst{20-16} = 0b11111; 961 let Inst{15-10} = 0b000000; 962 let Inst{4-0} = 0b00000; 963} 964 965class BranchReg<bits<4> opc, string asm, list<dag> pattern> 966 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> { 967 bits<5> Rn; 968 let Inst{9-5} = Rn; 969} 970 971let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in 972class SpecialReturn<bits<4> opc, string asm> 973 : BaseBranchReg<opc, (outs), (ins), asm, "", []> { 974 let Inst{9-5} = 0b11111; 975} 976 977//--- 978// Conditional branch instruction. 979//--- 980 981// Condition code. 982// 4-bit immediate. Pretty-printed as <cc> 983def ccode : Operand<i32> { 984 let PrintMethod = "printCondCode"; 985 let ParserMatchClass = CondCode; 986} 987def inv_ccode : Operand<i32> { 988 // AL and NV are invalid in the aliases which use inv_ccode 989 let PrintMethod = "printInverseCondCode"; 990 let ParserMatchClass = CondCode; 991 let MCOperandPredicate = [{ 992 return MCOp.isImm() && 993 MCOp.getImm() != AArch64CC::AL && 994 MCOp.getImm() != AArch64CC::NV; 995 }]; 996} 997 998// Conditional branch target. 19-bit immediate. The low two bits of the target 999// offset are implied zero and so are not part of the immediate. 1000def PCRelLabel19Operand : AsmOperandClass { 1001 let Name = "PCRelLabel19"; 1002 let DiagnosticType = "InvalidLabel"; 1003} 1004def am_brcond : Operand<OtherVT> { 1005 let EncoderMethod = "getCondBranchTargetOpValue"; 1006 let DecoderMethod = "DecodePCRelLabel19"; 1007 let PrintMethod = "printAlignedLabel"; 1008 let ParserMatchClass = PCRelLabel19Operand; 1009} 1010 1011class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), 1012 "b", ".$cond\t$target", "", 1013 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, 1014 Sched<[WriteBr]> { 1015 let isBranch = 1; 1016 let isTerminator = 1; 1017 let Uses = [NZCV]; 1018 1019 bits<4> cond; 1020 bits<19> target; 1021 let Inst{31-24} = 0b01010100; 1022 let Inst{23-5} = target; 1023 let Inst{4} = 0; 1024 let Inst{3-0} = cond; 1025} 1026 1027//--- 1028// Compare-and-branch instructions. 1029//--- 1030class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node> 1031 : I<(outs), (ins regtype:$Rt, am_brcond:$target), 1032 asm, "\t$Rt, $target", "", 1033 [(node regtype:$Rt, bb:$target)]>, 1034 Sched<[WriteBr]> { 1035 let isBranch = 1; 1036 let isTerminator = 1; 1037 1038 bits<5> Rt; 1039 bits<19> target; 1040 let Inst{30-25} = 0b011010; 1041 let Inst{24} = op; 1042 let Inst{23-5} = target; 1043 let Inst{4-0} = Rt; 1044} 1045 1046multiclass CmpBranch<bit op, string asm, SDNode node> { 1047 def W : BaseCmpBranch<GPR32, op, asm, node> { 1048 let Inst{31} = 0; 1049 } 1050 def X : BaseCmpBranch<GPR64, op, asm, node> { 1051 let Inst{31} = 1; 1052 } 1053} 1054 1055//--- 1056// Test-bit-and-branch instructions. 1057//--- 1058// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of 1059// the target offset are implied zero and so are not part of the immediate. 1060def BranchTarget14Operand : AsmOperandClass { 1061 let Name = "BranchTarget14"; 1062} 1063def am_tbrcond : Operand<OtherVT> { 1064 let EncoderMethod = "getTestBranchTargetOpValue"; 1065 let PrintMethod = "printAlignedLabel"; 1066 let ParserMatchClass = BranchTarget14Operand; 1067} 1068 1069// AsmOperand classes to emit (or not) special diagnostics 1070def TBZImm0_31Operand : AsmOperandClass { 1071 let Name = "TBZImm0_31"; 1072 let PredicateMethod = "isImm0_31"; 1073 let RenderMethod = "addImm0_31Operands"; 1074} 1075def TBZImm32_63Operand : AsmOperandClass { 1076 let Name = "Imm32_63"; 1077 let DiagnosticType = "InvalidImm0_63"; 1078} 1079 1080class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{ 1081 return (((uint32_t)Imm) < 32); 1082}]> { 1083 let ParserMatchClass = matcher; 1084} 1085 1086def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>; 1087def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>; 1088 1089def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{ 1090 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64); 1091}]> { 1092 let ParserMatchClass = TBZImm32_63Operand; 1093} 1094 1095class BaseTestBranch<RegisterClass regtype, Operand immtype, 1096 bit op, string asm, SDNode node> 1097 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target), 1098 asm, "\t$Rt, $bit_off, $target", "", 1099 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>, 1100 Sched<[WriteBr]> { 1101 let isBranch = 1; 1102 let isTerminator = 1; 1103 1104 bits<5> Rt; 1105 bits<6> bit_off; 1106 bits<14> target; 1107 1108 let Inst{30-25} = 0b011011; 1109 let Inst{24} = op; 1110 let Inst{23-19} = bit_off{4-0}; 1111 let Inst{18-5} = target; 1112 let Inst{4-0} = Rt; 1113 1114 let DecoderMethod = "DecodeTestAndBranch"; 1115} 1116 1117multiclass TestBranch<bit op, string asm, SDNode node> { 1118 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> { 1119 let Inst{31} = 0; 1120 } 1121 1122 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> { 1123 let Inst{31} = 1; 1124 } 1125 1126 // Alias X-reg with 0-31 imm to W-Reg. 1127 def : InstAlias<asm # "\t$Rd, $imm, $target", 1128 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd, 1129 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>; 1130 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target), 1131 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32), 1132 tbz_imm0_31_diag:$imm, bb:$target)>; 1133} 1134 1135//--- 1136// Unconditional branch (immediate) instructions. 1137//--- 1138def BranchTarget26Operand : AsmOperandClass { 1139 let Name = "BranchTarget26"; 1140 let DiagnosticType = "InvalidLabel"; 1141} 1142def am_b_target : Operand<OtherVT> { 1143 let EncoderMethod = "getBranchTargetOpValue"; 1144 let PrintMethod = "printAlignedLabel"; 1145 let ParserMatchClass = BranchTarget26Operand; 1146} 1147def am_bl_target : Operand<i64> { 1148 let EncoderMethod = "getBranchTargetOpValue"; 1149 let PrintMethod = "printAlignedLabel"; 1150 let ParserMatchClass = BranchTarget26Operand; 1151} 1152 1153class BImm<bit op, dag iops, string asm, list<dag> pattern> 1154 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> { 1155 bits<26> addr; 1156 let Inst{31} = op; 1157 let Inst{30-26} = 0b00101; 1158 let Inst{25-0} = addr; 1159 1160 let DecoderMethod = "DecodeUnconditionalBranch"; 1161} 1162 1163class BranchImm<bit op, string asm, list<dag> pattern> 1164 : BImm<op, (ins am_b_target:$addr), asm, pattern>; 1165class CallImm<bit op, string asm, list<dag> pattern> 1166 : BImm<op, (ins am_bl_target:$addr), asm, pattern>; 1167 1168//--- 1169// Basic one-operand data processing instructions. 1170//--- 1171 1172let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1173class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm, 1174 SDPatternOperator node> 1175 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 1176 [(set regtype:$Rd, (node regtype:$Rn))]>, 1177 Sched<[WriteI, ReadI]> { 1178 bits<5> Rd; 1179 bits<5> Rn; 1180 1181 let Inst{30-13} = 0b101101011000000000; 1182 let Inst{12-10} = opc; 1183 let Inst{9-5} = Rn; 1184 let Inst{4-0} = Rd; 1185} 1186 1187let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1188multiclass OneOperandData<bits<3> opc, string asm, 1189 SDPatternOperator node = null_frag> { 1190 def Wr : BaseOneOperandData<opc, GPR32, asm, node> { 1191 let Inst{31} = 0; 1192 } 1193 1194 def Xr : BaseOneOperandData<opc, GPR64, asm, node> { 1195 let Inst{31} = 1; 1196 } 1197} 1198 1199class OneWRegData<bits<3> opc, string asm, SDPatternOperator node> 1200 : BaseOneOperandData<opc, GPR32, asm, node> { 1201 let Inst{31} = 0; 1202} 1203 1204class OneXRegData<bits<3> opc, string asm, SDPatternOperator node> 1205 : BaseOneOperandData<opc, GPR64, asm, node> { 1206 let Inst{31} = 1; 1207} 1208 1209//--- 1210// Basic two-operand data processing instructions. 1211//--- 1212class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1213 list<dag> pattern> 1214 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1215 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1216 Sched<[WriteI, ReadI, ReadI]> { 1217 let Uses = [NZCV]; 1218 bits<5> Rd; 1219 bits<5> Rn; 1220 bits<5> Rm; 1221 let Inst{30} = isSub; 1222 let Inst{28-21} = 0b11010000; 1223 let Inst{20-16} = Rm; 1224 let Inst{15-10} = 0; 1225 let Inst{9-5} = Rn; 1226 let Inst{4-0} = Rd; 1227} 1228 1229class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm, 1230 SDNode OpNode> 1231 : BaseBaseAddSubCarry<isSub, regtype, asm, 1232 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; 1233 1234class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm, 1235 SDNode OpNode> 1236 : BaseBaseAddSubCarry<isSub, regtype, asm, 1237 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), 1238 (implicit NZCV)]> { 1239 let Defs = [NZCV]; 1240} 1241 1242multiclass AddSubCarry<bit isSub, string asm, string asm_setflags, 1243 SDNode OpNode, SDNode OpNode_setflags> { 1244 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> { 1245 let Inst{31} = 0; 1246 let Inst{29} = 0; 1247 } 1248 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> { 1249 let Inst{31} = 1; 1250 let Inst{29} = 0; 1251 } 1252 1253 // Sets flags. 1254 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags, 1255 OpNode_setflags> { 1256 let Inst{31} = 0; 1257 let Inst{29} = 1; 1258 } 1259 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags, 1260 OpNode_setflags> { 1261 let Inst{31} = 1; 1262 let Inst{29} = 1; 1263 } 1264} 1265 1266class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm, 1267 SDPatternOperator OpNode> 1268 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1269 asm, "\t$Rd, $Rn, $Rm", "", 1270 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> { 1271 bits<5> Rd; 1272 bits<5> Rn; 1273 bits<5> Rm; 1274 let Inst{30-21} = 0b0011010110; 1275 let Inst{20-16} = Rm; 1276 let Inst{15-14} = 0b00; 1277 let Inst{13-10} = opc; 1278 let Inst{9-5} = Rn; 1279 let Inst{4-0} = Rd; 1280} 1281 1282class BaseDiv<bit isSigned, RegisterClass regtype, string asm, 1283 SDPatternOperator OpNode> 1284 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> { 1285 let Inst{10} = isSigned; 1286} 1287 1288multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> { 1289 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>, 1290 Sched<[WriteID32, ReadID, ReadID]> { 1291 let Inst{31} = 0; 1292 } 1293 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>, 1294 Sched<[WriteID64, ReadID, ReadID]> { 1295 let Inst{31} = 1; 1296 } 1297} 1298 1299class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm, 1300 SDPatternOperator OpNode = null_frag> 1301 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>, 1302 Sched<[WriteIS, ReadI]> { 1303 let Inst{11-10} = shift_type; 1304} 1305 1306multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> { 1307 def Wr : BaseShift<shift_type, GPR32, asm> { 1308 let Inst{31} = 0; 1309 } 1310 1311 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> { 1312 let Inst{31} = 1; 1313 } 1314 1315 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)), 1316 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, 1317 (EXTRACT_SUBREG i64:$Rm, sub_32))>; 1318 1319 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))), 1320 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1321 1322 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))), 1323 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1324 1325 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))), 1326 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>; 1327} 1328 1329class ShiftAlias<string asm, Instruction inst, RegisterClass regtype> 1330 : InstAlias<asm#" $dst, $src1, $src2", 1331 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>; 1332 1333class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype, 1334 RegisterClass addtype, string asm, 1335 list<dag> pattern> 1336 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra), 1337 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> { 1338 bits<5> Rd; 1339 bits<5> Rn; 1340 bits<5> Rm; 1341 bits<5> Ra; 1342 let Inst{30-24} = 0b0011011; 1343 let Inst{23-21} = opc; 1344 let Inst{20-16} = Rm; 1345 let Inst{15} = isSub; 1346 let Inst{14-10} = Ra; 1347 let Inst{9-5} = Rn; 1348 let Inst{4-0} = Rd; 1349} 1350 1351multiclass MulAccum<bit isSub, string asm, SDNode AccNode> { 1352 // MADD/MSUB generation is decided by MachineCombiner.cpp 1353 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, 1354 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>, 1355 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1356 let Inst{31} = 0; 1357 } 1358 1359 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, 1360 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>, 1361 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> { 1362 let Inst{31} = 1; 1363 } 1364} 1365 1366class WideMulAccum<bit isSub, bits<3> opc, string asm, 1367 SDNode AccNode, SDNode ExtNode> 1368 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm, 1369 [(set GPR64:$Rd, (AccNode GPR64:$Ra, 1370 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>, 1371 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> { 1372 let Inst{31} = 1; 1373} 1374 1375class MulHi<bits<3> opc, string asm, SDNode OpNode> 1376 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm), 1377 asm, "\t$Rd, $Rn, $Rm", "", 1378 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>, 1379 Sched<[WriteIM64, ReadIM, ReadIM]> { 1380 bits<5> Rd; 1381 bits<5> Rn; 1382 bits<5> Rm; 1383 let Inst{31-24} = 0b10011011; 1384 let Inst{23-21} = opc; 1385 let Inst{20-16} = Rm; 1386 let Inst{15} = 0; 1387 let Inst{9-5} = Rn; 1388 let Inst{4-0} = Rd; 1389 1390 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 1391 // (i.e. all bits 1) but is ignored by the processor. 1392 let PostEncoderMethod = "fixMulHigh"; 1393} 1394 1395class MulAccumWAlias<string asm, Instruction inst> 1396 : InstAlias<asm#" $dst, $src1, $src2", 1397 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>; 1398class MulAccumXAlias<string asm, Instruction inst> 1399 : InstAlias<asm#" $dst, $src1, $src2", 1400 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>; 1401class WideMulAccumAlias<string asm, Instruction inst> 1402 : InstAlias<asm#" $dst, $src1, $src2", 1403 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>; 1404 1405class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg, 1406 SDPatternOperator OpNode, string asm> 1407 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm), 1408 asm, "\t$Rd, $Rn, $Rm", "", 1409 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>, 1410 Sched<[WriteISReg, ReadI, ReadISReg]> { 1411 bits<5> Rd; 1412 bits<5> Rn; 1413 bits<5> Rm; 1414 1415 let Inst{31} = sf; 1416 let Inst{30-21} = 0b0011010110; 1417 let Inst{20-16} = Rm; 1418 let Inst{15-13} = 0b010; 1419 let Inst{12} = C; 1420 let Inst{11-10} = sz; 1421 let Inst{9-5} = Rn; 1422 let Inst{4-0} = Rd; 1423 let Predicates = [HasCRC]; 1424} 1425 1426//--- 1427// Address generation. 1428//--- 1429 1430class ADRI<bit page, string asm, Operand adr, list<dag> pattern> 1431 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "", 1432 pattern>, 1433 Sched<[WriteI]> { 1434 bits<5> Xd; 1435 bits<21> label; 1436 let Inst{31} = page; 1437 let Inst{30-29} = label{1-0}; 1438 let Inst{28-24} = 0b10000; 1439 let Inst{23-5} = label{20-2}; 1440 let Inst{4-0} = Xd; 1441 1442 let DecoderMethod = "DecodeAdrInstruction"; 1443} 1444 1445//--- 1446// Move immediate. 1447//--- 1448 1449def movimm32_imm : Operand<i32> { 1450 let ParserMatchClass = Imm0_65535Operand; 1451 let EncoderMethod = "getMoveWideImmOpValue"; 1452 let PrintMethod = "printHexImm"; 1453} 1454def movimm32_shift : Operand<i32> { 1455 let PrintMethod = "printShifter"; 1456 let ParserMatchClass = MovImm32ShifterOperand; 1457} 1458def movimm64_shift : Operand<i32> { 1459 let PrintMethod = "printShifter"; 1460 let ParserMatchClass = MovImm64ShifterOperand; 1461} 1462 1463let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1464class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 1465 string asm> 1466 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift), 1467 asm, "\t$Rd, $imm$shift", "", []>, 1468 Sched<[WriteImm]> { 1469 bits<5> Rd; 1470 bits<16> imm; 1471 bits<6> shift; 1472 let Inst{30-29} = opc; 1473 let Inst{28-23} = 0b100101; 1474 let Inst{22-21} = shift{5-4}; 1475 let Inst{20-5} = imm; 1476 let Inst{4-0} = Rd; 1477 1478 let DecoderMethod = "DecodeMoveImmInstruction"; 1479} 1480 1481multiclass MoveImmediate<bits<2> opc, string asm> { 1482 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> { 1483 let Inst{31} = 0; 1484 } 1485 1486 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> { 1487 let Inst{31} = 1; 1488 } 1489} 1490 1491let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1492class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter, 1493 string asm> 1494 : I<(outs regtype:$Rd), 1495 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift), 1496 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>, 1497 Sched<[WriteI, ReadI]> { 1498 bits<5> Rd; 1499 bits<16> imm; 1500 bits<6> shift; 1501 let Inst{30-29} = opc; 1502 let Inst{28-23} = 0b100101; 1503 let Inst{22-21} = shift{5-4}; 1504 let Inst{20-5} = imm; 1505 let Inst{4-0} = Rd; 1506 1507 let DecoderMethod = "DecodeMoveImmInstruction"; 1508} 1509 1510multiclass InsertImmediate<bits<2> opc, string asm> { 1511 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> { 1512 let Inst{31} = 0; 1513 } 1514 1515 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> { 1516 let Inst{31} = 1; 1517 } 1518} 1519 1520//--- 1521// Add/Subtract 1522//--- 1523 1524class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype, 1525 RegisterClass srcRegtype, addsub_shifted_imm immtype, 1526 string asm, SDPatternOperator OpNode> 1527 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm), 1528 asm, "\t$Rd, $Rn, $imm", "", 1529 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>, 1530 Sched<[WriteI, ReadI]> { 1531 bits<5> Rd; 1532 bits<5> Rn; 1533 bits<14> imm; 1534 let Inst{30} = isSub; 1535 let Inst{29} = setFlags; 1536 let Inst{28-24} = 0b10001; 1537 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12 1538 let Inst{21-10} = imm{11-0}; 1539 let Inst{9-5} = Rn; 1540 let Inst{4-0} = Rd; 1541 let DecoderMethod = "DecodeBaseAddSubImm"; 1542} 1543 1544class BaseAddSubRegPseudo<RegisterClass regtype, 1545 SDPatternOperator OpNode> 1546 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 1547 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 1548 Sched<[WriteI, ReadI, ReadI]>; 1549 1550class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype, 1551 arith_shifted_reg shifted_regtype, string asm, 1552 SDPatternOperator OpNode> 1553 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 1554 asm, "\t$Rd, $Rn, $Rm", "", 1555 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, 1556 Sched<[WriteISReg, ReadI, ReadISReg]> { 1557 // The operands are in order to match the 'addr' MI operands, so we 1558 // don't need an encoder method and by-name matching. Just use the default 1559 // in-order handling. Since we're using by-order, make sure the names 1560 // do not match. 1561 bits<5> dst; 1562 bits<5> src1; 1563 bits<5> src2; 1564 bits<8> shift; 1565 let Inst{30} = isSub; 1566 let Inst{29} = setFlags; 1567 let Inst{28-24} = 0b01011; 1568 let Inst{23-22} = shift{7-6}; 1569 let Inst{21} = 0; 1570 let Inst{20-16} = src2; 1571 let Inst{15-10} = shift{5-0}; 1572 let Inst{9-5} = src1; 1573 let Inst{4-0} = dst; 1574 1575 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 1576} 1577 1578class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype, 1579 RegisterClass src1Regtype, Operand src2Regtype, 1580 string asm, SDPatternOperator OpNode> 1581 : I<(outs dstRegtype:$R1), 1582 (ins src1Regtype:$R2, src2Regtype:$R3), 1583 asm, "\t$R1, $R2, $R3", "", 1584 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, 1585 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 1586 bits<5> Rd; 1587 bits<5> Rn; 1588 bits<5> Rm; 1589 bits<6> ext; 1590 let Inst{30} = isSub; 1591 let Inst{29} = setFlags; 1592 let Inst{28-24} = 0b01011; 1593 let Inst{23-21} = 0b001; 1594 let Inst{20-16} = Rm; 1595 let Inst{15-13} = ext{5-3}; 1596 let Inst{12-10} = ext{2-0}; 1597 let Inst{9-5} = Rn; 1598 let Inst{4-0} = Rd; 1599 1600 let DecoderMethod = "DecodeAddSubERegInstruction"; 1601} 1602 1603let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1604class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype, 1605 RegisterClass src1Regtype, RegisterClass src2Regtype, 1606 Operand ext_op, string asm> 1607 : I<(outs dstRegtype:$Rd), 1608 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext), 1609 asm, "\t$Rd, $Rn, $Rm$ext", "", []>, 1610 Sched<[WriteIEReg, ReadI, ReadIEReg]> { 1611 bits<5> Rd; 1612 bits<5> Rn; 1613 bits<5> Rm; 1614 bits<6> ext; 1615 let Inst{30} = isSub; 1616 let Inst{29} = setFlags; 1617 let Inst{28-24} = 0b01011; 1618 let Inst{23-21} = 0b001; 1619 let Inst{20-16} = Rm; 1620 let Inst{15} = ext{5}; 1621 let Inst{12-10} = ext{2-0}; 1622 let Inst{9-5} = Rn; 1623 let Inst{4-0} = Rd; 1624 1625 let DecoderMethod = "DecodeAddSubERegInstruction"; 1626} 1627 1628// Aliases for register+register add/subtract. 1629class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype, 1630 RegisterClass src1Regtype, RegisterClass src2Regtype, 1631 int shiftExt> 1632 : InstAlias<asm#" $dst, $src1, $src2", 1633 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2, 1634 shiftExt)>; 1635 1636multiclass AddSub<bit isSub, string mnemonic, 1637 SDPatternOperator OpNode = null_frag> { 1638 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { 1639 // Add/Subtract immediate 1640 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32, 1641 mnemonic, OpNode> { 1642 let Inst{31} = 0; 1643 } 1644 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64, 1645 mnemonic, OpNode> { 1646 let Inst{31} = 1; 1647 } 1648 1649 // Add/Subtract register - Only used for CodeGen 1650 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 1651 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 1652 1653 // Add/Subtract shifted register 1654 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic, 1655 OpNode> { 1656 let Inst{31} = 0; 1657 } 1658 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic, 1659 OpNode> { 1660 let Inst{31} = 1; 1661 } 1662 } 1663 1664 // Add/Subtract extended register 1665 let AddedComplexity = 1, hasSideEffects = 0 in { 1666 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp, 1667 arith_extended_reg32<i32>, mnemonic, OpNode> { 1668 let Inst{31} = 0; 1669 } 1670 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp, 1671 arith_extended_reg32to64<i64>, mnemonic, OpNode> { 1672 let Inst{31} = 1; 1673 } 1674 } 1675 1676 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64, 1677 arith_extendlsl64, mnemonic> { 1678 // UXTX and SXTX only. 1679 let Inst{14-13} = 0b11; 1680 let Inst{31} = 1; 1681 } 1682 1683 // Register/register aliases with no shift when SP is not used. 1684 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 1685 GPR32, GPR32, GPR32, 0>; 1686 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 1687 GPR64, GPR64, GPR64, 0>; 1688 1689 // Register/register aliases with no shift when either the destination or 1690 // first source register is SP. 1691 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1692 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0 1693 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1694 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0 1695 def : AddSubRegAlias<mnemonic, 1696 !cast<Instruction>(NAME#"Xrx64"), 1697 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0 1698 def : AddSubRegAlias<mnemonic, 1699 !cast<Instruction>(NAME#"Xrx64"), 1700 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0 1701} 1702 1703multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp> { 1704 let isCompare = 1, Defs = [NZCV] in { 1705 // Add/Subtract immediate 1706 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32, 1707 mnemonic, OpNode> { 1708 let Inst{31} = 0; 1709 } 1710 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64, 1711 mnemonic, OpNode> { 1712 let Inst{31} = 1; 1713 } 1714 1715 // Add/Subtract register 1716 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>; 1717 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>; 1718 1719 // Add/Subtract shifted register 1720 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic, 1721 OpNode> { 1722 let Inst{31} = 0; 1723 } 1724 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic, 1725 OpNode> { 1726 let Inst{31} = 1; 1727 } 1728 1729 // Add/Subtract extended register 1730 let AddedComplexity = 1 in { 1731 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp, 1732 arith_extended_reg32<i32>, mnemonic, OpNode> { 1733 let Inst{31} = 0; 1734 } 1735 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp, 1736 arith_extended_reg32<i64>, mnemonic, OpNode> { 1737 let Inst{31} = 1; 1738 } 1739 } 1740 1741 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64, 1742 arith_extendlsl64, mnemonic> { 1743 // UXTX and SXTX only. 1744 let Inst{14-13} = 0b11; 1745 let Inst{31} = 1; 1746 } 1747 } // Defs = [NZCV] 1748 1749 // Compare aliases 1750 def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Wri") 1751 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>; 1752 def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Xri") 1753 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>; 1754 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx") 1755 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 1756 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx") 1757 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>; 1758 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64") 1759 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>; 1760 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs") 1761 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>; 1762 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs") 1763 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>; 1764 1765 // Compare shorthands 1766 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrs") 1767 WZR, GPR32:$src1, GPR32:$src2, 0), 5>; 1768 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrs") 1769 XZR, GPR64:$src1, GPR64:$src2, 0), 5>; 1770 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrx") 1771 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>; 1772 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrx64") 1773 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>; 1774 1775 // Register/register aliases with no shift when SP is not used. 1776 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"), 1777 GPR32, GPR32, GPR32, 0>; 1778 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"), 1779 GPR64, GPR64, GPR64, 0>; 1780 1781 // Register/register aliases with no shift when the first source register 1782 // is SP. 1783 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"), 1784 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0 1785 def : AddSubRegAlias<mnemonic, 1786 !cast<Instruction>(NAME#"Xrx64"), 1787 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0 1788} 1789 1790//--- 1791// Extract 1792//--- 1793def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 1794 SDTCisPtrTy<3>]>; 1795def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>; 1796 1797class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm, 1798 list<dag> patterns> 1799 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm), 1800 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>, 1801 Sched<[WriteExtr, ReadExtrHi]> { 1802 bits<5> Rd; 1803 bits<5> Rn; 1804 bits<5> Rm; 1805 bits<6> imm; 1806 1807 let Inst{30-23} = 0b00100111; 1808 let Inst{21} = 0; 1809 let Inst{20-16} = Rm; 1810 let Inst{15-10} = imm; 1811 let Inst{9-5} = Rn; 1812 let Inst{4-0} = Rd; 1813} 1814 1815multiclass ExtractImm<string asm> { 1816 def Wrri : BaseExtractImm<GPR32, imm0_31, asm, 1817 [(set GPR32:$Rd, 1818 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> { 1819 let Inst{31} = 0; 1820 let Inst{22} = 0; 1821 // imm<5> must be zero. 1822 let imm{5} = 0; 1823 } 1824 def Xrri : BaseExtractImm<GPR64, imm0_63, asm, 1825 [(set GPR64:$Rd, 1826 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> { 1827 1828 let Inst{31} = 1; 1829 let Inst{22} = 1; 1830 } 1831} 1832 1833//--- 1834// Bitfield 1835//--- 1836 1837let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1838class BaseBitfieldImm<bits<2> opc, 1839 RegisterClass regtype, Operand imm_type, string asm> 1840 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms), 1841 asm, "\t$Rd, $Rn, $immr, $imms", "", []>, 1842 Sched<[WriteIS, ReadI]> { 1843 bits<5> Rd; 1844 bits<5> Rn; 1845 bits<6> immr; 1846 bits<6> imms; 1847 1848 let Inst{30-29} = opc; 1849 let Inst{28-23} = 0b100110; 1850 let Inst{21-16} = immr; 1851 let Inst{15-10} = imms; 1852 let Inst{9-5} = Rn; 1853 let Inst{4-0} = Rd; 1854} 1855 1856multiclass BitfieldImm<bits<2> opc, string asm> { 1857 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> { 1858 let Inst{31} = 0; 1859 let Inst{22} = 0; 1860 // imms<5> and immr<5> must be zero, else ReservedValue(). 1861 let Inst{21} = 0; 1862 let Inst{15} = 0; 1863 } 1864 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> { 1865 let Inst{31} = 1; 1866 let Inst{22} = 1; 1867 } 1868} 1869 1870let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 1871class BaseBitfieldImmWith2RegArgs<bits<2> opc, 1872 RegisterClass regtype, Operand imm_type, string asm> 1873 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr, 1874 imm_type:$imms), 1875 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>, 1876 Sched<[WriteIS, ReadI]> { 1877 bits<5> Rd; 1878 bits<5> Rn; 1879 bits<6> immr; 1880 bits<6> imms; 1881 1882 let Inst{30-29} = opc; 1883 let Inst{28-23} = 0b100110; 1884 let Inst{21-16} = immr; 1885 let Inst{15-10} = imms; 1886 let Inst{9-5} = Rn; 1887 let Inst{4-0} = Rd; 1888} 1889 1890multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> { 1891 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> { 1892 let Inst{31} = 0; 1893 let Inst{22} = 0; 1894 // imms<5> and immr<5> must be zero, else ReservedValue(). 1895 let Inst{21} = 0; 1896 let Inst{15} = 0; 1897 } 1898 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> { 1899 let Inst{31} = 1; 1900 let Inst{22} = 1; 1901 } 1902} 1903 1904//--- 1905// Logical 1906//--- 1907 1908// Logical (immediate) 1909class BaseLogicalImm<bits<2> opc, RegisterClass dregtype, 1910 RegisterClass sregtype, Operand imm_type, string asm, 1911 list<dag> pattern> 1912 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm), 1913 asm, "\t$Rd, $Rn, $imm", "", pattern>, 1914 Sched<[WriteI, ReadI]> { 1915 bits<5> Rd; 1916 bits<5> Rn; 1917 bits<13> imm; 1918 let Inst{30-29} = opc; 1919 let Inst{28-23} = 0b100100; 1920 let Inst{22} = imm{12}; 1921 let Inst{21-16} = imm{11-6}; 1922 let Inst{15-10} = imm{5-0}; 1923 let Inst{9-5} = Rn; 1924 let Inst{4-0} = Rd; 1925 1926 let DecoderMethod = "DecodeLogicalImmInstruction"; 1927} 1928 1929// Logical (shifted register) 1930class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype, 1931 logical_shifted_reg shifted_regtype, string asm, 1932 list<dag> pattern> 1933 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), 1934 asm, "\t$Rd, $Rn, $Rm", "", pattern>, 1935 Sched<[WriteISReg, ReadI, ReadISReg]> { 1936 // The operands are in order to match the 'addr' MI operands, so we 1937 // don't need an encoder method and by-name matching. Just use the default 1938 // in-order handling. Since we're using by-order, make sure the names 1939 // do not match. 1940 bits<5> dst; 1941 bits<5> src1; 1942 bits<5> src2; 1943 bits<8> shift; 1944 let Inst{30-29} = opc; 1945 let Inst{28-24} = 0b01010; 1946 let Inst{23-22} = shift{7-6}; 1947 let Inst{21} = N; 1948 let Inst{20-16} = src2; 1949 let Inst{15-10} = shift{5-0}; 1950 let Inst{9-5} = src1; 1951 let Inst{4-0} = dst; 1952 1953 let DecoderMethod = "DecodeThreeAddrSRegInstruction"; 1954} 1955 1956// Aliases for register+register logical instructions. 1957class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype> 1958 : InstAlias<asm#" $dst, $src1, $src2", 1959 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>; 1960 1961multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode, 1962 string Alias> { 1963 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 1964 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic, 1965 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn, 1966 logical_imm32:$imm))]> { 1967 let Inst{31} = 0; 1968 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 1969 } 1970 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in 1971 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic, 1972 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn, 1973 logical_imm64:$imm))]> { 1974 let Inst{31} = 1; 1975 } 1976 1977 def : InstAlias<Alias # " $Rd, $Rn, $imm", 1978 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn, 1979 logical_imm32_not:$imm), 0>; 1980 def : InstAlias<Alias # " $Rd, $Rn, $imm", 1981 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn, 1982 logical_imm64_not:$imm), 0>; 1983} 1984 1985multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode, 1986 string Alias> { 1987 let isCompare = 1, Defs = [NZCV] in { 1988 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic, 1989 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> { 1990 let Inst{31} = 0; 1991 let Inst{22} = 0; // 64-bit version has an additional bit of immediate. 1992 } 1993 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic, 1994 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { 1995 let Inst{31} = 1; 1996 } 1997 } // end Defs = [NZCV] 1998 1999 def : InstAlias<Alias # " $Rd, $Rn, $imm", 2000 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn, 2001 logical_imm32_not:$imm), 0>; 2002 def : InstAlias<Alias # " $Rd, $Rn, $imm", 2003 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn, 2004 logical_imm64_not:$imm), 0>; 2005} 2006 2007class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode> 2008 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 2009 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>, 2010 Sched<[WriteI, ReadI, ReadI]>; 2011 2012// Split from LogicalImm as not all instructions have both. 2013multiclass LogicalReg<bits<2> opc, bit N, string mnemonic, 2014 SDPatternOperator OpNode> { 2015 let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 2016 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2017 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2018 } 2019 2020 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2021 [(set GPR32:$Rd, (OpNode GPR32:$Rn, 2022 logical_shifted_reg32:$Rm))]> { 2023 let Inst{31} = 0; 2024 } 2025 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2026 [(set GPR64:$Rd, (OpNode GPR64:$Rn, 2027 logical_shifted_reg64:$Rm))]> { 2028 let Inst{31} = 1; 2029 } 2030 2031 def : LogicalRegAlias<mnemonic, 2032 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2033 def : LogicalRegAlias<mnemonic, 2034 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2035} 2036 2037// Split from LogicalReg to allow setting NZCV Defs 2038multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic, 2039 SDPatternOperator OpNode = null_frag> { 2040 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 2041 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>; 2042 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>; 2043 2044 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, 2045 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> { 2046 let Inst{31} = 0; 2047 } 2048 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, 2049 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { 2050 let Inst{31} = 1; 2051 } 2052 } // Defs = [NZCV] 2053 2054 def : LogicalRegAlias<mnemonic, 2055 !cast<Instruction>(NAME#"Wrs"), GPR32>; 2056 def : LogicalRegAlias<mnemonic, 2057 !cast<Instruction>(NAME#"Xrs"), GPR64>; 2058} 2059 2060//--- 2061// Conditionally set flags 2062//--- 2063 2064let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2065class BaseCondSetFlagsImm<bit op, RegisterClass regtype, string asm> 2066 : I<(outs), (ins regtype:$Rn, imm0_31:$imm, imm0_15:$nzcv, ccode:$cond), 2067 asm, "\t$Rn, $imm, $nzcv, $cond", "", []>, 2068 Sched<[WriteI, ReadI]> { 2069 let Uses = [NZCV]; 2070 let Defs = [NZCV]; 2071 2072 bits<5> Rn; 2073 bits<5> imm; 2074 bits<4> nzcv; 2075 bits<4> cond; 2076 2077 let Inst{30} = op; 2078 let Inst{29-21} = 0b111010010; 2079 let Inst{20-16} = imm; 2080 let Inst{15-12} = cond; 2081 let Inst{11-10} = 0b10; 2082 let Inst{9-5} = Rn; 2083 let Inst{4} = 0b0; 2084 let Inst{3-0} = nzcv; 2085} 2086 2087multiclass CondSetFlagsImm<bit op, string asm> { 2088 def Wi : BaseCondSetFlagsImm<op, GPR32, asm> { 2089 let Inst{31} = 0; 2090 } 2091 def Xi : BaseCondSetFlagsImm<op, GPR64, asm> { 2092 let Inst{31} = 1; 2093 } 2094} 2095 2096let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 2097class BaseCondSetFlagsReg<bit op, RegisterClass regtype, string asm> 2098 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond), 2099 asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>, 2100 Sched<[WriteI, ReadI, ReadI]> { 2101 let Uses = [NZCV]; 2102 let Defs = [NZCV]; 2103 2104 bits<5> Rn; 2105 bits<5> Rm; 2106 bits<4> nzcv; 2107 bits<4> cond; 2108 2109 let Inst{30} = op; 2110 let Inst{29-21} = 0b111010010; 2111 let Inst{20-16} = Rm; 2112 let Inst{15-12} = cond; 2113 let Inst{11-10} = 0b00; 2114 let Inst{9-5} = Rn; 2115 let Inst{4} = 0b0; 2116 let Inst{3-0} = nzcv; 2117} 2118 2119multiclass CondSetFlagsReg<bit op, string asm> { 2120 def Wr : BaseCondSetFlagsReg<op, GPR32, asm> { 2121 let Inst{31} = 0; 2122 } 2123 def Xr : BaseCondSetFlagsReg<op, GPR64, asm> { 2124 let Inst{31} = 1; 2125 } 2126} 2127 2128//--- 2129// Conditional select 2130//--- 2131 2132class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm> 2133 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2134 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2135 [(set regtype:$Rd, 2136 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, 2137 Sched<[WriteI, ReadI, ReadI]> { 2138 let Uses = [NZCV]; 2139 2140 bits<5> Rd; 2141 bits<5> Rn; 2142 bits<5> Rm; 2143 bits<4> cond; 2144 2145 let Inst{30} = op; 2146 let Inst{29-21} = 0b011010100; 2147 let Inst{20-16} = Rm; 2148 let Inst{15-12} = cond; 2149 let Inst{11-10} = op2; 2150 let Inst{9-5} = Rn; 2151 let Inst{4-0} = Rd; 2152} 2153 2154multiclass CondSelect<bit op, bits<2> op2, string asm> { 2155 def Wr : BaseCondSelect<op, op2, GPR32, asm> { 2156 let Inst{31} = 0; 2157 } 2158 def Xr : BaseCondSelect<op, op2, GPR64, asm> { 2159 let Inst{31} = 1; 2160 } 2161} 2162 2163class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm, 2164 PatFrag frag> 2165 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 2166 asm, "\t$Rd, $Rn, $Rm, $cond", "", 2167 [(set regtype:$Rd, 2168 (AArch64csel regtype:$Rn, (frag regtype:$Rm), 2169 (i32 imm:$cond), NZCV))]>, 2170 Sched<[WriteI, ReadI, ReadI]> { 2171 let Uses = [NZCV]; 2172 2173 bits<5> Rd; 2174 bits<5> Rn; 2175 bits<5> Rm; 2176 bits<4> cond; 2177 2178 let Inst{30} = op; 2179 let Inst{29-21} = 0b011010100; 2180 let Inst{20-16} = Rm; 2181 let Inst{15-12} = cond; 2182 let Inst{11-10} = op2; 2183 let Inst{9-5} = Rn; 2184 let Inst{4-0} = Rd; 2185} 2186 2187def inv_cond_XFORM : SDNodeXForm<imm, [{ 2188 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue()); 2189 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), MVT::i32); 2190}]>; 2191 2192multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> { 2193 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> { 2194 let Inst{31} = 0; 2195 } 2196 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> { 2197 let Inst{31} = 1; 2198 } 2199 2200 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), 2201 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm, 2202 (inv_cond_XFORM imm:$cond))>; 2203 2204 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), 2205 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm, 2206 (inv_cond_XFORM imm:$cond))>; 2207} 2208 2209//--- 2210// Special Mask Value 2211//--- 2212def maski8_or_more : Operand<i32>, 2213 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> { 2214} 2215def maski16_or_more : Operand<i32>, 2216 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> { 2217} 2218 2219 2220//--- 2221// Load/store 2222//--- 2223 2224// (unsigned immediate) 2225// Indexed for 8-bit registers. offset is in range [0,4095]. 2226def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>; 2227def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>; 2228def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>; 2229def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>; 2230def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>; 2231 2232class UImm12OffsetOperand<int Scale> : AsmOperandClass { 2233 let Name = "UImm12Offset" # Scale; 2234 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">"; 2235 let PredicateMethod = "isUImm12Offset<" # Scale # ">"; 2236 let DiagnosticType = "InvalidMemoryIndexed" # Scale; 2237} 2238 2239def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>; 2240def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>; 2241def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>; 2242def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>; 2243def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>; 2244 2245class uimm12_scaled<int Scale> : Operand<i64> { 2246 let ParserMatchClass 2247 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand"); 2248 let EncoderMethod 2249 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">"; 2250 let PrintMethod = "printUImm12Offset<" # Scale # ">"; 2251} 2252 2253def uimm12s1 : uimm12_scaled<1>; 2254def uimm12s2 : uimm12_scaled<2>; 2255def uimm12s4 : uimm12_scaled<4>; 2256def uimm12s8 : uimm12_scaled<8>; 2257def uimm12s16 : uimm12_scaled<16>; 2258 2259class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2260 string asm, list<dag> pattern> 2261 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 2262 bits<5> Rt; 2263 2264 bits<5> Rn; 2265 bits<12> offset; 2266 2267 let Inst{31-30} = sz; 2268 let Inst{29-27} = 0b111; 2269 let Inst{26} = V; 2270 let Inst{25-24} = 0b01; 2271 let Inst{23-22} = opc; 2272 let Inst{21-10} = offset; 2273 let Inst{9-5} = Rn; 2274 let Inst{4-0} = Rt; 2275 2276 let DecoderMethod = "DecodeUnsignedLdStInstruction"; 2277} 2278 2279multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2280 Operand indextype, string asm, list<dag> pattern> { 2281 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2282 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt), 2283 (ins GPR64sp:$Rn, indextype:$offset), 2284 asm, pattern>, 2285 Sched<[WriteLD]>; 2286 2287 def : InstAlias<asm # " $Rt, [$Rn]", 2288 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2289} 2290 2291multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2292 Operand indextype, string asm, list<dag> pattern> { 2293 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2294 def ui : BaseLoadStoreUI<sz, V, opc, (outs), 2295 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset), 2296 asm, pattern>, 2297 Sched<[WriteST]>; 2298 2299 def : InstAlias<asm # " $Rt, [$Rn]", 2300 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>; 2301} 2302 2303def PrefetchOperand : AsmOperandClass { 2304 let Name = "Prefetch"; 2305 let ParserMethod = "tryParsePrefetch"; 2306} 2307def prfop : Operand<i32> { 2308 let PrintMethod = "printPrefetchOp"; 2309 let ParserMatchClass = PrefetchOperand; 2310} 2311 2312let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2313class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat> 2314 : BaseLoadStoreUI<sz, V, opc, 2315 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset), 2316 asm, pat>, 2317 Sched<[WriteLD]>; 2318 2319//--- 2320// Load literal 2321//--- 2322 2323// Load literal address: 19-bit immediate. The low two bits of the target 2324// offset are implied zero and so are not part of the immediate. 2325def am_ldrlit : Operand<OtherVT> { 2326 let EncoderMethod = "getLoadLiteralOpValue"; 2327 let DecoderMethod = "DecodePCRelLabel19"; 2328 let PrintMethod = "printAlignedLabel"; 2329 let ParserMatchClass = PCRelLabel19Operand; 2330} 2331 2332let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2333class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm> 2334 : I<(outs regtype:$Rt), (ins am_ldrlit:$label), 2335 asm, "\t$Rt, $label", "", []>, 2336 Sched<[WriteLD]> { 2337 bits<5> Rt; 2338 bits<19> label; 2339 let Inst{31-30} = opc; 2340 let Inst{29-27} = 0b011; 2341 let Inst{26} = V; 2342 let Inst{25-24} = 0b00; 2343 let Inst{23-5} = label; 2344 let Inst{4-0} = Rt; 2345} 2346 2347let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2348class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat> 2349 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label), 2350 asm, "\t$Rt, $label", "", pat>, 2351 Sched<[WriteLD]> { 2352 bits<5> Rt; 2353 bits<19> label; 2354 let Inst{31-30} = opc; 2355 let Inst{29-27} = 0b011; 2356 let Inst{26} = V; 2357 let Inst{25-24} = 0b00; 2358 let Inst{23-5} = label; 2359 let Inst{4-0} = Rt; 2360} 2361 2362//--- 2363// Load/store register offset 2364//--- 2365 2366def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>; 2367def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>; 2368def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>; 2369def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>; 2370def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>; 2371 2372def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>; 2373def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>; 2374def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>; 2375def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>; 2376def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>; 2377 2378class MemExtendOperand<string Reg, int Width> : AsmOperandClass { 2379 let Name = "Mem" # Reg # "Extend" # Width; 2380 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">"; 2381 let RenderMethod = "addMemExtendOperands"; 2382 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width; 2383} 2384 2385def MemWExtend8Operand : MemExtendOperand<"W", 8> { 2386 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 2387 // the trivial shift. 2388 let RenderMethod = "addMemExtend8Operands"; 2389} 2390def MemWExtend16Operand : MemExtendOperand<"W", 16>; 2391def MemWExtend32Operand : MemExtendOperand<"W", 32>; 2392def MemWExtend64Operand : MemExtendOperand<"W", 64>; 2393def MemWExtend128Operand : MemExtendOperand<"W", 128>; 2394 2395def MemXExtend8Operand : MemExtendOperand<"X", 8> { 2396 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs 2397 // the trivial shift. 2398 let RenderMethod = "addMemExtend8Operands"; 2399} 2400def MemXExtend16Operand : MemExtendOperand<"X", 16>; 2401def MemXExtend32Operand : MemExtendOperand<"X", 32>; 2402def MemXExtend64Operand : MemExtendOperand<"X", 64>; 2403def MemXExtend128Operand : MemExtendOperand<"X", 128>; 2404 2405class ro_extend<AsmOperandClass ParserClass, string Reg, int Width> 2406 : Operand<i32> { 2407 let ParserMatchClass = ParserClass; 2408 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">"; 2409 let DecoderMethod = "DecodeMemExtend"; 2410 let EncoderMethod = "getMemExtendOpValue"; 2411 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift); 2412} 2413 2414def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>; 2415def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>; 2416def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>; 2417def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>; 2418def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>; 2419 2420def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>; 2421def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>; 2422def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>; 2423def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>; 2424def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>; 2425 2426class ROAddrMode<ComplexPattern windex, ComplexPattern xindex, 2427 Operand wextend, Operand xextend> { 2428 // CodeGen-level pattern covering the entire addressing mode. 2429 ComplexPattern Wpat = windex; 2430 ComplexPattern Xpat = xindex; 2431 2432 // Asm-level Operand covering the valid "uxtw #3" style syntax. 2433 Operand Wext = wextend; 2434 Operand Xext = xextend; 2435} 2436 2437def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>; 2438def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>; 2439def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>; 2440def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>; 2441def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128, 2442 ro_Xextend128>; 2443 2444class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2445 string asm, dag ins, dag outs, list<dag> pat> 2446 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2447 bits<5> Rt; 2448 bits<5> Rn; 2449 bits<5> Rm; 2450 bits<2> extend; 2451 let Inst{31-30} = sz; 2452 let Inst{29-27} = 0b111; 2453 let Inst{26} = V; 2454 let Inst{25-24} = 0b00; 2455 let Inst{23-22} = opc; 2456 let Inst{21} = 1; 2457 let Inst{20-16} = Rm; 2458 let Inst{15} = extend{1}; // sign extend Rm? 2459 let Inst{14} = 1; 2460 let Inst{12} = extend{0}; // do shift? 2461 let Inst{11-10} = 0b10; 2462 let Inst{9-5} = Rn; 2463 let Inst{4-0} = Rt; 2464} 2465 2466class ROInstAlias<string asm, RegisterClass regtype, Instruction INST> 2467 : InstAlias<asm # " $Rt, [$Rn, $Rm]", 2468 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 2469 2470multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2471 string asm, ValueType Ty, SDPatternOperator loadop> { 2472 let AddedComplexity = 10 in 2473 def roW : LoadStore8RO<sz, V, opc, regtype, asm, 2474 (outs regtype:$Rt), 2475 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 2476 [(set (Ty regtype:$Rt), 2477 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 2478 ro_Wextend8:$extend)))]>, 2479 Sched<[WriteLDIdx, ReadAdrBase]> { 2480 let Inst{13} = 0b0; 2481 } 2482 2483 let AddedComplexity = 10 in 2484 def roX : LoadStore8RO<sz, V, opc, regtype, asm, 2485 (outs regtype:$Rt), 2486 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 2487 [(set (Ty regtype:$Rt), 2488 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 2489 ro_Xextend8:$extend)))]>, 2490 Sched<[WriteLDIdx, ReadAdrBase]> { 2491 let Inst{13} = 0b1; 2492 } 2493 2494 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2495} 2496 2497multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2498 string asm, ValueType Ty, SDPatternOperator storeop> { 2499 let AddedComplexity = 10 in 2500 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 2501 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 2502 [(storeop (Ty regtype:$Rt), 2503 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 2504 ro_Wextend8:$extend))]>, 2505 Sched<[WriteSTIdx, ReadAdrBase]> { 2506 let Inst{13} = 0b0; 2507 } 2508 2509 let AddedComplexity = 10 in 2510 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs), 2511 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 2512 [(storeop (Ty regtype:$Rt), 2513 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 2514 ro_Xextend8:$extend))]>, 2515 Sched<[WriteSTIdx, ReadAdrBase]> { 2516 let Inst{13} = 0b1; 2517 } 2518 2519 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2520} 2521 2522class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2523 string asm, dag ins, dag outs, list<dag> pat> 2524 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2525 bits<5> Rt; 2526 bits<5> Rn; 2527 bits<5> Rm; 2528 bits<2> extend; 2529 let Inst{31-30} = sz; 2530 let Inst{29-27} = 0b111; 2531 let Inst{26} = V; 2532 let Inst{25-24} = 0b00; 2533 let Inst{23-22} = opc; 2534 let Inst{21} = 1; 2535 let Inst{20-16} = Rm; 2536 let Inst{15} = extend{1}; // sign extend Rm? 2537 let Inst{14} = 1; 2538 let Inst{12} = extend{0}; // do shift? 2539 let Inst{11-10} = 0b10; 2540 let Inst{9-5} = Rn; 2541 let Inst{4-0} = Rt; 2542} 2543 2544multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2545 string asm, ValueType Ty, SDPatternOperator loadop> { 2546 let AddedComplexity = 10 in 2547 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2548 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 2549 [(set (Ty regtype:$Rt), 2550 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 2551 ro_Wextend16:$extend)))]>, 2552 Sched<[WriteLDIdx, ReadAdrBase]> { 2553 let Inst{13} = 0b0; 2554 } 2555 2556 let AddedComplexity = 10 in 2557 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2558 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 2559 [(set (Ty regtype:$Rt), 2560 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 2561 ro_Xextend16:$extend)))]>, 2562 Sched<[WriteLDIdx, ReadAdrBase]> { 2563 let Inst{13} = 0b1; 2564 } 2565 2566 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2567} 2568 2569multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2570 string asm, ValueType Ty, SDPatternOperator storeop> { 2571 let AddedComplexity = 10 in 2572 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 2573 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend), 2574 [(storeop (Ty regtype:$Rt), 2575 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 2576 ro_Wextend16:$extend))]>, 2577 Sched<[WriteSTIdx, ReadAdrBase]> { 2578 let Inst{13} = 0b0; 2579 } 2580 2581 let AddedComplexity = 10 in 2582 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs), 2583 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend), 2584 [(storeop (Ty regtype:$Rt), 2585 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 2586 ro_Xextend16:$extend))]>, 2587 Sched<[WriteSTIdx, ReadAdrBase]> { 2588 let Inst{13} = 0b1; 2589 } 2590 2591 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2592} 2593 2594class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2595 string asm, dag ins, dag outs, list<dag> pat> 2596 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2597 bits<5> Rt; 2598 bits<5> Rn; 2599 bits<5> Rm; 2600 bits<2> extend; 2601 let Inst{31-30} = sz; 2602 let Inst{29-27} = 0b111; 2603 let Inst{26} = V; 2604 let Inst{25-24} = 0b00; 2605 let Inst{23-22} = opc; 2606 let Inst{21} = 1; 2607 let Inst{20-16} = Rm; 2608 let Inst{15} = extend{1}; // sign extend Rm? 2609 let Inst{14} = 1; 2610 let Inst{12} = extend{0}; // do shift? 2611 let Inst{11-10} = 0b10; 2612 let Inst{9-5} = Rn; 2613 let Inst{4-0} = Rt; 2614} 2615 2616multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2617 string asm, ValueType Ty, SDPatternOperator loadop> { 2618 let AddedComplexity = 10 in 2619 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2620 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 2621 [(set (Ty regtype:$Rt), 2622 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 2623 ro_Wextend32:$extend)))]>, 2624 Sched<[WriteLDIdx, ReadAdrBase]> { 2625 let Inst{13} = 0b0; 2626 } 2627 2628 let AddedComplexity = 10 in 2629 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2630 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 2631 [(set (Ty regtype:$Rt), 2632 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 2633 ro_Xextend32:$extend)))]>, 2634 Sched<[WriteLDIdx, ReadAdrBase]> { 2635 let Inst{13} = 0b1; 2636 } 2637 2638 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2639} 2640 2641multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2642 string asm, ValueType Ty, SDPatternOperator storeop> { 2643 let AddedComplexity = 10 in 2644 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 2645 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend), 2646 [(storeop (Ty regtype:$Rt), 2647 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 2648 ro_Wextend32:$extend))]>, 2649 Sched<[WriteSTIdx, ReadAdrBase]> { 2650 let Inst{13} = 0b0; 2651 } 2652 2653 let AddedComplexity = 10 in 2654 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs), 2655 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend), 2656 [(storeop (Ty regtype:$Rt), 2657 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 2658 ro_Xextend32:$extend))]>, 2659 Sched<[WriteSTIdx, ReadAdrBase]> { 2660 let Inst{13} = 0b1; 2661 } 2662 2663 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2664} 2665 2666class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2667 string asm, dag ins, dag outs, list<dag> pat> 2668 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2669 bits<5> Rt; 2670 bits<5> Rn; 2671 bits<5> Rm; 2672 bits<2> extend; 2673 let Inst{31-30} = sz; 2674 let Inst{29-27} = 0b111; 2675 let Inst{26} = V; 2676 let Inst{25-24} = 0b00; 2677 let Inst{23-22} = opc; 2678 let Inst{21} = 1; 2679 let Inst{20-16} = Rm; 2680 let Inst{15} = extend{1}; // sign extend Rm? 2681 let Inst{14} = 1; 2682 let Inst{12} = extend{0}; // do shift? 2683 let Inst{11-10} = 0b10; 2684 let Inst{9-5} = Rn; 2685 let Inst{4-0} = Rt; 2686} 2687 2688multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2689 string asm, ValueType Ty, SDPatternOperator loadop> { 2690 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2691 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2692 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2693 [(set (Ty regtype:$Rt), 2694 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2695 ro_Wextend64:$extend)))]>, 2696 Sched<[WriteLDIdx, ReadAdrBase]> { 2697 let Inst{13} = 0b0; 2698 } 2699 2700 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2701 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2702 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2703 [(set (Ty regtype:$Rt), 2704 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2705 ro_Xextend64:$extend)))]>, 2706 Sched<[WriteLDIdx, ReadAdrBase]> { 2707 let Inst{13} = 0b1; 2708 } 2709 2710 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2711} 2712 2713multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2714 string asm, ValueType Ty, SDPatternOperator storeop> { 2715 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2716 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 2717 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2718 [(storeop (Ty regtype:$Rt), 2719 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2720 ro_Wextend64:$extend))]>, 2721 Sched<[WriteSTIdx, ReadAdrBase]> { 2722 let Inst{13} = 0b0; 2723 } 2724 2725 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2726 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs), 2727 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2728 [(storeop (Ty regtype:$Rt), 2729 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2730 ro_Xextend64:$extend))]>, 2731 Sched<[WriteSTIdx, ReadAdrBase]> { 2732 let Inst{13} = 0b1; 2733 } 2734 2735 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2736} 2737 2738class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2739 string asm, dag ins, dag outs, list<dag> pat> 2740 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> { 2741 bits<5> Rt; 2742 bits<5> Rn; 2743 bits<5> Rm; 2744 bits<2> extend; 2745 let Inst{31-30} = sz; 2746 let Inst{29-27} = 0b111; 2747 let Inst{26} = V; 2748 let Inst{25-24} = 0b00; 2749 let Inst{23-22} = opc; 2750 let Inst{21} = 1; 2751 let Inst{20-16} = Rm; 2752 let Inst{15} = extend{1}; // sign extend Rm? 2753 let Inst{14} = 1; 2754 let Inst{12} = extend{0}; // do shift? 2755 let Inst{11-10} = 0b10; 2756 let Inst{9-5} = Rn; 2757 let Inst{4-0} = Rt; 2758} 2759 2760multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2761 string asm, ValueType Ty, SDPatternOperator loadop> { 2762 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2763 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2764 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 2765 [(set (Ty regtype:$Rt), 2766 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 2767 ro_Wextend128:$extend)))]>, 2768 Sched<[WriteLDIdx, ReadAdrBase]> { 2769 let Inst{13} = 0b0; 2770 } 2771 2772 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 2773 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt), 2774 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 2775 [(set (Ty regtype:$Rt), 2776 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 2777 ro_Xextend128:$extend)))]>, 2778 Sched<[WriteLDIdx, ReadAdrBase]> { 2779 let Inst{13} = 0b1; 2780 } 2781 2782 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2783} 2784 2785multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2786 string asm, ValueType Ty, SDPatternOperator storeop> { 2787 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2788 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 2789 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend), 2790 [(storeop (Ty regtype:$Rt), 2791 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm, 2792 ro_Wextend128:$extend))]>, 2793 Sched<[WriteSTIdx, ReadAdrBase]> { 2794 let Inst{13} = 0b0; 2795 } 2796 2797 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 2798 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs), 2799 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend), 2800 [(storeop (Ty regtype:$Rt), 2801 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm, 2802 ro_Xextend128:$extend))]>, 2803 Sched<[WriteSTIdx, ReadAdrBase]> { 2804 let Inst{13} = 0b1; 2805 } 2806 2807 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>; 2808} 2809 2810let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2811class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins, 2812 string asm, list<dag> pat> 2813 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>, 2814 Sched<[WriteLD]> { 2815 bits<5> Rt; 2816 bits<5> Rn; 2817 bits<5> Rm; 2818 bits<2> extend; 2819 let Inst{31-30} = sz; 2820 let Inst{29-27} = 0b111; 2821 let Inst{26} = V; 2822 let Inst{25-24} = 0b00; 2823 let Inst{23-22} = opc; 2824 let Inst{21} = 1; 2825 let Inst{20-16} = Rm; 2826 let Inst{15} = extend{1}; // sign extend Rm? 2827 let Inst{14} = 1; 2828 let Inst{12} = extend{0}; // do shift? 2829 let Inst{11-10} = 0b10; 2830 let Inst{9-5} = Rn; 2831 let Inst{4-0} = Rt; 2832} 2833 2834multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> { 2835 def roW : BasePrefetchRO<sz, V, opc, (outs), 2836 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend), 2837 asm, [(AArch64Prefetch imm:$Rt, 2838 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 2839 ro_Wextend64:$extend))]> { 2840 let Inst{13} = 0b0; 2841 } 2842 2843 def roX : BasePrefetchRO<sz, V, opc, (outs), 2844 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend), 2845 asm, [(AArch64Prefetch imm:$Rt, 2846 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 2847 ro_Xextend64:$extend))]> { 2848 let Inst{13} = 0b1; 2849 } 2850 2851 def : InstAlias<"prfm $Rt, [$Rn, $Rm]", 2852 (!cast<Instruction>(NAME # "roX") prfop:$Rt, 2853 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>; 2854} 2855 2856//--- 2857// Load/store unscaled immediate 2858//--- 2859 2860def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>; 2861def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>; 2862def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>; 2863def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>; 2864def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>; 2865 2866class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2867 string asm, list<dag> pattern> 2868 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> { 2869 bits<5> Rt; 2870 bits<5> Rn; 2871 bits<9> offset; 2872 let Inst{31-30} = sz; 2873 let Inst{29-27} = 0b111; 2874 let Inst{26} = V; 2875 let Inst{25-24} = 0b00; 2876 let Inst{23-22} = opc; 2877 let Inst{21} = 0; 2878 let Inst{20-12} = offset; 2879 let Inst{11-10} = 0b00; 2880 let Inst{9-5} = Rn; 2881 let Inst{4-0} = Rt; 2882 2883 let DecoderMethod = "DecodeSignedLdStInstruction"; 2884} 2885 2886multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2887 string asm, list<dag> pattern> { 2888 let AddedComplexity = 1 in // try this before LoadUI 2889 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt), 2890 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>, 2891 Sched<[WriteLD]>; 2892 2893 def : InstAlias<asm # " $Rt, [$Rn]", 2894 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 2895} 2896 2897multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2898 string asm, list<dag> pattern> { 2899 let AddedComplexity = 1 in // try this before StoreUI 2900 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 2901 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 2902 asm, pattern>, 2903 Sched<[WriteST]>; 2904 2905 def : InstAlias<asm # " $Rt, [$Rn]", 2906 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 2907} 2908 2909multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, 2910 list<dag> pat> { 2911 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 2912 def i : BaseLoadStoreUnscale<sz, V, opc, (outs), 2913 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset), 2914 asm, pat>, 2915 Sched<[WriteLD]>; 2916 2917 def : InstAlias<asm # " $Rt, [$Rn]", 2918 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>; 2919} 2920 2921//--- 2922// Load/store unscaled immediate, unprivileged 2923//--- 2924 2925class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 2926 dag oops, dag iops, string asm> 2927 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> { 2928 bits<5> Rt; 2929 bits<5> Rn; 2930 bits<9> offset; 2931 let Inst{31-30} = sz; 2932 let Inst{29-27} = 0b111; 2933 let Inst{26} = V; 2934 let Inst{25-24} = 0b00; 2935 let Inst{23-22} = opc; 2936 let Inst{21} = 0; 2937 let Inst{20-12} = offset; 2938 let Inst{11-10} = 0b10; 2939 let Inst{9-5} = Rn; 2940 let Inst{4-0} = Rt; 2941 2942 let DecoderMethod = "DecodeSignedLdStInstruction"; 2943} 2944 2945multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, 2946 RegisterClass regtype, string asm> { 2947 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in 2948 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt), 2949 (ins GPR64sp:$Rn, simm9:$offset), asm>, 2950 Sched<[WriteLD]>; 2951 2952 def : InstAlias<asm # " $Rt, [$Rn]", 2953 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 2954} 2955 2956multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, 2957 RegisterClass regtype, string asm> { 2958 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in 2959 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs), 2960 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 2961 asm>, 2962 Sched<[WriteST]>; 2963 2964 def : InstAlias<asm # " $Rt, [$Rn]", 2965 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>; 2966} 2967 2968//--- 2969// Load/store pre-indexed 2970//--- 2971 2972class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 2973 string asm, string cstr, list<dag> pat> 2974 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> { 2975 bits<5> Rt; 2976 bits<5> Rn; 2977 bits<9> offset; 2978 let Inst{31-30} = sz; 2979 let Inst{29-27} = 0b111; 2980 let Inst{26} = V; 2981 let Inst{25-24} = 0; 2982 let Inst{23-22} = opc; 2983 let Inst{21} = 0; 2984 let Inst{20-12} = offset; 2985 let Inst{11-10} = 0b11; 2986 let Inst{9-5} = Rn; 2987 let Inst{4-0} = Rt; 2988 2989 let DecoderMethod = "DecodeSignedLdStInstruction"; 2990} 2991 2992let hasSideEffects = 0 in { 2993let mayStore = 0, mayLoad = 1 in 2994class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 2995 string asm> 2996 : BaseLoadStorePreIdx<sz, V, opc, 2997 (outs GPR64sp:$wback, regtype:$Rt), 2998 (ins GPR64sp:$Rn, simm9:$offset), asm, 2999 "$Rn = $wback,@earlyclobber $wback", []>, 3000 Sched<[WriteLD, WriteAdr]>; 3001 3002let mayStore = 1, mayLoad = 0 in 3003class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3004 string asm, SDPatternOperator storeop, ValueType Ty> 3005 : BaseLoadStorePreIdx<sz, V, opc, 3006 (outs GPR64sp:$wback), 3007 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3008 asm, "$Rn = $wback,@earlyclobber $wback", 3009 [(set GPR64sp:$wback, 3010 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3011 Sched<[WriteAdr, WriteST]>; 3012} // hasSideEffects = 0 3013 3014//--- 3015// Load/store post-indexed 3016//--- 3017 3018class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops, 3019 string asm, string cstr, list<dag> pat> 3020 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> { 3021 bits<5> Rt; 3022 bits<5> Rn; 3023 bits<9> offset; 3024 let Inst{31-30} = sz; 3025 let Inst{29-27} = 0b111; 3026 let Inst{26} = V; 3027 let Inst{25-24} = 0b00; 3028 let Inst{23-22} = opc; 3029 let Inst{21} = 0b0; 3030 let Inst{20-12} = offset; 3031 let Inst{11-10} = 0b01; 3032 let Inst{9-5} = Rn; 3033 let Inst{4-0} = Rt; 3034 3035 let DecoderMethod = "DecodeSignedLdStInstruction"; 3036} 3037 3038let hasSideEffects = 0 in { 3039let mayStore = 0, mayLoad = 1 in 3040class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3041 string asm> 3042 : BaseLoadStorePostIdx<sz, V, opc, 3043 (outs GPR64sp:$wback, regtype:$Rt), 3044 (ins GPR64sp:$Rn, simm9:$offset), 3045 asm, "$Rn = $wback,@earlyclobber $wback", []>, 3046 Sched<[WriteLD, WriteI]>; 3047 3048let mayStore = 1, mayLoad = 0 in 3049class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype, 3050 string asm, SDPatternOperator storeop, ValueType Ty> 3051 : BaseLoadStorePostIdx<sz, V, opc, 3052 (outs GPR64sp:$wback), 3053 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset), 3054 asm, "$Rn = $wback,@earlyclobber $wback", 3055 [(set GPR64sp:$wback, 3056 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>, 3057 Sched<[WriteAdr, WriteST, ReadAdrBase]>; 3058} // hasSideEffects = 0 3059 3060 3061//--- 3062// Load/store pair 3063//--- 3064 3065// (indexed, offset) 3066 3067class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops, 3068 string asm> 3069 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3070 bits<5> Rt; 3071 bits<5> Rt2; 3072 bits<5> Rn; 3073 bits<7> offset; 3074 let Inst{31-30} = opc; 3075 let Inst{29-27} = 0b101; 3076 let Inst{26} = V; 3077 let Inst{25-23} = 0b010; 3078 let Inst{22} = L; 3079 let Inst{21-15} = offset; 3080 let Inst{14-10} = Rt2; 3081 let Inst{9-5} = Rn; 3082 let Inst{4-0} = Rt; 3083 3084 let DecoderMethod = "DecodePairLdStInstruction"; 3085} 3086 3087multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype, 3088 Operand indextype, string asm> { 3089 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3090 def i : BaseLoadStorePairOffset<opc, V, 1, 3091 (outs regtype:$Rt, regtype:$Rt2), 3092 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3093 Sched<[WriteLD, WriteLDHi]>; 3094 3095 def : InstAlias<asm # " $Rt, $Rt2, [$Rn]", 3096 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3097 GPR64sp:$Rn, 0)>; 3098} 3099 3100 3101multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype, 3102 Operand indextype, string asm> { 3103 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 3104 def i : BaseLoadStorePairOffset<opc, V, 0, (outs), 3105 (ins regtype:$Rt, regtype:$Rt2, 3106 GPR64sp:$Rn, indextype:$offset), 3107 asm>, 3108 Sched<[WriteSTP]>; 3109 3110 def : InstAlias<asm # " $Rt, $Rt2, [$Rn]", 3111 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3112 GPR64sp:$Rn, 0)>; 3113} 3114 3115// (pre-indexed) 3116class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3117 string asm> 3118 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> { 3119 bits<5> Rt; 3120 bits<5> Rt2; 3121 bits<5> Rn; 3122 bits<7> offset; 3123 let Inst{31-30} = opc; 3124 let Inst{29-27} = 0b101; 3125 let Inst{26} = V; 3126 let Inst{25-23} = 0b011; 3127 let Inst{22} = L; 3128 let Inst{21-15} = offset; 3129 let Inst{14-10} = Rt2; 3130 let Inst{9-5} = Rn; 3131 let Inst{4-0} = Rt; 3132 3133 let DecoderMethod = "DecodePairLdStInstruction"; 3134} 3135 3136let hasSideEffects = 0 in { 3137let mayStore = 0, mayLoad = 1 in 3138class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype, 3139 Operand indextype, string asm> 3140 : BaseLoadStorePairPreIdx<opc, V, 1, 3141 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3142 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3143 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3144 3145let mayStore = 1, mayLoad = 0 in 3146class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype, 3147 Operand indextype, string asm> 3148 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback), 3149 (ins regtype:$Rt, regtype:$Rt2, 3150 GPR64sp:$Rn, indextype:$offset), 3151 asm>, 3152 Sched<[WriteAdr, WriteSTP]>; 3153} // hasSideEffects = 0 3154 3155// (post-indexed) 3156 3157class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops, 3158 string asm> 3159 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> { 3160 bits<5> Rt; 3161 bits<5> Rt2; 3162 bits<5> Rn; 3163 bits<7> offset; 3164 let Inst{31-30} = opc; 3165 let Inst{29-27} = 0b101; 3166 let Inst{26} = V; 3167 let Inst{25-23} = 0b001; 3168 let Inst{22} = L; 3169 let Inst{21-15} = offset; 3170 let Inst{14-10} = Rt2; 3171 let Inst{9-5} = Rn; 3172 let Inst{4-0} = Rt; 3173 3174 let DecoderMethod = "DecodePairLdStInstruction"; 3175} 3176 3177let hasSideEffects = 0 in { 3178let mayStore = 0, mayLoad = 1 in 3179class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype, 3180 Operand idxtype, string asm> 3181 : BaseLoadStorePairPostIdx<opc, V, 1, 3182 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2), 3183 (ins GPR64sp:$Rn, idxtype:$offset), asm>, 3184 Sched<[WriteLD, WriteLDHi, WriteAdr]>; 3185 3186let mayStore = 1, mayLoad = 0 in 3187class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype, 3188 Operand idxtype, string asm> 3189 : BaseLoadStorePairPostIdx<opc, V, 0, (outs), 3190 (ins GPR64sp:$wback, regtype:$Rt, regtype:$Rt2, 3191 GPR64sp:$Rn, idxtype:$offset), 3192 asm>, 3193 Sched<[WriteAdr, WriteSTP]>; 3194} // hasSideEffects = 0 3195 3196// (no-allocate) 3197 3198class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops, 3199 string asm> 3200 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> { 3201 bits<5> Rt; 3202 bits<5> Rt2; 3203 bits<5> Rn; 3204 bits<7> offset; 3205 let Inst{31-30} = opc; 3206 let Inst{29-27} = 0b101; 3207 let Inst{26} = V; 3208 let Inst{25-23} = 0b000; 3209 let Inst{22} = L; 3210 let Inst{21-15} = offset; 3211 let Inst{14-10} = Rt2; 3212 let Inst{9-5} = Rn; 3213 let Inst{4-0} = Rt; 3214 3215 let DecoderMethod = "DecodePairLdStInstruction"; 3216} 3217 3218multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3219 Operand indextype, string asm> { 3220 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in 3221 def i : BaseLoadStorePairNoAlloc<opc, V, 1, 3222 (outs regtype:$Rt, regtype:$Rt2), 3223 (ins GPR64sp:$Rn, indextype:$offset), asm>, 3224 Sched<[WriteLD, WriteLDHi]>; 3225 3226 3227 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3228 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3229 GPR64sp:$Rn, 0)>; 3230} 3231 3232multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype, 3233 Operand indextype, string asm> { 3234 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in 3235 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs), 3236 (ins regtype:$Rt, regtype:$Rt2, 3237 GPR64sp:$Rn, indextype:$offset), 3238 asm>, 3239 Sched<[WriteSTP]>; 3240 3241 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]", 3242 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2, 3243 GPR64sp:$Rn, 0)>; 3244} 3245 3246//--- 3247// Load/store exclusive 3248//--- 3249 3250// True exclusive operations write to and/or read from the system's exclusive 3251// monitors, which as far as a compiler is concerned can be modelled as a 3252// random shared memory address. Hence LoadExclusive mayStore. 3253// 3254// Since these instructions have the undefined register bits set to 1 in 3255// their canonical form, we need a post encoder method to set those bits 3256// to 1 when encoding these instructions. We do this using the 3257// fixLoadStoreExclusive function. This function has template parameters: 3258// 3259// fixLoadStoreExclusive<int hasRs, int hasRt2> 3260// 3261// hasRs indicates that the instruction uses the Rs field, so we won't set 3262// it to 1 (and the same for Rt2). We don't need template parameters for 3263// the other register fields since Rt and Rn are always used. 3264// 3265let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in 3266class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3267 dag oops, dag iops, string asm, string operands> 3268 : I<oops, iops, asm, operands, "", []> { 3269 let Inst{31-30} = sz; 3270 let Inst{29-24} = 0b001000; 3271 let Inst{23} = o2; 3272 let Inst{22} = L; 3273 let Inst{21} = o1; 3274 let Inst{15} = o0; 3275 3276 let DecoderMethod = "DecodeExclusiveLdStInstruction"; 3277} 3278 3279// Neither Rs nor Rt2 operands. 3280class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3281 dag oops, dag iops, string asm, string operands> 3282 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> { 3283 bits<5> Rt; 3284 bits<5> Rn; 3285 let Inst{9-5} = Rn; 3286 let Inst{4-0} = Rt; 3287 3288 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>"; 3289} 3290 3291// Simple load acquires don't set the exclusive monitor 3292let mayLoad = 1, mayStore = 0 in 3293class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3294 RegisterClass regtype, string asm> 3295 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 3296 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 3297 Sched<[WriteLD]>; 3298 3299class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3300 RegisterClass regtype, string asm> 3301 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt), 3302 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">, 3303 Sched<[WriteLD]>; 3304 3305class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3306 RegisterClass regtype, string asm> 3307 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 3308 (outs regtype:$Rt, regtype:$Rt2), 3309 (ins GPR64sp0:$Rn), asm, 3310 "\t$Rt, $Rt2, [$Rn]">, 3311 Sched<[WriteLD, WriteLDHi]> { 3312 bits<5> Rt; 3313 bits<5> Rt2; 3314 bits<5> Rn; 3315 let Inst{14-10} = Rt2; 3316 let Inst{9-5} = Rn; 3317 let Inst{4-0} = Rt; 3318 3319 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>"; 3320} 3321 3322// Simple store release operations do not check the exclusive monitor. 3323let mayLoad = 0, mayStore = 1 in 3324class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3325 RegisterClass regtype, string asm> 3326 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs), 3327 (ins regtype:$Rt, GPR64sp0:$Rn), 3328 asm, "\t$Rt, [$Rn]">, 3329 Sched<[WriteST]>; 3330 3331let mayLoad = 1, mayStore = 1 in 3332class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3333 RegisterClass regtype, string asm> 3334 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws), 3335 (ins regtype:$Rt, GPR64sp0:$Rn), 3336 asm, "\t$Ws, $Rt, [$Rn]">, 3337 Sched<[WriteSTX]> { 3338 bits<5> Ws; 3339 bits<5> Rt; 3340 bits<5> Rn; 3341 let Inst{20-16} = Ws; 3342 let Inst{9-5} = Rn; 3343 let Inst{4-0} = Rt; 3344 3345 let Constraints = "@earlyclobber $Ws"; 3346 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; 3347} 3348 3349class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0, 3350 RegisterClass regtype, string asm> 3351 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, 3352 (outs GPR32:$Ws), 3353 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn), 3354 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">, 3355 Sched<[WriteSTX]> { 3356 bits<5> Ws; 3357 bits<5> Rt; 3358 bits<5> Rt2; 3359 bits<5> Rn; 3360 let Inst{20-16} = Ws; 3361 let Inst{14-10} = Rt2; 3362 let Inst{9-5} = Rn; 3363 let Inst{4-0} = Rt; 3364 3365 let Constraints = "@earlyclobber $Ws"; 3366} 3367 3368//--- 3369// Exception generation 3370//--- 3371 3372let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in 3373class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> 3374 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>, 3375 Sched<[WriteSys]> { 3376 bits<16> imm; 3377 let Inst{31-24} = 0b11010100; 3378 let Inst{23-21} = op1; 3379 let Inst{20-5} = imm; 3380 let Inst{4-2} = 0b000; 3381 let Inst{1-0} = ll; 3382} 3383 3384let Predicates = [HasFPARMv8] in { 3385 3386//--- 3387// Floating point to integer conversion 3388//--- 3389 3390class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode, 3391 RegisterClass srcType, RegisterClass dstType, 3392 string asm, list<dag> pattern> 3393 : I<(outs dstType:$Rd), (ins srcType:$Rn), 3394 asm, "\t$Rd, $Rn", "", pattern>, 3395 Sched<[WriteFCvt]> { 3396 bits<5> Rd; 3397 bits<5> Rn; 3398 let Inst{30-29} = 0b00; 3399 let Inst{28-24} = 0b11110; 3400 let Inst{23-22} = type; 3401 let Inst{21} = 1; 3402 let Inst{20-19} = rmode; 3403 let Inst{18-16} = opcode; 3404 let Inst{15-10} = 0; 3405 let Inst{9-5} = Rn; 3406 let Inst{4-0} = Rd; 3407} 3408 3409let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3410class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode, 3411 RegisterClass srcType, RegisterClass dstType, 3412 Operand immType, string asm, list<dag> pattern> 3413 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 3414 asm, "\t$Rd, $Rn, $scale", "", pattern>, 3415 Sched<[WriteFCvt]> { 3416 bits<5> Rd; 3417 bits<5> Rn; 3418 bits<6> scale; 3419 let Inst{30-29} = 0b00; 3420 let Inst{28-24} = 0b11110; 3421 let Inst{23-22} = type; 3422 let Inst{21} = 0; 3423 let Inst{20-19} = rmode; 3424 let Inst{18-16} = opcode; 3425 let Inst{15-10} = scale; 3426 let Inst{9-5} = Rn; 3427 let Inst{4-0} = Rd; 3428} 3429 3430multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm, 3431 SDPatternOperator OpN> { 3432 // Unscaled single-precision to 32-bit 3433 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm, 3434 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> { 3435 let Inst{31} = 0; // 32-bit GPR flag 3436 } 3437 3438 // Unscaled single-precision to 64-bit 3439 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm, 3440 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> { 3441 let Inst{31} = 1; // 64-bit GPR flag 3442 } 3443 3444 // Unscaled double-precision to 32-bit 3445 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm, 3446 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> { 3447 let Inst{31} = 0; // 32-bit GPR flag 3448 } 3449 3450 // Unscaled double-precision to 64-bit 3451 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm, 3452 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> { 3453 let Inst{31} = 1; // 64-bit GPR flag 3454 } 3455} 3456 3457multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm, 3458 SDPatternOperator OpN> { 3459 // Scaled single-precision to 32-bit 3460 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32, 3461 fixedpoint_f32_i32, asm, 3462 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn, 3463 fixedpoint_f32_i32:$scale)))]> { 3464 let Inst{31} = 0; // 32-bit GPR flag 3465 let scale{5} = 1; 3466 } 3467 3468 // Scaled single-precision to 64-bit 3469 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64, 3470 fixedpoint_f32_i64, asm, 3471 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn, 3472 fixedpoint_f32_i64:$scale)))]> { 3473 let Inst{31} = 1; // 64-bit GPR flag 3474 } 3475 3476 // Scaled double-precision to 32-bit 3477 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32, 3478 fixedpoint_f64_i32, asm, 3479 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn, 3480 fixedpoint_f64_i32:$scale)))]> { 3481 let Inst{31} = 0; // 32-bit GPR flag 3482 let scale{5} = 1; 3483 } 3484 3485 // Scaled double-precision to 64-bit 3486 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64, 3487 fixedpoint_f64_i64, asm, 3488 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn, 3489 fixedpoint_f64_i64:$scale)))]> { 3490 let Inst{31} = 1; // 64-bit GPR flag 3491 } 3492} 3493 3494//--- 3495// Integer to floating point conversion 3496//--- 3497 3498let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 3499class BaseIntegerToFP<bit isUnsigned, 3500 RegisterClass srcType, RegisterClass dstType, 3501 Operand immType, string asm, list<dag> pattern> 3502 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale), 3503 asm, "\t$Rd, $Rn, $scale", "", pattern>, 3504 Sched<[WriteFCvt]> { 3505 bits<5> Rd; 3506 bits<5> Rn; 3507 bits<6> scale; 3508 let Inst{30-23} = 0b00111100; 3509 let Inst{21-17} = 0b00001; 3510 let Inst{16} = isUnsigned; 3511 let Inst{15-10} = scale; 3512 let Inst{9-5} = Rn; 3513 let Inst{4-0} = Rd; 3514} 3515 3516class BaseIntegerToFPUnscaled<bit isUnsigned, 3517 RegisterClass srcType, RegisterClass dstType, 3518 ValueType dvt, string asm, SDNode node> 3519 : I<(outs dstType:$Rd), (ins srcType:$Rn), 3520 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>, 3521 Sched<[WriteFCvt]> { 3522 bits<5> Rd; 3523 bits<5> Rn; 3524 bits<6> scale; 3525 let Inst{30-23} = 0b00111100; 3526 let Inst{21-17} = 0b10001; 3527 let Inst{16} = isUnsigned; 3528 let Inst{15-10} = 0b000000; 3529 let Inst{9-5} = Rn; 3530 let Inst{4-0} = Rd; 3531} 3532 3533multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> { 3534 // Unscaled 3535 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> { 3536 let Inst{31} = 0; // 32-bit GPR flag 3537 let Inst{22} = 0; // 32-bit FPR flag 3538 } 3539 3540 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> { 3541 let Inst{31} = 0; // 32-bit GPR flag 3542 let Inst{22} = 1; // 64-bit FPR flag 3543 } 3544 3545 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> { 3546 let Inst{31} = 1; // 64-bit GPR flag 3547 let Inst{22} = 0; // 32-bit FPR flag 3548 } 3549 3550 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> { 3551 let Inst{31} = 1; // 64-bit GPR flag 3552 let Inst{22} = 1; // 64-bit FPR flag 3553 } 3554 3555 // Scaled 3556 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm, 3557 [(set FPR32:$Rd, 3558 (fdiv (node GPR32:$Rn), 3559 fixedpoint_f32_i32:$scale))]> { 3560 let Inst{31} = 0; // 32-bit GPR flag 3561 let Inst{22} = 0; // 32-bit FPR flag 3562 let scale{5} = 1; 3563 } 3564 3565 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm, 3566 [(set FPR64:$Rd, 3567 (fdiv (node GPR32:$Rn), 3568 fixedpoint_f64_i32:$scale))]> { 3569 let Inst{31} = 0; // 32-bit GPR flag 3570 let Inst{22} = 1; // 64-bit FPR flag 3571 let scale{5} = 1; 3572 } 3573 3574 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm, 3575 [(set FPR32:$Rd, 3576 (fdiv (node GPR64:$Rn), 3577 fixedpoint_f32_i64:$scale))]> { 3578 let Inst{31} = 1; // 64-bit GPR flag 3579 let Inst{22} = 0; // 32-bit FPR flag 3580 } 3581 3582 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm, 3583 [(set FPR64:$Rd, 3584 (fdiv (node GPR64:$Rn), 3585 fixedpoint_f64_i64:$scale))]> { 3586 let Inst{31} = 1; // 64-bit GPR flag 3587 let Inst{22} = 1; // 64-bit FPR flag 3588 } 3589} 3590 3591//--- 3592// Unscaled integer <-> floating point conversion (i.e. FMOV) 3593//--- 3594 3595let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3596class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode, 3597 RegisterClass srcType, RegisterClass dstType, 3598 string asm> 3599 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", 3600 // We use COPY_TO_REGCLASS for these bitconvert operations. 3601 // copyPhysReg() expands the resultant COPY instructions after 3602 // regalloc is done. This gives greater freedom for the allocator 3603 // and related passes (coalescing, copy propagation, et. al.) to 3604 // be more effective. 3605 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>, 3606 Sched<[WriteFCopy]> { 3607 bits<5> Rd; 3608 bits<5> Rn; 3609 let Inst{30-23} = 0b00111100; 3610 let Inst{21} = 1; 3611 let Inst{20-19} = rmode; 3612 let Inst{18-16} = opcode; 3613 let Inst{15-10} = 0b000000; 3614 let Inst{9-5} = Rn; 3615 let Inst{4-0} = Rd; 3616} 3617 3618let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3619class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode, 3620 RegisterClass srcType, RegisterOperand dstType, string asm, 3621 string kind> 3622 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 3623 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>, 3624 Sched<[WriteFCopy]> { 3625 bits<5> Rd; 3626 bits<5> Rn; 3627 let Inst{30-23} = 0b00111101; 3628 let Inst{21} = 1; 3629 let Inst{20-19} = rmode; 3630 let Inst{18-16} = opcode; 3631 let Inst{15-10} = 0b000000; 3632 let Inst{9-5} = Rn; 3633 let Inst{4-0} = Rd; 3634 3635 let DecoderMethod = "DecodeFMOVLaneInstruction"; 3636} 3637 3638let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3639class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode, 3640 RegisterOperand srcType, RegisterClass dstType, string asm, 3641 string kind> 3642 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm, 3643 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>, 3644 Sched<[WriteFCopy]> { 3645 bits<5> Rd; 3646 bits<5> Rn; 3647 let Inst{30-23} = 0b00111101; 3648 let Inst{21} = 1; 3649 let Inst{20-19} = rmode; 3650 let Inst{18-16} = opcode; 3651 let Inst{15-10} = 0b000000; 3652 let Inst{9-5} = Rn; 3653 let Inst{4-0} = Rd; 3654 3655 let DecoderMethod = "DecodeFMOVLaneInstruction"; 3656} 3657 3658 3659 3660multiclass UnscaledConversion<string asm> { 3661 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> { 3662 let Inst{31} = 0; // 32-bit GPR flag 3663 let Inst{22} = 0; // 32-bit FPR flag 3664 } 3665 3666 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> { 3667 let Inst{31} = 1; // 64-bit GPR flag 3668 let Inst{22} = 1; // 64-bit FPR flag 3669 } 3670 3671 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> { 3672 let Inst{31} = 0; // 32-bit GPR flag 3673 let Inst{22} = 0; // 32-bit FPR flag 3674 } 3675 3676 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> { 3677 let Inst{31} = 1; // 64-bit GPR flag 3678 let Inst{22} = 1; // 64-bit FPR flag 3679 } 3680 3681 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128, 3682 asm, ".d"> { 3683 let Inst{31} = 1; 3684 let Inst{22} = 0; 3685 } 3686 3687 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64, 3688 asm, ".d"> { 3689 let Inst{31} = 1; 3690 let Inst{22} = 0; 3691 } 3692} 3693 3694//--- 3695// Floating point conversion 3696//--- 3697 3698class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType, 3699 RegisterClass srcType, string asm, list<dag> pattern> 3700 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>, 3701 Sched<[WriteFCvt]> { 3702 bits<5> Rd; 3703 bits<5> Rn; 3704 let Inst{31-24} = 0b00011110; 3705 let Inst{23-22} = type; 3706 let Inst{21-17} = 0b10001; 3707 let Inst{16-15} = opcode; 3708 let Inst{14-10} = 0b10000; 3709 let Inst{9-5} = Rn; 3710 let Inst{4-0} = Rd; 3711} 3712 3713multiclass FPConversion<string asm> { 3714 // Double-precision to Half-precision 3715 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, 3716 [(set FPR16:$Rd, (fround FPR64:$Rn))]>; 3717 3718 // Double-precision to Single-precision 3719 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm, 3720 [(set FPR32:$Rd, (fround FPR64:$Rn))]>; 3721 3722 // Half-precision to Double-precision 3723 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, 3724 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>; 3725 3726 // Half-precision to Single-precision 3727 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, 3728 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>; 3729 3730 // Single-precision to Double-precision 3731 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm, 3732 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>; 3733 3734 // Single-precision to Half-precision 3735 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, 3736 [(set FPR16:$Rd, (fround FPR32:$Rn))]>; 3737} 3738 3739//--- 3740// Single operand floating point data processing 3741//--- 3742 3743let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3744class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype, 3745 ValueType vt, string asm, SDPatternOperator node> 3746 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "", 3747 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>, 3748 Sched<[WriteF]> { 3749 bits<5> Rd; 3750 bits<5> Rn; 3751 let Inst{31-23} = 0b000111100; 3752 let Inst{21-19} = 0b100; 3753 let Inst{18-15} = opcode; 3754 let Inst{14-10} = 0b10000; 3755 let Inst{9-5} = Rn; 3756 let Inst{4-0} = Rd; 3757} 3758 3759multiclass SingleOperandFPData<bits<4> opcode, string asm, 3760 SDPatternOperator node = null_frag> { 3761 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> { 3762 let Inst{22} = 0; // 32-bit size flag 3763 } 3764 3765 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> { 3766 let Inst{22} = 1; // 64-bit size flag 3767 } 3768} 3769 3770//--- 3771// Two operand floating point data processing 3772//--- 3773 3774let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3775class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype, 3776 string asm, list<dag> pat> 3777 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), 3778 asm, "\t$Rd, $Rn, $Rm", "", pat>, 3779 Sched<[WriteF]> { 3780 bits<5> Rd; 3781 bits<5> Rn; 3782 bits<5> Rm; 3783 let Inst{31-23} = 0b000111100; 3784 let Inst{21} = 1; 3785 let Inst{20-16} = Rm; 3786 let Inst{15-12} = opcode; 3787 let Inst{11-10} = 0b10; 3788 let Inst{9-5} = Rn; 3789 let Inst{4-0} = Rd; 3790} 3791 3792multiclass TwoOperandFPData<bits<4> opcode, string asm, 3793 SDPatternOperator node = null_frag> { 3794 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 3795 [(set (f32 FPR32:$Rd), 3796 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> { 3797 let Inst{22} = 0; // 32-bit size flag 3798 } 3799 3800 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 3801 [(set (f64 FPR64:$Rd), 3802 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> { 3803 let Inst{22} = 1; // 64-bit size flag 3804 } 3805} 3806 3807multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> { 3808 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm, 3809 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> { 3810 let Inst{22} = 0; // 32-bit size flag 3811 } 3812 3813 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm, 3814 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> { 3815 let Inst{22} = 1; // 64-bit size flag 3816 } 3817} 3818 3819 3820//--- 3821// Three operand floating point data processing 3822//--- 3823 3824class BaseThreeOperandFPData<bit isNegated, bit isSub, 3825 RegisterClass regtype, string asm, list<dag> pat> 3826 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra), 3827 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>, 3828 Sched<[WriteFMul]> { 3829 bits<5> Rd; 3830 bits<5> Rn; 3831 bits<5> Rm; 3832 bits<5> Ra; 3833 let Inst{31-23} = 0b000111110; 3834 let Inst{21} = isNegated; 3835 let Inst{20-16} = Rm; 3836 let Inst{15} = isSub; 3837 let Inst{14-10} = Ra; 3838 let Inst{9-5} = Rn; 3839 let Inst{4-0} = Rd; 3840} 3841 3842multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm, 3843 SDPatternOperator node> { 3844 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm, 3845 [(set FPR32:$Rd, 3846 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> { 3847 let Inst{22} = 0; // 32-bit size flag 3848 } 3849 3850 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm, 3851 [(set FPR64:$Rd, 3852 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> { 3853 let Inst{22} = 1; // 64-bit size flag 3854 } 3855} 3856 3857//--- 3858// Floating point data comparisons 3859//--- 3860 3861let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3862class BaseOneOperandFPComparison<bit signalAllNans, 3863 RegisterClass regtype, string asm, 3864 list<dag> pat> 3865 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>, 3866 Sched<[WriteFCmp]> { 3867 bits<5> Rn; 3868 let Inst{31-23} = 0b000111100; 3869 let Inst{21} = 1; 3870 3871 let Inst{15-10} = 0b001000; 3872 let Inst{9-5} = Rn; 3873 let Inst{4} = signalAllNans; 3874 let Inst{3-0} = 0b1000; 3875 3876 // Rm should be 0b00000 canonically, but we need to accept any value. 3877 let PostEncoderMethod = "fixOneOperandFPComparison"; 3878} 3879 3880let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3881class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype, 3882 string asm, list<dag> pat> 3883 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>, 3884 Sched<[WriteFCmp]> { 3885 bits<5> Rm; 3886 bits<5> Rn; 3887 let Inst{31-23} = 0b000111100; 3888 let Inst{21} = 1; 3889 let Inst{20-16} = Rm; 3890 let Inst{15-10} = 0b001000; 3891 let Inst{9-5} = Rn; 3892 let Inst{4} = signalAllNans; 3893 let Inst{3-0} = 0b0000; 3894} 3895 3896multiclass FPComparison<bit signalAllNans, string asm, 3897 SDPatternOperator OpNode = null_frag> { 3898 let Defs = [NZCV] in { 3899 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm, 3900 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { 3901 let Inst{22} = 0; 3902 } 3903 3904 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm, 3905 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { 3906 let Inst{22} = 0; 3907 } 3908 3909 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm, 3910 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { 3911 let Inst{22} = 1; 3912 } 3913 3914 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm, 3915 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { 3916 let Inst{22} = 1; 3917 } 3918 } // Defs = [NZCV] 3919} 3920 3921//--- 3922// Floating point conditional comparisons 3923//--- 3924 3925let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 3926class BaseFPCondComparison<bit signalAllNans, 3927 RegisterClass regtype, string asm> 3928 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond), 3929 asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>, 3930 Sched<[WriteFCmp]> { 3931 bits<5> Rn; 3932 bits<5> Rm; 3933 bits<4> nzcv; 3934 bits<4> cond; 3935 3936 let Inst{31-23} = 0b000111100; 3937 let Inst{21} = 1; 3938 let Inst{20-16} = Rm; 3939 let Inst{15-12} = cond; 3940 let Inst{11-10} = 0b01; 3941 let Inst{9-5} = Rn; 3942 let Inst{4} = signalAllNans; 3943 let Inst{3-0} = nzcv; 3944} 3945 3946multiclass FPCondComparison<bit signalAllNans, string asm> { 3947 let Defs = [NZCV], Uses = [NZCV] in { 3948 def Srr : BaseFPCondComparison<signalAllNans, FPR32, asm> { 3949 let Inst{22} = 0; 3950 } 3951 3952 def Drr : BaseFPCondComparison<signalAllNans, FPR64, asm> { 3953 let Inst{22} = 1; 3954 } 3955 } // Defs = [NZCV], Uses = [NZCV] 3956} 3957 3958//--- 3959// Floating point conditional select 3960//--- 3961 3962class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm> 3963 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), 3964 asm, "\t$Rd, $Rn, $Rm, $cond", "", 3965 [(set regtype:$Rd, 3966 (AArch64csel (vt regtype:$Rn), regtype:$Rm, 3967 (i32 imm:$cond), NZCV))]>, 3968 Sched<[WriteF]> { 3969 bits<5> Rd; 3970 bits<5> Rn; 3971 bits<5> Rm; 3972 bits<4> cond; 3973 3974 let Inst{31-23} = 0b000111100; 3975 let Inst{21} = 1; 3976 let Inst{20-16} = Rm; 3977 let Inst{15-12} = cond; 3978 let Inst{11-10} = 0b11; 3979 let Inst{9-5} = Rn; 3980 let Inst{4-0} = Rd; 3981} 3982 3983multiclass FPCondSelect<string asm> { 3984 let Uses = [NZCV] in { 3985 def Srrr : BaseFPCondSelect<FPR32, f32, asm> { 3986 let Inst{22} = 0; 3987 } 3988 3989 def Drrr : BaseFPCondSelect<FPR64, f64, asm> { 3990 let Inst{22} = 1; 3991 } 3992 } // Uses = [NZCV] 3993} 3994 3995//--- 3996// Floating move immediate 3997//--- 3998 3999class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm> 4000 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "", 4001 [(set regtype:$Rd, fpimmtype:$imm)]>, 4002 Sched<[WriteFImm]> { 4003 bits<5> Rd; 4004 bits<8> imm; 4005 let Inst{31-23} = 0b000111100; 4006 let Inst{21} = 1; 4007 let Inst{20-13} = imm; 4008 let Inst{12-5} = 0b10000000; 4009 let Inst{4-0} = Rd; 4010} 4011 4012multiclass FPMoveImmediate<string asm> { 4013 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> { 4014 let Inst{22} = 0; 4015 } 4016 4017 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> { 4018 let Inst{22} = 1; 4019 } 4020} 4021} // end of 'let Predicates = [HasFPARMv8]' 4022 4023//---------------------------------------------------------------------------- 4024// AdvSIMD 4025//---------------------------------------------------------------------------- 4026 4027let Predicates = [HasNEON] in { 4028 4029//---------------------------------------------------------------------------- 4030// AdvSIMD three register vector instructions 4031//---------------------------------------------------------------------------- 4032 4033let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4034class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4035 RegisterOperand regtype, string asm, string kind, 4036 list<dag> pattern> 4037 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 4038 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 4039 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>, 4040 Sched<[WriteV]> { 4041 bits<5> Rd; 4042 bits<5> Rn; 4043 bits<5> Rm; 4044 let Inst{31} = 0; 4045 let Inst{30} = Q; 4046 let Inst{29} = U; 4047 let Inst{28-24} = 0b01110; 4048 let Inst{23-22} = size; 4049 let Inst{21} = 1; 4050 let Inst{20-16} = Rm; 4051 let Inst{15-11} = opcode; 4052 let Inst{10} = 1; 4053 let Inst{9-5} = Rn; 4054 let Inst{4-0} = Rd; 4055} 4056 4057let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4058class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4059 RegisterOperand regtype, string asm, string kind, 4060 list<dag> pattern> 4061 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm, 4062 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 4063 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 4064 Sched<[WriteV]> { 4065 bits<5> Rd; 4066 bits<5> Rn; 4067 bits<5> Rm; 4068 let Inst{31} = 0; 4069 let Inst{30} = Q; 4070 let Inst{29} = U; 4071 let Inst{28-24} = 0b01110; 4072 let Inst{23-22} = size; 4073 let Inst{21} = 1; 4074 let Inst{20-16} = Rm; 4075 let Inst{15-11} = opcode; 4076 let Inst{10} = 1; 4077 let Inst{9-5} = Rn; 4078 let Inst{4-0} = Rd; 4079} 4080 4081// All operand sizes distinguished in the encoding. 4082multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm, 4083 SDPatternOperator OpNode> { 4084 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64, 4085 asm, ".8b", 4086 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4087 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128, 4088 asm, ".16b", 4089 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4090 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64, 4091 asm, ".4h", 4092 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4093 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128, 4094 asm, ".8h", 4095 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4096 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64, 4097 asm, ".2s", 4098 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4099 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128, 4100 asm, ".4s", 4101 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4102 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128, 4103 asm, ".2d", 4104 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 4105} 4106 4107// As above, but D sized elements unsupported. 4108multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm, 4109 SDPatternOperator OpNode> { 4110 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64, 4111 asm, ".8b", 4112 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>; 4113 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128, 4114 asm, ".16b", 4115 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>; 4116 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64, 4117 asm, ".4h", 4118 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>; 4119 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128, 4120 asm, ".8h", 4121 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>; 4122 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64, 4123 asm, ".2s", 4124 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>; 4125 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128, 4126 asm, ".4s", 4127 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>; 4128} 4129 4130multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm, 4131 SDPatternOperator OpNode> { 4132 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64, 4133 asm, ".8b", 4134 [(set (v8i8 V64:$dst), 4135 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4136 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128, 4137 asm, ".16b", 4138 [(set (v16i8 V128:$dst), 4139 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4140 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64, 4141 asm, ".4h", 4142 [(set (v4i16 V64:$dst), 4143 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4144 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128, 4145 asm, ".8h", 4146 [(set (v8i16 V128:$dst), 4147 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4148 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64, 4149 asm, ".2s", 4150 [(set (v2i32 V64:$dst), 4151 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4152 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128, 4153 asm, ".4s", 4154 [(set (v4i32 V128:$dst), 4155 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4156} 4157 4158// As above, but only B sized elements supported. 4159multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm, 4160 SDPatternOperator OpNode> { 4161 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64, 4162 asm, ".8b", 4163 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4164 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128, 4165 asm, ".16b", 4166 [(set (v16i8 V128:$Rd), 4167 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>; 4168} 4169 4170// As above, but only S and D sized floating point elements supported. 4171multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc, 4172 string asm, SDPatternOperator OpNode> { 4173 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64, 4174 asm, ".2s", 4175 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4176 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128, 4177 asm, ".4s", 4178 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4179 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128, 4180 asm, ".2d", 4181 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4182} 4183 4184multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc, 4185 string asm, 4186 SDPatternOperator OpNode> { 4187 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64, 4188 asm, ".2s", 4189 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4190 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128, 4191 asm, ".4s", 4192 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4193 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128, 4194 asm, ".2d", 4195 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4196} 4197 4198multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc, 4199 string asm, SDPatternOperator OpNode> { 4200 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64, 4201 asm, ".2s", 4202 [(set (v2f32 V64:$dst), 4203 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>; 4204 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128, 4205 asm, ".4s", 4206 [(set (v4f32 V128:$dst), 4207 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>; 4208 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128, 4209 asm, ".2d", 4210 [(set (v2f64 V128:$dst), 4211 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>; 4212} 4213 4214// As above, but D and B sized elements unsupported. 4215multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm, 4216 SDPatternOperator OpNode> { 4217 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64, 4218 asm, ".4h", 4219 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4220 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128, 4221 asm, ".8h", 4222 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4223 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64, 4224 asm, ".2s", 4225 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4226 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128, 4227 asm, ".4s", 4228 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4229} 4230 4231// Logical three vector ops share opcode bits, and only use B sized elements. 4232multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm, 4233 SDPatternOperator OpNode = null_frag> { 4234 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64, 4235 asm, ".8b", 4236 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>; 4237 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128, 4238 asm, ".16b", 4239 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>; 4240 4241 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)), 4242 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4243 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)), 4244 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4245 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)), 4246 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>; 4247 4248 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)), 4249 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4250 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)), 4251 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4252 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)), 4253 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>; 4254} 4255 4256multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size, 4257 string asm, SDPatternOperator OpNode> { 4258 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64, 4259 asm, ".8b", 4260 [(set (v8i8 V64:$dst), 4261 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4262 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128, 4263 asm, ".16b", 4264 [(set (v16i8 V128:$dst), 4265 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 4266 (v16i8 V128:$Rm)))]>; 4267 4268 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS), 4269 (v4i16 V64:$RHS))), 4270 (!cast<Instruction>(NAME#"v8i8") 4271 V64:$LHS, V64:$MHS, V64:$RHS)>; 4272 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS), 4273 (v2i32 V64:$RHS))), 4274 (!cast<Instruction>(NAME#"v8i8") 4275 V64:$LHS, V64:$MHS, V64:$RHS)>; 4276 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS), 4277 (v1i64 V64:$RHS))), 4278 (!cast<Instruction>(NAME#"v8i8") 4279 V64:$LHS, V64:$MHS, V64:$RHS)>; 4280 4281 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS), 4282 (v8i16 V128:$RHS))), 4283 (!cast<Instruction>(NAME#"v16i8") 4284 V128:$LHS, V128:$MHS, V128:$RHS)>; 4285 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS), 4286 (v4i32 V128:$RHS))), 4287 (!cast<Instruction>(NAME#"v16i8") 4288 V128:$LHS, V128:$MHS, V128:$RHS)>; 4289 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS), 4290 (v2i64 V128:$RHS))), 4291 (!cast<Instruction>(NAME#"v16i8") 4292 V128:$LHS, V128:$MHS, V128:$RHS)>; 4293} 4294 4295 4296//---------------------------------------------------------------------------- 4297// AdvSIMD two register vector instructions. 4298//---------------------------------------------------------------------------- 4299 4300let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4301class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4302 RegisterOperand regtype, string asm, string dstkind, 4303 string srckind, list<dag> pattern> 4304 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 4305 "{\t$Rd" # dstkind # ", $Rn" # srckind # 4306 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>, 4307 Sched<[WriteV]> { 4308 bits<5> Rd; 4309 bits<5> Rn; 4310 let Inst{31} = 0; 4311 let Inst{30} = Q; 4312 let Inst{29} = U; 4313 let Inst{28-24} = 0b01110; 4314 let Inst{23-22} = size; 4315 let Inst{21-17} = 0b10000; 4316 let Inst{16-12} = opcode; 4317 let Inst{11-10} = 0b10; 4318 let Inst{9-5} = Rn; 4319 let Inst{4-0} = Rd; 4320} 4321 4322let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4323class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4324 RegisterOperand regtype, string asm, string dstkind, 4325 string srckind, list<dag> pattern> 4326 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm, 4327 "{\t$Rd" # dstkind # ", $Rn" # srckind # 4328 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 4329 Sched<[WriteV]> { 4330 bits<5> Rd; 4331 bits<5> Rn; 4332 let Inst{31} = 0; 4333 let Inst{30} = Q; 4334 let Inst{29} = U; 4335 let Inst{28-24} = 0b01110; 4336 let Inst{23-22} = size; 4337 let Inst{21-17} = 0b10000; 4338 let Inst{16-12} = opcode; 4339 let Inst{11-10} = 0b10; 4340 let Inst{9-5} = Rn; 4341 let Inst{4-0} = Rd; 4342} 4343 4344// Supports B, H, and S element sizes. 4345multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm, 4346 SDPatternOperator OpNode> { 4347 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64, 4348 asm, ".8b", ".8b", 4349 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4350 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128, 4351 asm, ".16b", ".16b", 4352 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4353 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64, 4354 asm, ".4h", ".4h", 4355 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4356 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128, 4357 asm, ".8h", ".8h", 4358 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4359 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64, 4360 asm, ".2s", ".2s", 4361 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4362 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128, 4363 asm, ".4s", ".4s", 4364 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4365} 4366 4367class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size, 4368 RegisterOperand regtype, string asm, string dstkind, 4369 string srckind, string amount> 4370 : I<(outs V128:$Rd), (ins regtype:$Rn), asm, 4371 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount # 4372 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>, 4373 Sched<[WriteV]> { 4374 bits<5> Rd; 4375 bits<5> Rn; 4376 let Inst{31} = 0; 4377 let Inst{30} = Q; 4378 let Inst{29-24} = 0b101110; 4379 let Inst{23-22} = size; 4380 let Inst{21-10} = 0b100001001110; 4381 let Inst{9-5} = Rn; 4382 let Inst{4-0} = Rd; 4383} 4384 4385multiclass SIMDVectorLShiftLongBySizeBHS { 4386 let hasSideEffects = 0 in { 4387 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64, 4388 "shll", ".8h", ".8b", "8">; 4389 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128, 4390 "shll2", ".8h", ".16b", "8">; 4391 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64, 4392 "shll", ".4s", ".4h", "16">; 4393 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128, 4394 "shll2", ".4s", ".8h", "16">; 4395 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64, 4396 "shll", ".2d", ".2s", "32">; 4397 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128, 4398 "shll2", ".2d", ".4s", "32">; 4399 } 4400} 4401 4402// Supports all element sizes. 4403multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm, 4404 SDPatternOperator OpNode> { 4405 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64, 4406 asm, ".4h", ".8b", 4407 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4408 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128, 4409 asm, ".8h", ".16b", 4410 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4411 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64, 4412 asm, ".2s", ".4h", 4413 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4414 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128, 4415 asm, ".4s", ".8h", 4416 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4417 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64, 4418 asm, ".1d", ".2s", 4419 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4420 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128, 4421 asm, ".2d", ".4s", 4422 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4423} 4424 4425multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm, 4426 SDPatternOperator OpNode> { 4427 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64, 4428 asm, ".4h", ".8b", 4429 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), 4430 (v8i8 V64:$Rn)))]>; 4431 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128, 4432 asm, ".8h", ".16b", 4433 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), 4434 (v16i8 V128:$Rn)))]>; 4435 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64, 4436 asm, ".2s", ".4h", 4437 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), 4438 (v4i16 V64:$Rn)))]>; 4439 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128, 4440 asm, ".4s", ".8h", 4441 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), 4442 (v8i16 V128:$Rn)))]>; 4443 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64, 4444 asm, ".1d", ".2s", 4445 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd), 4446 (v2i32 V64:$Rn)))]>; 4447 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128, 4448 asm, ".2d", ".4s", 4449 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), 4450 (v4i32 V128:$Rn)))]>; 4451} 4452 4453// Supports all element sizes, except 1xD. 4454multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm, 4455 SDPatternOperator OpNode> { 4456 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64, 4457 asm, ".8b", ".8b", 4458 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>; 4459 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128, 4460 asm, ".16b", ".16b", 4461 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 4462 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64, 4463 asm, ".4h", ".4h", 4464 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>; 4465 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128, 4466 asm, ".8h", ".8h", 4467 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>; 4468 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64, 4469 asm, ".2s", ".2s", 4470 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>; 4471 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128, 4472 asm, ".4s", ".4s", 4473 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 4474 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128, 4475 asm, ".2d", ".2d", 4476 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>; 4477} 4478 4479multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm, 4480 SDPatternOperator OpNode = null_frag> { 4481 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64, 4482 asm, ".8b", ".8b", 4483 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4484 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128, 4485 asm, ".16b", ".16b", 4486 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4487 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64, 4488 asm, ".4h", ".4h", 4489 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>; 4490 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128, 4491 asm, ".8h", ".8h", 4492 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4493 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64, 4494 asm, ".2s", ".2s", 4495 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4496 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128, 4497 asm, ".4s", ".4s", 4498 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4499 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128, 4500 asm, ".2d", ".2d", 4501 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4502} 4503 4504 4505// Supports only B element sizes. 4506multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm, 4507 SDPatternOperator OpNode> { 4508 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64, 4509 asm, ".8b", ".8b", 4510 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>; 4511 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128, 4512 asm, ".16b", ".16b", 4513 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 4514 4515} 4516 4517// Supports only B and H element sizes. 4518multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm, 4519 SDPatternOperator OpNode> { 4520 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64, 4521 asm, ".8b", ".8b", 4522 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>; 4523 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128, 4524 asm, ".16b", ".16b", 4525 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>; 4526 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64, 4527 asm, ".4h", ".4h", 4528 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>; 4529 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128, 4530 asm, ".8h", ".8h", 4531 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>; 4532} 4533 4534// Supports only S and D element sizes, uses high bit of the size field 4535// as an extra opcode bit. 4536multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm, 4537 SDPatternOperator OpNode> { 4538 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64, 4539 asm, ".2s", ".2s", 4540 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 4541 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128, 4542 asm, ".4s", ".4s", 4543 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 4544 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128, 4545 asm, ".2d", ".2d", 4546 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4547} 4548 4549// Supports only S element size. 4550multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm, 4551 SDPatternOperator OpNode> { 4552 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64, 4553 asm, ".2s", ".2s", 4554 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4555 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128, 4556 asm, ".4s", ".4s", 4557 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4558} 4559 4560 4561multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm, 4562 SDPatternOperator OpNode> { 4563 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64, 4564 asm, ".2s", ".2s", 4565 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>; 4566 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128, 4567 asm, ".4s", ".4s", 4568 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>; 4569 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128, 4570 asm, ".2d", ".2d", 4571 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4572} 4573 4574multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm, 4575 SDPatternOperator OpNode> { 4576 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64, 4577 asm, ".2s", ".2s", 4578 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>; 4579 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128, 4580 asm, ".4s", ".4s", 4581 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4582 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128, 4583 asm, ".2d", ".2d", 4584 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4585} 4586 4587 4588class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4589 RegisterOperand inreg, RegisterOperand outreg, 4590 string asm, string outkind, string inkind, 4591 list<dag> pattern> 4592 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm, 4593 "{\t$Rd" # outkind # ", $Rn" # inkind # 4594 "|" # outkind # "\t$Rd, $Rn}", "", pattern>, 4595 Sched<[WriteV]> { 4596 bits<5> Rd; 4597 bits<5> Rn; 4598 let Inst{31} = 0; 4599 let Inst{30} = Q; 4600 let Inst{29} = U; 4601 let Inst{28-24} = 0b01110; 4602 let Inst{23-22} = size; 4603 let Inst{21-17} = 0b10000; 4604 let Inst{16-12} = opcode; 4605 let Inst{11-10} = 0b10; 4606 let Inst{9-5} = Rn; 4607 let Inst{4-0} = Rd; 4608} 4609 4610class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4611 RegisterOperand inreg, RegisterOperand outreg, 4612 string asm, string outkind, string inkind, 4613 list<dag> pattern> 4614 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm, 4615 "{\t$Rd" # outkind # ", $Rn" # inkind # 4616 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>, 4617 Sched<[WriteV]> { 4618 bits<5> Rd; 4619 bits<5> Rn; 4620 let Inst{31} = 0; 4621 let Inst{30} = Q; 4622 let Inst{29} = U; 4623 let Inst{28-24} = 0b01110; 4624 let Inst{23-22} = size; 4625 let Inst{21-17} = 0b10000; 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 4632multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm, 4633 SDPatternOperator OpNode> { 4634 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64, 4635 asm, ".8b", ".8h", 4636 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>; 4637 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128, 4638 asm#"2", ".16b", ".8h", []>; 4639 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64, 4640 asm, ".4h", ".4s", 4641 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>; 4642 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128, 4643 asm#"2", ".8h", ".4s", []>; 4644 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64, 4645 asm, ".2s", ".2d", 4646 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>; 4647 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128, 4648 asm#"2", ".4s", ".2d", []>; 4649 4650 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))), 4651 (!cast<Instruction>(NAME # "v16i8") 4652 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4653 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))), 4654 (!cast<Instruction>(NAME # "v8i16") 4655 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4656 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))), 4657 (!cast<Instruction>(NAME # "v4i32") 4658 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4659} 4660 4661class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4662 RegisterOperand regtype, 4663 string asm, string kind, string zero, 4664 ValueType dty, ValueType sty, SDNode OpNode> 4665 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 4666 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero # 4667 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "", 4668 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>, 4669 Sched<[WriteV]> { 4670 bits<5> Rd; 4671 bits<5> Rn; 4672 let Inst{31} = 0; 4673 let Inst{30} = Q; 4674 let Inst{29} = U; 4675 let Inst{28-24} = 0b01110; 4676 let Inst{23-22} = size; 4677 let Inst{21-17} = 0b10000; 4678 let Inst{16-12} = opcode; 4679 let Inst{11-10} = 0b10; 4680 let Inst{9-5} = Rn; 4681 let Inst{4-0} = Rd; 4682} 4683 4684// Comparisons support all element sizes, except 1xD. 4685multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm, 4686 SDNode OpNode> { 4687 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64, 4688 asm, ".8b", "0", 4689 v8i8, v8i8, OpNode>; 4690 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128, 4691 asm, ".16b", "0", 4692 v16i8, v16i8, OpNode>; 4693 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64, 4694 asm, ".4h", "0", 4695 v4i16, v4i16, OpNode>; 4696 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128, 4697 asm, ".8h", "0", 4698 v8i16, v8i16, OpNode>; 4699 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64, 4700 asm, ".2s", "0", 4701 v2i32, v2i32, OpNode>; 4702 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128, 4703 asm, ".4s", "0", 4704 v4i32, v4i32, OpNode>; 4705 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128, 4706 asm, ".2d", "0", 4707 v2i64, v2i64, OpNode>; 4708} 4709 4710// FP Comparisons support only S and D element sizes. 4711multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc, 4712 string asm, SDNode OpNode> { 4713 4714 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64, 4715 asm, ".2s", "0.0", 4716 v2i32, v2f32, OpNode>; 4717 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128, 4718 asm, ".4s", "0.0", 4719 v4i32, v4f32, OpNode>; 4720 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128, 4721 asm, ".2d", "0.0", 4722 v2i64, v2f64, OpNode>; 4723 4724 def : InstAlias<asm # " $Vd.2s, $Vn.2s, #0", 4725 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 4726 def : InstAlias<asm # " $Vd.4s, $Vn.4s, #0", 4727 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 4728 def : InstAlias<asm # " $Vd.2d, $Vn.2d, #0", 4729 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 4730 def : InstAlias<asm # ".2s $Vd, $Vn, #0", 4731 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>; 4732 def : InstAlias<asm # ".4s $Vd, $Vn, #0", 4733 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>; 4734 def : InstAlias<asm # ".2d $Vd, $Vn, #0", 4735 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>; 4736} 4737 4738let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4739class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode, 4740 RegisterOperand outtype, RegisterOperand intype, 4741 string asm, string VdTy, string VnTy, 4742 list<dag> pattern> 4743 : I<(outs outtype:$Rd), (ins intype:$Rn), asm, 4744 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>, 4745 Sched<[WriteV]> { 4746 bits<5> Rd; 4747 bits<5> Rn; 4748 let Inst{31} = 0; 4749 let Inst{30} = Q; 4750 let Inst{29} = U; 4751 let Inst{28-24} = 0b01110; 4752 let Inst{23-22} = size; 4753 let Inst{21-17} = 0b10000; 4754 let Inst{16-12} = opcode; 4755 let Inst{11-10} = 0b10; 4756 let Inst{9-5} = Rn; 4757 let Inst{4-0} = Rd; 4758} 4759 4760class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode, 4761 RegisterOperand outtype, RegisterOperand intype, 4762 string asm, string VdTy, string VnTy, 4763 list<dag> pattern> 4764 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm, 4765 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>, 4766 Sched<[WriteV]> { 4767 bits<5> Rd; 4768 bits<5> Rn; 4769 let Inst{31} = 0; 4770 let Inst{30} = Q; 4771 let Inst{29} = U; 4772 let Inst{28-24} = 0b01110; 4773 let Inst{23-22} = size; 4774 let Inst{21-17} = 0b10000; 4775 let Inst{16-12} = opcode; 4776 let Inst{11-10} = 0b10; 4777 let Inst{9-5} = Rn; 4778 let Inst{4-0} = Rd; 4779} 4780 4781multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> { 4782 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64, 4783 asm, ".4s", ".4h", []>; 4784 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128, 4785 asm#"2", ".4s", ".8h", []>; 4786 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64, 4787 asm, ".2d", ".2s", []>; 4788 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128, 4789 asm#"2", ".2d", ".4s", []>; 4790} 4791 4792multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> { 4793 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128, 4794 asm, ".4h", ".4s", []>; 4795 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128, 4796 asm#"2", ".8h", ".4s", []>; 4797 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 4798 asm, ".2s", ".2d", []>; 4799 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 4800 asm#"2", ".4s", ".2d", []>; 4801} 4802 4803multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm, 4804 Intrinsic OpNode> { 4805 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128, 4806 asm, ".2s", ".2d", 4807 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>; 4808 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128, 4809 asm#"2", ".4s", ".2d", []>; 4810 4811 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))), 4812 (!cast<Instruction>(NAME # "v4f32") 4813 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>; 4814} 4815 4816//---------------------------------------------------------------------------- 4817// AdvSIMD three register different-size vector instructions. 4818//---------------------------------------------------------------------------- 4819 4820let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4821class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode, 4822 RegisterOperand outtype, RegisterOperand intype1, 4823 RegisterOperand intype2, string asm, 4824 string outkind, string inkind1, string inkind2, 4825 list<dag> pattern> 4826 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm, 4827 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 4828 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>, 4829 Sched<[WriteV]> { 4830 bits<5> Rd; 4831 bits<5> Rn; 4832 bits<5> Rm; 4833 let Inst{31} = 0; 4834 let Inst{30} = size{0}; 4835 let Inst{29} = U; 4836 let Inst{28-24} = 0b01110; 4837 let Inst{23-22} = size{2-1}; 4838 let Inst{21} = 1; 4839 let Inst{20-16} = Rm; 4840 let Inst{15-12} = opcode; 4841 let Inst{11-10} = 0b00; 4842 let Inst{9-5} = Rn; 4843 let Inst{4-0} = Rd; 4844} 4845 4846let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 4847class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode, 4848 RegisterOperand outtype, RegisterOperand intype1, 4849 RegisterOperand intype2, string asm, 4850 string outkind, string inkind1, string inkind2, 4851 list<dag> pattern> 4852 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm, 4853 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 # 4854 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>, 4855 Sched<[WriteV]> { 4856 bits<5> Rd; 4857 bits<5> Rn; 4858 bits<5> Rm; 4859 let Inst{31} = 0; 4860 let Inst{30} = size{0}; 4861 let Inst{29} = U; 4862 let Inst{28-24} = 0b01110; 4863 let Inst{23-22} = size{2-1}; 4864 let Inst{21} = 1; 4865 let Inst{20-16} = Rm; 4866 let Inst{15-12} = opcode; 4867 let Inst{11-10} = 0b00; 4868 let Inst{9-5} = Rn; 4869 let Inst{4-0} = Rd; 4870} 4871 4872// FIXME: TableGen doesn't know how to deal with expanded types that also 4873// change the element count (in this case, placing the results in 4874// the high elements of the result register rather than the low 4875// elements). Until that's fixed, we can't code-gen those. 4876multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm, 4877 Intrinsic IntOp> { 4878 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 4879 V64, V128, V128, 4880 asm, ".8b", ".8h", ".8h", 4881 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>; 4882 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 4883 V128, V128, V128, 4884 asm#"2", ".16b", ".8h", ".8h", 4885 []>; 4886 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 4887 V64, V128, V128, 4888 asm, ".4h", ".4s", ".4s", 4889 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>; 4890 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 4891 V128, V128, V128, 4892 asm#"2", ".8h", ".4s", ".4s", 4893 []>; 4894 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 4895 V64, V128, V128, 4896 asm, ".2s", ".2d", ".2d", 4897 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>; 4898 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 4899 V128, V128, V128, 4900 asm#"2", ".4s", ".2d", ".2d", 4901 []>; 4902 4903 4904 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in 4905 // a version attached to an instruction. 4906 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), 4907 (v8i16 V128:$Rm))), 4908 (!cast<Instruction>(NAME # "v8i16_v16i8") 4909 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 4910 V128:$Rn, V128:$Rm)>; 4911 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), 4912 (v4i32 V128:$Rm))), 4913 (!cast<Instruction>(NAME # "v4i32_v8i16") 4914 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 4915 V128:$Rn, V128:$Rm)>; 4916 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), 4917 (v2i64 V128:$Rm))), 4918 (!cast<Instruction>(NAME # "v2i64_v4i32") 4919 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 4920 V128:$Rn, V128:$Rm)>; 4921} 4922 4923multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm, 4924 Intrinsic IntOp> { 4925 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 4926 V128, V64, V64, 4927 asm, ".8h", ".8b", ".8b", 4928 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 4929 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 4930 V128, V128, V128, 4931 asm#"2", ".8h", ".16b", ".16b", []>; 4932 let Predicates = [HasCrypto] in { 4933 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc, 4934 V128, V64, V64, 4935 asm, ".1q", ".1d", ".1d", []>; 4936 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc, 4937 V128, V128, V128, 4938 asm#"2", ".1q", ".2d", ".2d", []>; 4939 } 4940 4941 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)), 4942 (v8i8 (extract_high_v16i8 V128:$Rm)))), 4943 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>; 4944} 4945 4946multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm, 4947 SDPatternOperator OpNode> { 4948 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 4949 V128, V64, V64, 4950 asm, ".4s", ".4h", ".4h", 4951 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 4952 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 4953 V128, V128, V128, 4954 asm#"2", ".4s", ".8h", ".8h", 4955 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 4956 (extract_high_v8i16 V128:$Rm)))]>; 4957 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 4958 V128, V64, V64, 4959 asm, ".2d", ".2s", ".2s", 4960 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 4961 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 4962 V128, V128, V128, 4963 asm#"2", ".2d", ".4s", ".4s", 4964 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 4965 (extract_high_v4i32 V128:$Rm)))]>; 4966} 4967 4968multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm, 4969 SDPatternOperator OpNode = null_frag> { 4970 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 4971 V128, V64, V64, 4972 asm, ".8h", ".8b", ".8b", 4973 [(set (v8i16 V128:$Rd), 4974 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>; 4975 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 4976 V128, V128, V128, 4977 asm#"2", ".8h", ".16b", ".16b", 4978 [(set (v8i16 V128:$Rd), 4979 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 4980 (extract_high_v16i8 V128:$Rm)))))]>; 4981 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 4982 V128, V64, V64, 4983 asm, ".4s", ".4h", ".4h", 4984 [(set (v4i32 V128:$Rd), 4985 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>; 4986 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 4987 V128, V128, V128, 4988 asm#"2", ".4s", ".8h", ".8h", 4989 [(set (v4i32 V128:$Rd), 4990 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 4991 (extract_high_v8i16 V128:$Rm)))))]>; 4992 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 4993 V128, V64, V64, 4994 asm, ".2d", ".2s", ".2s", 4995 [(set (v2i64 V128:$Rd), 4996 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>; 4997 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 4998 V128, V128, V128, 4999 asm#"2", ".2d", ".4s", ".4s", 5000 [(set (v2i64 V128:$Rd), 5001 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 5002 (extract_high_v4i32 V128:$Rm)))))]>; 5003} 5004 5005multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc, 5006 string asm, 5007 SDPatternOperator OpNode> { 5008 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 5009 V128, V64, V64, 5010 asm, ".8h", ".8b", ".8b", 5011 [(set (v8i16 V128:$dst), 5012 (add (v8i16 V128:$Rd), 5013 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>; 5014 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5015 V128, V128, V128, 5016 asm#"2", ".8h", ".16b", ".16b", 5017 [(set (v8i16 V128:$dst), 5018 (add (v8i16 V128:$Rd), 5019 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn), 5020 (extract_high_v16i8 V128:$Rm))))))]>; 5021 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5022 V128, V64, V64, 5023 asm, ".4s", ".4h", ".4h", 5024 [(set (v4i32 V128:$dst), 5025 (add (v4i32 V128:$Rd), 5026 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>; 5027 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5028 V128, V128, V128, 5029 asm#"2", ".4s", ".8h", ".8h", 5030 [(set (v4i32 V128:$dst), 5031 (add (v4i32 V128:$Rd), 5032 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn), 5033 (extract_high_v8i16 V128:$Rm))))))]>; 5034 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5035 V128, V64, V64, 5036 asm, ".2d", ".2s", ".2s", 5037 [(set (v2i64 V128:$dst), 5038 (add (v2i64 V128:$Rd), 5039 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>; 5040 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5041 V128, V128, V128, 5042 asm#"2", ".2d", ".4s", ".4s", 5043 [(set (v2i64 V128:$dst), 5044 (add (v2i64 V128:$Rd), 5045 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn), 5046 (extract_high_v4i32 V128:$Rm))))))]>; 5047} 5048 5049multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm, 5050 SDPatternOperator OpNode = null_frag> { 5051 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5052 V128, V64, V64, 5053 asm, ".8h", ".8b", ".8b", 5054 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5055 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5056 V128, V128, V128, 5057 asm#"2", ".8h", ".16b", ".16b", 5058 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn), 5059 (extract_high_v16i8 V128:$Rm)))]>; 5060 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5061 V128, V64, V64, 5062 asm, ".4s", ".4h", ".4h", 5063 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5064 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5065 V128, V128, V128, 5066 asm#"2", ".4s", ".8h", ".8h", 5067 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn), 5068 (extract_high_v8i16 V128:$Rm)))]>; 5069 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5070 V128, V64, V64, 5071 asm, ".2d", ".2s", ".2s", 5072 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5073 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5074 V128, V128, V128, 5075 asm#"2", ".2d", ".4s", ".4s", 5076 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn), 5077 (extract_high_v4i32 V128:$Rm)))]>; 5078} 5079 5080multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc, 5081 string asm, 5082 SDPatternOperator OpNode> { 5083 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc, 5084 V128, V64, V64, 5085 asm, ".8h", ".8b", ".8b", 5086 [(set (v8i16 V128:$dst), 5087 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; 5088 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc, 5089 V128, V128, V128, 5090 asm#"2", ".8h", ".16b", ".16b", 5091 [(set (v8i16 V128:$dst), 5092 (OpNode (v8i16 V128:$Rd), 5093 (extract_high_v16i8 V128:$Rn), 5094 (extract_high_v16i8 V128:$Rm)))]>; 5095 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5096 V128, V64, V64, 5097 asm, ".4s", ".4h", ".4h", 5098 [(set (v4i32 V128:$dst), 5099 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>; 5100 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5101 V128, V128, V128, 5102 asm#"2", ".4s", ".8h", ".8h", 5103 [(set (v4i32 V128:$dst), 5104 (OpNode (v4i32 V128:$Rd), 5105 (extract_high_v8i16 V128:$Rn), 5106 (extract_high_v8i16 V128:$Rm)))]>; 5107 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5108 V128, V64, V64, 5109 asm, ".2d", ".2s", ".2s", 5110 [(set (v2i64 V128:$dst), 5111 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>; 5112 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5113 V128, V128, V128, 5114 asm#"2", ".2d", ".4s", ".4s", 5115 [(set (v2i64 V128:$dst), 5116 (OpNode (v2i64 V128:$Rd), 5117 (extract_high_v4i32 V128:$Rn), 5118 (extract_high_v4i32 V128:$Rm)))]>; 5119} 5120 5121multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm, 5122 SDPatternOperator Accum> { 5123 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc, 5124 V128, V64, V64, 5125 asm, ".4s", ".4h", ".4h", 5126 [(set (v4i32 V128:$dst), 5127 (Accum (v4i32 V128:$Rd), 5128 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 5129 (v4i16 V64:$Rm)))))]>; 5130 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc, 5131 V128, V128, V128, 5132 asm#"2", ".4s", ".8h", ".8h", 5133 [(set (v4i32 V128:$dst), 5134 (Accum (v4i32 V128:$Rd), 5135 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn), 5136 (extract_high_v8i16 V128:$Rm)))))]>; 5137 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc, 5138 V128, V64, V64, 5139 asm, ".2d", ".2s", ".2s", 5140 [(set (v2i64 V128:$dst), 5141 (Accum (v2i64 V128:$Rd), 5142 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn), 5143 (v2i32 V64:$Rm)))))]>; 5144 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc, 5145 V128, V128, V128, 5146 asm#"2", ".2d", ".4s", ".4s", 5147 [(set (v2i64 V128:$dst), 5148 (Accum (v2i64 V128:$Rd), 5149 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn), 5150 (extract_high_v4i32 V128:$Rm)))))]>; 5151} 5152 5153multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm, 5154 SDPatternOperator OpNode> { 5155 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc, 5156 V128, V128, V64, 5157 asm, ".8h", ".8h", ".8b", 5158 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>; 5159 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc, 5160 V128, V128, V128, 5161 asm#"2", ".8h", ".8h", ".16b", 5162 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 5163 (extract_high_v16i8 V128:$Rm)))]>; 5164 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc, 5165 V128, V128, V64, 5166 asm, ".4s", ".4s", ".4h", 5167 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>; 5168 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc, 5169 V128, V128, V128, 5170 asm#"2", ".4s", ".4s", ".8h", 5171 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 5172 (extract_high_v8i16 V128:$Rm)))]>; 5173 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc, 5174 V128, V128, V64, 5175 asm, ".2d", ".2d", ".2s", 5176 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>; 5177 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc, 5178 V128, V128, V128, 5179 asm#"2", ".2d", ".2d", ".4s", 5180 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 5181 (extract_high_v4i32 V128:$Rm)))]>; 5182} 5183 5184//---------------------------------------------------------------------------- 5185// AdvSIMD bitwise extract from vector 5186//---------------------------------------------------------------------------- 5187 5188class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty, 5189 string asm, string kind> 5190 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm, 5191 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" # 5192 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "", 5193 [(set (vty regtype:$Rd), 5194 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>, 5195 Sched<[WriteV]> { 5196 bits<5> Rd; 5197 bits<5> Rn; 5198 bits<5> Rm; 5199 bits<4> imm; 5200 let Inst{31} = 0; 5201 let Inst{30} = size; 5202 let Inst{29-21} = 0b101110000; 5203 let Inst{20-16} = Rm; 5204 let Inst{15} = 0; 5205 let Inst{14-11} = imm; 5206 let Inst{10} = 0; 5207 let Inst{9-5} = Rn; 5208 let Inst{4-0} = Rd; 5209} 5210 5211 5212multiclass SIMDBitwiseExtract<string asm> { 5213 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> { 5214 let imm{3} = 0; 5215 } 5216 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">; 5217} 5218 5219//---------------------------------------------------------------------------- 5220// AdvSIMD zip vector 5221//---------------------------------------------------------------------------- 5222 5223class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype, 5224 string asm, string kind, SDNode OpNode, ValueType valty> 5225 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5226 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # 5227 "|" # kind # "\t$Rd, $Rn, $Rm}", "", 5228 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>, 5229 Sched<[WriteV]> { 5230 bits<5> Rd; 5231 bits<5> Rn; 5232 bits<5> Rm; 5233 let Inst{31} = 0; 5234 let Inst{30} = size{0}; 5235 let Inst{29-24} = 0b001110; 5236 let Inst{23-22} = size{2-1}; 5237 let Inst{21} = 0; 5238 let Inst{20-16} = Rm; 5239 let Inst{15} = 0; 5240 let Inst{14-12} = opc; 5241 let Inst{11-10} = 0b10; 5242 let Inst{9-5} = Rn; 5243 let Inst{4-0} = Rd; 5244} 5245 5246multiclass SIMDZipVector<bits<3>opc, string asm, 5247 SDNode OpNode> { 5248 def v8i8 : BaseSIMDZipVector<0b000, opc, V64, 5249 asm, ".8b", OpNode, v8i8>; 5250 def v16i8 : BaseSIMDZipVector<0b001, opc, V128, 5251 asm, ".16b", OpNode, v16i8>; 5252 def v4i16 : BaseSIMDZipVector<0b010, opc, V64, 5253 asm, ".4h", OpNode, v4i16>; 5254 def v8i16 : BaseSIMDZipVector<0b011, opc, V128, 5255 asm, ".8h", OpNode, v8i16>; 5256 def v2i32 : BaseSIMDZipVector<0b100, opc, V64, 5257 asm, ".2s", OpNode, v2i32>; 5258 def v4i32 : BaseSIMDZipVector<0b101, opc, V128, 5259 asm, ".4s", OpNode, v4i32>; 5260 def v2i64 : BaseSIMDZipVector<0b111, opc, V128, 5261 asm, ".2d", OpNode, v2i64>; 5262 5263 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)), 5264 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>; 5265 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)), 5266 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>; 5267 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)), 5268 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>; 5269 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)), 5270 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>; 5271 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)), 5272 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>; 5273} 5274 5275//---------------------------------------------------------------------------- 5276// AdvSIMD three register scalar instructions 5277//---------------------------------------------------------------------------- 5278 5279let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5280class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode, 5281 RegisterClass regtype, string asm, 5282 list<dag> pattern> 5283 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm, 5284 "\t$Rd, $Rn, $Rm", "", pattern>, 5285 Sched<[WriteV]> { 5286 bits<5> Rd; 5287 bits<5> Rn; 5288 bits<5> Rm; 5289 let Inst{31-30} = 0b01; 5290 let Inst{29} = U; 5291 let Inst{28-24} = 0b11110; 5292 let Inst{23-22} = size; 5293 let Inst{21} = 1; 5294 let Inst{20-16} = Rm; 5295 let Inst{15-11} = opcode; 5296 let Inst{10} = 1; 5297 let Inst{9-5} = Rn; 5298 let Inst{4-0} = Rd; 5299} 5300 5301multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm, 5302 SDPatternOperator OpNode> { 5303 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm, 5304 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 5305} 5306 5307multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm, 5308 SDPatternOperator OpNode> { 5309 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm, 5310 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>; 5311 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>; 5312 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>; 5313 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>; 5314 5315 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))), 5316 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>; 5317 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))), 5318 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>; 5319} 5320 5321multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm, 5322 SDPatternOperator OpNode> { 5323 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, 5324 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 5325 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>; 5326} 5327 5328multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm, 5329 SDPatternOperator OpNode = null_frag> { 5330 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5331 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm, 5332 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 5333 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm, 5334 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>; 5335 } 5336 5337 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5338 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 5339} 5340 5341multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm, 5342 SDPatternOperator OpNode = null_frag> { 5343 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5344 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm, 5345 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>; 5346 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm, 5347 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>; 5348 } 5349 5350 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5351 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>; 5352} 5353 5354class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode, 5355 dag oops, dag iops, string asm, string cstr, list<dag> pat> 5356 : I<oops, iops, asm, 5357 "\t$Rd, $Rn, $Rm", cstr, pat>, 5358 Sched<[WriteV]> { 5359 bits<5> Rd; 5360 bits<5> Rn; 5361 bits<5> Rm; 5362 let Inst{31-30} = 0b01; 5363 let Inst{29} = U; 5364 let Inst{28-24} = 0b11110; 5365 let Inst{23-22} = size; 5366 let Inst{21} = 1; 5367 let Inst{20-16} = Rm; 5368 let Inst{15-11} = opcode; 5369 let Inst{10} = 0; 5370 let Inst{9-5} = Rn; 5371 let Inst{4-0} = Rd; 5372} 5373 5374let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5375multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm, 5376 SDPatternOperator OpNode = null_frag> { 5377 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 5378 (outs FPR32:$Rd), 5379 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>; 5380 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 5381 (outs FPR64:$Rd), 5382 (ins FPR32:$Rn, FPR32:$Rm), asm, "", 5383 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 5384} 5385 5386let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5387multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm, 5388 SDPatternOperator OpNode = null_frag> { 5389 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc, 5390 (outs FPR32:$dst), 5391 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm), 5392 asm, "$Rd = $dst", []>; 5393 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc, 5394 (outs FPR64:$dst), 5395 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm), 5396 asm, "$Rd = $dst", 5397 [(set (i64 FPR64:$dst), 5398 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>; 5399} 5400 5401//---------------------------------------------------------------------------- 5402// AdvSIMD two register scalar instructions 5403//---------------------------------------------------------------------------- 5404 5405let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5406class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode, 5407 RegisterClass regtype, RegisterClass regtype2, 5408 string asm, list<dag> pat> 5409 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm, 5410 "\t$Rd, $Rn", "", pat>, 5411 Sched<[WriteV]> { 5412 bits<5> Rd; 5413 bits<5> Rn; 5414 let Inst{31-30} = 0b01; 5415 let Inst{29} = U; 5416 let Inst{28-24} = 0b11110; 5417 let Inst{23-22} = size; 5418 let Inst{21-17} = 0b10000; 5419 let Inst{16-12} = opcode; 5420 let Inst{11-10} = 0b10; 5421 let Inst{9-5} = Rn; 5422 let Inst{4-0} = Rd; 5423} 5424 5425let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5426class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode, 5427 RegisterClass regtype, RegisterClass regtype2, 5428 string asm, list<dag> pat> 5429 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm, 5430 "\t$Rd, $Rn", "$Rd = $dst", pat>, 5431 Sched<[WriteV]> { 5432 bits<5> Rd; 5433 bits<5> Rn; 5434 let Inst{31-30} = 0b01; 5435 let Inst{29} = U; 5436 let Inst{28-24} = 0b11110; 5437 let Inst{23-22} = size; 5438 let Inst{21-17} = 0b10000; 5439 let Inst{16-12} = opcode; 5440 let Inst{11-10} = 0b10; 5441 let Inst{9-5} = Rn; 5442 let Inst{4-0} = Rd; 5443} 5444 5445 5446let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5447class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode, 5448 RegisterClass regtype, string asm, string zero> 5449 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, 5450 "\t$Rd, $Rn, #" # zero, "", []>, 5451 Sched<[WriteV]> { 5452 bits<5> Rd; 5453 bits<5> Rn; 5454 let Inst{31-30} = 0b01; 5455 let Inst{29} = U; 5456 let Inst{28-24} = 0b11110; 5457 let Inst{23-22} = size; 5458 let Inst{21-17} = 0b10000; 5459 let Inst{16-12} = opcode; 5460 let Inst{11-10} = 0b10; 5461 let Inst{9-5} = Rn; 5462 let Inst{4-0} = Rd; 5463} 5464 5465class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm> 5466 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "", 5467 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>, 5468 Sched<[WriteV]> { 5469 bits<5> Rd; 5470 bits<5> Rn; 5471 let Inst{31-17} = 0b011111100110000; 5472 let Inst{16-12} = opcode; 5473 let Inst{11-10} = 0b10; 5474 let Inst{9-5} = Rn; 5475 let Inst{4-0} = Rd; 5476} 5477 5478multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm, 5479 SDPatternOperator OpNode> { 5480 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">; 5481 5482 def : Pat<(v1i64 (OpNode FPR64:$Rn)), 5483 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 5484} 5485 5486multiclass SIMDCmpTwoScalarSD<bit U, bit S, bits<5> opc, string asm, 5487 SDPatternOperator OpNode> { 5488 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">; 5489 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">; 5490 5491 def : InstAlias<asm # " $Rd, $Rn, #0", 5492 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>; 5493 def : InstAlias<asm # " $Rd, $Rn, #0", 5494 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>; 5495 5496 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))), 5497 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>; 5498} 5499 5500multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm, 5501 SDPatternOperator OpNode = null_frag> { 5502 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm, 5503 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>; 5504 5505 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), 5506 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>; 5507} 5508 5509multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> { 5510 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>; 5511 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>; 5512} 5513 5514multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm, 5515 SDPatternOperator OpNode> { 5516 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm, 5517 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>; 5518 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm, 5519 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>; 5520} 5521 5522multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm, 5523 SDPatternOperator OpNode = null_frag> { 5524 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5525 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm, 5526 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 5527 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm, 5528 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 5529 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>; 5530 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 5531 } 5532 5533 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))), 5534 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>; 5535} 5536 5537multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm, 5538 Intrinsic OpNode> { 5539 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 5540 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm, 5541 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>; 5542 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm, 5543 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>; 5544 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>; 5545 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>; 5546 } 5547 5548 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))), 5549 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>; 5550} 5551 5552 5553 5554let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5555multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm, 5556 SDPatternOperator OpNode = null_frag> { 5557 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm, 5558 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>; 5559 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>; 5560 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>; 5561} 5562 5563//---------------------------------------------------------------------------- 5564// AdvSIMD scalar pairwise instructions 5565//---------------------------------------------------------------------------- 5566 5567let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5568class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode, 5569 RegisterOperand regtype, RegisterOperand vectype, 5570 string asm, string kind> 5571 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 5572 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>, 5573 Sched<[WriteV]> { 5574 bits<5> Rd; 5575 bits<5> Rn; 5576 let Inst{31-30} = 0b01; 5577 let Inst{29} = U; 5578 let Inst{28-24} = 0b11110; 5579 let Inst{23-22} = size; 5580 let Inst{21-17} = 0b11000; 5581 let Inst{16-12} = opcode; 5582 let Inst{11-10} = 0b10; 5583 let Inst{9-5} = Rn; 5584 let Inst{4-0} = Rd; 5585} 5586 5587multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> { 5588 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128, 5589 asm, ".2d">; 5590} 5591 5592multiclass SIMDPairwiseScalarSD<bit U, bit S, bits<5> opc, string asm> { 5593 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64, 5594 asm, ".2s">; 5595 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128, 5596 asm, ".2d">; 5597} 5598 5599//---------------------------------------------------------------------------- 5600// AdvSIMD across lanes instructions 5601//---------------------------------------------------------------------------- 5602 5603let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 5604class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode, 5605 RegisterClass regtype, RegisterOperand vectype, 5606 string asm, string kind, list<dag> pattern> 5607 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm, 5608 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>, 5609 Sched<[WriteV]> { 5610 bits<5> Rd; 5611 bits<5> Rn; 5612 let Inst{31} = 0; 5613 let Inst{30} = Q; 5614 let Inst{29} = U; 5615 let Inst{28-24} = 0b01110; 5616 let Inst{23-22} = size; 5617 let Inst{21-17} = 0b11000; 5618 let Inst{16-12} = opcode; 5619 let Inst{11-10} = 0b10; 5620 let Inst{9-5} = Rn; 5621 let Inst{4-0} = Rd; 5622} 5623 5624multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode, 5625 string asm> { 5626 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64, 5627 asm, ".8b", []>; 5628 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128, 5629 asm, ".16b", []>; 5630 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64, 5631 asm, ".4h", []>; 5632 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128, 5633 asm, ".8h", []>; 5634 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128, 5635 asm, ".4s", []>; 5636} 5637 5638multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> { 5639 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64, 5640 asm, ".8b", []>; 5641 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128, 5642 asm, ".16b", []>; 5643 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64, 5644 asm, ".4h", []>; 5645 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128, 5646 asm, ".8h", []>; 5647 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128, 5648 asm, ".4s", []>; 5649} 5650 5651multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm, 5652 Intrinsic intOp> { 5653 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128, 5654 asm, ".4s", 5655 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>; 5656} 5657 5658//---------------------------------------------------------------------------- 5659// AdvSIMD INS/DUP instructions 5660//---------------------------------------------------------------------------- 5661 5662// FIXME: There has got to be a better way to factor these. ugh. 5663 5664class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm, 5665 string operands, string constraints, list<dag> pattern> 5666 : I<outs, ins, asm, operands, constraints, pattern>, 5667 Sched<[WriteV]> { 5668 bits<5> Rd; 5669 bits<5> Rn; 5670 let Inst{31} = 0; 5671 let Inst{30} = Q; 5672 let Inst{29} = op; 5673 let Inst{28-21} = 0b01110000; 5674 let Inst{15} = 0; 5675 let Inst{10} = 1; 5676 let Inst{9-5} = Rn; 5677 let Inst{4-0} = Rd; 5678} 5679 5680class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype, 5681 RegisterOperand vecreg, RegisterClass regtype> 5682 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup", 5683 "{\t$Rd" # size # ", $Rn" # 5684 "|" # size # "\t$Rd, $Rn}", "", 5685 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> { 5686 let Inst{20-16} = imm5; 5687 let Inst{14-11} = 0b0001; 5688} 5689 5690class SIMDDupFromElement<bit Q, string dstkind, string srckind, 5691 ValueType vectype, ValueType insreg, 5692 RegisterOperand vecreg, Operand idxtype, 5693 ValueType elttype, SDNode OpNode> 5694 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup", 5695 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" # 5696 "|" # dstkind # "\t$Rd, $Rn$idx}", "", 5697 [(set (vectype vecreg:$Rd), 5698 (OpNode (insreg V128:$Rn), idxtype:$idx))]> { 5699 let Inst{14-11} = 0b0000; 5700} 5701 5702class SIMDDup64FromElement 5703 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128, 5704 VectorIndexD, i64, AArch64duplane64> { 5705 bits<1> idx; 5706 let Inst{20} = idx; 5707 let Inst{19-16} = 0b1000; 5708} 5709 5710class SIMDDup32FromElement<bit Q, string size, ValueType vectype, 5711 RegisterOperand vecreg> 5712 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg, 5713 VectorIndexS, i64, AArch64duplane32> { 5714 bits<2> idx; 5715 let Inst{20-19} = idx; 5716 let Inst{18-16} = 0b100; 5717} 5718 5719class SIMDDup16FromElement<bit Q, string size, ValueType vectype, 5720 RegisterOperand vecreg> 5721 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg, 5722 VectorIndexH, i64, AArch64duplane16> { 5723 bits<3> idx; 5724 let Inst{20-18} = idx; 5725 let Inst{17-16} = 0b10; 5726} 5727 5728class SIMDDup8FromElement<bit Q, string size, ValueType vectype, 5729 RegisterOperand vecreg> 5730 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg, 5731 VectorIndexB, i64, AArch64duplane8> { 5732 bits<4> idx; 5733 let Inst{20-17} = idx; 5734 let Inst{16} = 1; 5735} 5736 5737class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype, 5738 Operand idxtype, string asm, list<dag> pattern> 5739 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm, 5740 "{\t$Rd, $Rn" # size # "$idx" # 5741 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> { 5742 let Inst{14-11} = imm4; 5743} 5744 5745class SIMDSMov<bit Q, string size, RegisterClass regtype, 5746 Operand idxtype> 5747 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>; 5748class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype, 5749 Operand idxtype> 5750 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov", 5751 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>; 5752 5753class SIMDMovAlias<string asm, string size, Instruction inst, 5754 RegisterClass regtype, Operand idxtype> 5755 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" # 5756 "|" # size # "\t$dst, $src$idx}", 5757 (inst regtype:$dst, V128:$src, idxtype:$idx)>; 5758 5759multiclass SMov { 5760 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> { 5761 bits<4> idx; 5762 let Inst{20-17} = idx; 5763 let Inst{16} = 1; 5764 } 5765 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> { 5766 bits<4> idx; 5767 let Inst{20-17} = idx; 5768 let Inst{16} = 1; 5769 } 5770 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> { 5771 bits<3> idx; 5772 let Inst{20-18} = idx; 5773 let Inst{17-16} = 0b10; 5774 } 5775 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> { 5776 bits<3> idx; 5777 let Inst{20-18} = idx; 5778 let Inst{17-16} = 0b10; 5779 } 5780 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> { 5781 bits<2> idx; 5782 let Inst{20-19} = idx; 5783 let Inst{18-16} = 0b100; 5784 } 5785} 5786 5787multiclass UMov { 5788 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> { 5789 bits<4> idx; 5790 let Inst{20-17} = idx; 5791 let Inst{16} = 1; 5792 } 5793 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> { 5794 bits<3> idx; 5795 let Inst{20-18} = idx; 5796 let Inst{17-16} = 0b10; 5797 } 5798 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> { 5799 bits<2> idx; 5800 let Inst{20-19} = idx; 5801 let Inst{18-16} = 0b100; 5802 } 5803 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> { 5804 bits<1> idx; 5805 let Inst{20} = idx; 5806 let Inst{19-16} = 0b1000; 5807 } 5808 def : SIMDMovAlias<"mov", ".s", 5809 !cast<Instruction>(NAME#"vi32"), 5810 GPR32, VectorIndexS>; 5811 def : SIMDMovAlias<"mov", ".d", 5812 !cast<Instruction>(NAME#"vi64"), 5813 GPR64, VectorIndexD>; 5814} 5815 5816class SIMDInsFromMain<string size, ValueType vectype, 5817 RegisterClass regtype, Operand idxtype> 5818 : BaseSIMDInsDup<1, 0, (outs V128:$dst), 5819 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins", 5820 "{\t$Rd" # size # "$idx, $Rn" # 5821 "|" # size # "\t$Rd$idx, $Rn}", 5822 "$Rd = $dst", 5823 [(set V128:$dst, 5824 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> { 5825 let Inst{14-11} = 0b0011; 5826} 5827 5828class SIMDInsFromElement<string size, ValueType vectype, 5829 ValueType elttype, Operand idxtype> 5830 : BaseSIMDInsDup<1, 1, (outs V128:$dst), 5831 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins", 5832 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" # 5833 "|" # size # "\t$Rd$idx, $Rn$idx2}", 5834 "$Rd = $dst", 5835 [(set V128:$dst, 5836 (vector_insert 5837 (vectype V128:$Rd), 5838 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)), 5839 idxtype:$idx))]>; 5840 5841class SIMDInsMainMovAlias<string size, Instruction inst, 5842 RegisterClass regtype, Operand idxtype> 5843 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # 5844 "|" # size #"\t$dst$idx, $src}", 5845 (inst V128:$dst, idxtype:$idx, regtype:$src)>; 5846class SIMDInsElementMovAlias<string size, Instruction inst, 5847 Operand idxtype> 5848 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" # 5849 # "|" # size #" $dst$idx, $src$idx2}", 5850 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>; 5851 5852 5853multiclass SIMDIns { 5854 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> { 5855 bits<4> idx; 5856 let Inst{20-17} = idx; 5857 let Inst{16} = 1; 5858 } 5859 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> { 5860 bits<3> idx; 5861 let Inst{20-18} = idx; 5862 let Inst{17-16} = 0b10; 5863 } 5864 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> { 5865 bits<2> idx; 5866 let Inst{20-19} = idx; 5867 let Inst{18-16} = 0b100; 5868 } 5869 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> { 5870 bits<1> idx; 5871 let Inst{20} = idx; 5872 let Inst{19-16} = 0b1000; 5873 } 5874 5875 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> { 5876 bits<4> idx; 5877 bits<4> idx2; 5878 let Inst{20-17} = idx; 5879 let Inst{16} = 1; 5880 let Inst{14-11} = idx2; 5881 } 5882 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> { 5883 bits<3> idx; 5884 bits<3> idx2; 5885 let Inst{20-18} = idx; 5886 let Inst{17-16} = 0b10; 5887 let Inst{14-12} = idx2; 5888 let Inst{11} = 0; 5889 } 5890 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> { 5891 bits<2> idx; 5892 bits<2> idx2; 5893 let Inst{20-19} = idx; 5894 let Inst{18-16} = 0b100; 5895 let Inst{14-13} = idx2; 5896 let Inst{12-11} = 0; 5897 } 5898 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> { 5899 bits<1> idx; 5900 bits<1> idx2; 5901 let Inst{20} = idx; 5902 let Inst{19-16} = 0b1000; 5903 let Inst{14} = idx2; 5904 let Inst{13-11} = 0; 5905 } 5906 5907 // For all forms of the INS instruction, the "mov" mnemonic is the 5908 // preferred alias. Why they didn't just call the instruction "mov" in 5909 // the first place is a very good question indeed... 5910 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"), 5911 GPR32, VectorIndexB>; 5912 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"), 5913 GPR32, VectorIndexH>; 5914 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"), 5915 GPR32, VectorIndexS>; 5916 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"), 5917 GPR64, VectorIndexD>; 5918 5919 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"), 5920 VectorIndexB>; 5921 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"), 5922 VectorIndexH>; 5923 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"), 5924 VectorIndexS>; 5925 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"), 5926 VectorIndexD>; 5927} 5928 5929//---------------------------------------------------------------------------- 5930// AdvSIMD TBL/TBX 5931//---------------------------------------------------------------------------- 5932 5933let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5934class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype, 5935 RegisterOperand listtype, string asm, string kind> 5936 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm, 5937 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>, 5938 Sched<[WriteV]> { 5939 bits<5> Vd; 5940 bits<5> Vn; 5941 bits<5> Vm; 5942 let Inst{31} = 0; 5943 let Inst{30} = Q; 5944 let Inst{29-21} = 0b001110000; 5945 let Inst{20-16} = Vm; 5946 let Inst{15} = 0; 5947 let Inst{14-13} = len; 5948 let Inst{12} = op; 5949 let Inst{11-10} = 0b00; 5950 let Inst{9-5} = Vn; 5951 let Inst{4-0} = Vd; 5952} 5953 5954let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 5955class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype, 5956 RegisterOperand listtype, string asm, string kind> 5957 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm, 5958 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>, 5959 Sched<[WriteV]> { 5960 bits<5> Vd; 5961 bits<5> Vn; 5962 bits<5> Vm; 5963 let Inst{31} = 0; 5964 let Inst{30} = Q; 5965 let Inst{29-21} = 0b001110000; 5966 let Inst{20-16} = Vm; 5967 let Inst{15} = 0; 5968 let Inst{14-13} = len; 5969 let Inst{12} = op; 5970 let Inst{11-10} = 0b00; 5971 let Inst{9-5} = Vn; 5972 let Inst{4-0} = Vd; 5973} 5974 5975class SIMDTableLookupAlias<string asm, Instruction inst, 5976 RegisterOperand vectype, RegisterOperand listtype> 5977 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"), 5978 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>; 5979 5980multiclass SIMDTableLookup<bit op, string asm> { 5981 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b, 5982 asm, ".8b">; 5983 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b, 5984 asm, ".8b">; 5985 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b, 5986 asm, ".8b">; 5987 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b, 5988 asm, ".8b">; 5989 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b, 5990 asm, ".16b">; 5991 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b, 5992 asm, ".16b">; 5993 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b, 5994 asm, ".16b">; 5995 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b, 5996 asm, ".16b">; 5997 5998 def : SIMDTableLookupAlias<asm # ".8b", 5999 !cast<Instruction>(NAME#"v8i8One"), 6000 V64, VecListOne128>; 6001 def : SIMDTableLookupAlias<asm # ".8b", 6002 !cast<Instruction>(NAME#"v8i8Two"), 6003 V64, VecListTwo128>; 6004 def : SIMDTableLookupAlias<asm # ".8b", 6005 !cast<Instruction>(NAME#"v8i8Three"), 6006 V64, VecListThree128>; 6007 def : SIMDTableLookupAlias<asm # ".8b", 6008 !cast<Instruction>(NAME#"v8i8Four"), 6009 V64, VecListFour128>; 6010 def : SIMDTableLookupAlias<asm # ".16b", 6011 !cast<Instruction>(NAME#"v16i8One"), 6012 V128, VecListOne128>; 6013 def : SIMDTableLookupAlias<asm # ".16b", 6014 !cast<Instruction>(NAME#"v16i8Two"), 6015 V128, VecListTwo128>; 6016 def : SIMDTableLookupAlias<asm # ".16b", 6017 !cast<Instruction>(NAME#"v16i8Three"), 6018 V128, VecListThree128>; 6019 def : SIMDTableLookupAlias<asm # ".16b", 6020 !cast<Instruction>(NAME#"v16i8Four"), 6021 V128, VecListFour128>; 6022} 6023 6024multiclass SIMDTableLookupTied<bit op, string asm> { 6025 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b, 6026 asm, ".8b">; 6027 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b, 6028 asm, ".8b">; 6029 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b, 6030 asm, ".8b">; 6031 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b, 6032 asm, ".8b">; 6033 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b, 6034 asm, ".16b">; 6035 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b, 6036 asm, ".16b">; 6037 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b, 6038 asm, ".16b">; 6039 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b, 6040 asm, ".16b">; 6041 6042 def : SIMDTableLookupAlias<asm # ".8b", 6043 !cast<Instruction>(NAME#"v8i8One"), 6044 V64, VecListOne128>; 6045 def : SIMDTableLookupAlias<asm # ".8b", 6046 !cast<Instruction>(NAME#"v8i8Two"), 6047 V64, VecListTwo128>; 6048 def : SIMDTableLookupAlias<asm # ".8b", 6049 !cast<Instruction>(NAME#"v8i8Three"), 6050 V64, VecListThree128>; 6051 def : SIMDTableLookupAlias<asm # ".8b", 6052 !cast<Instruction>(NAME#"v8i8Four"), 6053 V64, VecListFour128>; 6054 def : SIMDTableLookupAlias<asm # ".16b", 6055 !cast<Instruction>(NAME#"v16i8One"), 6056 V128, VecListOne128>; 6057 def : SIMDTableLookupAlias<asm # ".16b", 6058 !cast<Instruction>(NAME#"v16i8Two"), 6059 V128, VecListTwo128>; 6060 def : SIMDTableLookupAlias<asm # ".16b", 6061 !cast<Instruction>(NAME#"v16i8Three"), 6062 V128, VecListThree128>; 6063 def : SIMDTableLookupAlias<asm # ".16b", 6064 !cast<Instruction>(NAME#"v16i8Four"), 6065 V128, VecListFour128>; 6066} 6067 6068 6069//---------------------------------------------------------------------------- 6070// AdvSIMD scalar CPY 6071//---------------------------------------------------------------------------- 6072let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6073class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype, 6074 string kind, Operand idxtype> 6075 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov", 6076 "{\t$dst, $src" # kind # "$idx" # 6077 "|\t$dst, $src$idx}", "", []>, 6078 Sched<[WriteV]> { 6079 bits<5> dst; 6080 bits<5> src; 6081 let Inst{31-21} = 0b01011110000; 6082 let Inst{15-10} = 0b000001; 6083 let Inst{9-5} = src; 6084 let Inst{4-0} = dst; 6085} 6086 6087class SIMDScalarCPYAlias<string asm, string size, Instruction inst, 6088 RegisterClass regtype, RegisterOperand vectype, Operand idxtype> 6089 : InstAlias<asm # "{\t$dst, $src" # size # "$index" # 6090 # "|\t$dst, $src$index}", 6091 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>; 6092 6093 6094multiclass SIMDScalarCPY<string asm> { 6095 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> { 6096 bits<4> idx; 6097 let Inst{20-17} = idx; 6098 let Inst{16} = 1; 6099 } 6100 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> { 6101 bits<3> idx; 6102 let Inst{20-18} = idx; 6103 let Inst{17-16} = 0b10; 6104 } 6105 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> { 6106 bits<2> idx; 6107 let Inst{20-19} = idx; 6108 let Inst{18-16} = 0b100; 6109 } 6110 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> { 6111 bits<1> idx; 6112 let Inst{20} = idx; 6113 let Inst{19-16} = 0b1000; 6114 } 6115 6116 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src), 6117 VectorIndexD:$idx)))), 6118 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>; 6119 6120 // 'DUP' mnemonic aliases. 6121 def : SIMDScalarCPYAlias<"dup", ".b", 6122 !cast<Instruction>(NAME#"i8"), 6123 FPR8, V128, VectorIndexB>; 6124 def : SIMDScalarCPYAlias<"dup", ".h", 6125 !cast<Instruction>(NAME#"i16"), 6126 FPR16, V128, VectorIndexH>; 6127 def : SIMDScalarCPYAlias<"dup", ".s", 6128 !cast<Instruction>(NAME#"i32"), 6129 FPR32, V128, VectorIndexS>; 6130 def : SIMDScalarCPYAlias<"dup", ".d", 6131 !cast<Instruction>(NAME#"i64"), 6132 FPR64, V128, VectorIndexD>; 6133} 6134 6135//---------------------------------------------------------------------------- 6136// AdvSIMD modified immediate instructions 6137//---------------------------------------------------------------------------- 6138 6139class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops, 6140 string asm, string op_string, 6141 string cstr, list<dag> pattern> 6142 : I<oops, iops, asm, op_string, cstr, pattern>, 6143 Sched<[WriteV]> { 6144 bits<5> Rd; 6145 bits<8> imm8; 6146 let Inst{31} = 0; 6147 let Inst{30} = Q; 6148 let Inst{29} = op; 6149 let Inst{28-19} = 0b0111100000; 6150 let Inst{18-16} = imm8{7-5}; 6151 let Inst{11-10} = 0b01; 6152 let Inst{9-5} = imm8{4-0}; 6153 let Inst{4-0} = Rd; 6154} 6155 6156class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype, 6157 Operand immtype, dag opt_shift_iop, 6158 string opt_shift, string asm, string kind, 6159 list<dag> pattern> 6160 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd), 6161 !con((ins immtype:$imm8), opt_shift_iop), asm, 6162 "{\t$Rd" # kind # ", $imm8" # opt_shift # 6163 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 6164 "", pattern> { 6165 let DecoderMethod = "DecodeModImmInstruction"; 6166} 6167 6168class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype, 6169 Operand immtype, dag opt_shift_iop, 6170 string opt_shift, string asm, string kind, 6171 list<dag> pattern> 6172 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst), 6173 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop), 6174 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift # 6175 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}", 6176 "$Rd = $dst", pattern> { 6177 let DecoderMethod = "DecodeModImmTiedInstruction"; 6178} 6179 6180class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12, 6181 RegisterOperand vectype, string asm, 6182 string kind, list<dag> pattern> 6183 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255, 6184 (ins logical_vec_shift:$shift), 6185 "$shift", asm, kind, pattern> { 6186 bits<2> shift; 6187 let Inst{15} = b15_b12{1}; 6188 let Inst{14-13} = shift; 6189 let Inst{12} = b15_b12{0}; 6190} 6191 6192class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12, 6193 RegisterOperand vectype, string asm, 6194 string kind, list<dag> pattern> 6195 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 6196 (ins logical_vec_shift:$shift), 6197 "$shift", asm, kind, pattern> { 6198 bits<2> shift; 6199 let Inst{15} = b15_b12{1}; 6200 let Inst{14-13} = shift; 6201 let Inst{12} = b15_b12{0}; 6202} 6203 6204 6205class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12, 6206 RegisterOperand vectype, string asm, 6207 string kind, list<dag> pattern> 6208 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255, 6209 (ins logical_vec_hw_shift:$shift), 6210 "$shift", asm, kind, pattern> { 6211 bits<2> shift; 6212 let Inst{15} = b15_b12{1}; 6213 let Inst{14} = 0; 6214 let Inst{13} = shift{0}; 6215 let Inst{12} = b15_b12{0}; 6216} 6217 6218class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12, 6219 RegisterOperand vectype, string asm, 6220 string kind, list<dag> pattern> 6221 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255, 6222 (ins logical_vec_hw_shift:$shift), 6223 "$shift", asm, kind, pattern> { 6224 bits<2> shift; 6225 let Inst{15} = b15_b12{1}; 6226 let Inst{14} = 0; 6227 let Inst{13} = shift{0}; 6228 let Inst{12} = b15_b12{0}; 6229} 6230 6231multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode, 6232 string asm> { 6233 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64, 6234 asm, ".4h", []>; 6235 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128, 6236 asm, ".8h", []>; 6237 6238 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64, 6239 asm, ".2s", []>; 6240 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128, 6241 asm, ".4s", []>; 6242} 6243 6244multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode, 6245 bits<2> w_cmode, string asm, 6246 SDNode OpNode> { 6247 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64, 6248 asm, ".4h", 6249 [(set (v4i16 V64:$dst), (OpNode V64:$Rd, 6250 imm0_255:$imm8, 6251 (i32 imm:$shift)))]>; 6252 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128, 6253 asm, ".8h", 6254 [(set (v8i16 V128:$dst), (OpNode V128:$Rd, 6255 imm0_255:$imm8, 6256 (i32 imm:$shift)))]>; 6257 6258 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64, 6259 asm, ".2s", 6260 [(set (v2i32 V64:$dst), (OpNode V64:$Rd, 6261 imm0_255:$imm8, 6262 (i32 imm:$shift)))]>; 6263 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128, 6264 asm, ".4s", 6265 [(set (v4i32 V128:$dst), (OpNode V128:$Rd, 6266 imm0_255:$imm8, 6267 (i32 imm:$shift)))]>; 6268} 6269 6270class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode, 6271 RegisterOperand vectype, string asm, 6272 string kind, list<dag> pattern> 6273 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255, 6274 (ins move_vec_shift:$shift), 6275 "$shift", asm, kind, pattern> { 6276 bits<1> shift; 6277 let Inst{15-13} = cmode{3-1}; 6278 let Inst{12} = shift; 6279} 6280 6281class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode, 6282 RegisterOperand vectype, 6283 Operand imm_type, string asm, 6284 string kind, list<dag> pattern> 6285 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "", 6286 asm, kind, pattern> { 6287 let Inst{15-12} = cmode; 6288} 6289 6290class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm, 6291 list<dag> pattern> 6292 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm, 6293 "\t$Rd, $imm8", "", pattern> { 6294 let Inst{15-12} = cmode; 6295 let DecoderMethod = "DecodeModImmInstruction"; 6296} 6297 6298//---------------------------------------------------------------------------- 6299// AdvSIMD indexed element 6300//---------------------------------------------------------------------------- 6301 6302let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6303class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 6304 RegisterOperand dst_reg, RegisterOperand lhs_reg, 6305 RegisterOperand rhs_reg, Operand vec_idx, string asm, 6306 string apple_kind, string dst_kind, string lhs_kind, 6307 string rhs_kind, list<dag> pattern> 6308 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), 6309 asm, 6310 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 6311 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>, 6312 Sched<[WriteV]> { 6313 bits<5> Rd; 6314 bits<5> Rn; 6315 bits<5> Rm; 6316 6317 let Inst{31} = 0; 6318 let Inst{30} = Q; 6319 let Inst{29} = U; 6320 let Inst{28} = Scalar; 6321 let Inst{27-24} = 0b1111; 6322 let Inst{23-22} = size; 6323 // Bit 21 must be set by the derived class. 6324 let Inst{20-16} = Rm; 6325 let Inst{15-12} = opc; 6326 // Bit 11 must be set by the derived class. 6327 let Inst{10} = 0; 6328 let Inst{9-5} = Rn; 6329 let Inst{4-0} = Rd; 6330} 6331 6332let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 6333class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc, 6334 RegisterOperand dst_reg, RegisterOperand lhs_reg, 6335 RegisterOperand rhs_reg, Operand vec_idx, string asm, 6336 string apple_kind, string dst_kind, string lhs_kind, 6337 string rhs_kind, list<dag> pattern> 6338 : I<(outs dst_reg:$dst), 6339 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm, 6340 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" # 6341 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>, 6342 Sched<[WriteV]> { 6343 bits<5> Rd; 6344 bits<5> Rn; 6345 bits<5> Rm; 6346 6347 let Inst{31} = 0; 6348 let Inst{30} = Q; 6349 let Inst{29} = U; 6350 let Inst{28} = Scalar; 6351 let Inst{27-24} = 0b1111; 6352 let Inst{23-22} = size; 6353 // Bit 21 must be set by the derived class. 6354 let Inst{20-16} = Rm; 6355 let Inst{15-12} = opc; 6356 // Bit 11 must be set by the derived class. 6357 let Inst{10} = 0; 6358 let Inst{9-5} = Rn; 6359 let Inst{4-0} = Rd; 6360} 6361 6362multiclass SIMDFPIndexedSD<bit U, bits<4> opc, string asm, 6363 SDPatternOperator OpNode> { 6364 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6365 V64, V64, 6366 V128, VectorIndexS, 6367 asm, ".2s", ".2s", ".2s", ".s", 6368 [(set (v2f32 V64:$Rd), 6369 (OpNode (v2f32 V64:$Rn), 6370 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 6371 bits<2> idx; 6372 let Inst{11} = idx{1}; 6373 let Inst{21} = idx{0}; 6374 } 6375 6376 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6377 V128, V128, 6378 V128, VectorIndexS, 6379 asm, ".4s", ".4s", ".4s", ".s", 6380 [(set (v4f32 V128:$Rd), 6381 (OpNode (v4f32 V128:$Rn), 6382 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> { 6383 bits<2> idx; 6384 let Inst{11} = idx{1}; 6385 let Inst{21} = idx{0}; 6386 } 6387 6388 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc, 6389 V128, V128, 6390 V128, VectorIndexD, 6391 asm, ".2d", ".2d", ".2d", ".d", 6392 [(set (v2f64 V128:$Rd), 6393 (OpNode (v2f64 V128:$Rn), 6394 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> { 6395 bits<1> idx; 6396 let Inst{11} = idx{0}; 6397 let Inst{21} = 0; 6398 } 6399 6400 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 6401 FPR32Op, FPR32Op, V128, VectorIndexS, 6402 asm, ".s", "", "", ".s", 6403 [(set (f32 FPR32Op:$Rd), 6404 (OpNode (f32 FPR32Op:$Rn), 6405 (f32 (vector_extract (v4f32 V128:$Rm), 6406 VectorIndexS:$idx))))]> { 6407 bits<2> idx; 6408 let Inst{11} = idx{1}; 6409 let Inst{21} = idx{0}; 6410 } 6411 6412 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc, 6413 FPR64Op, FPR64Op, V128, VectorIndexD, 6414 asm, ".d", "", "", ".d", 6415 [(set (f64 FPR64Op:$Rd), 6416 (OpNode (f64 FPR64Op:$Rn), 6417 (f64 (vector_extract (v2f64 V128:$Rm), 6418 VectorIndexD:$idx))))]> { 6419 bits<1> idx; 6420 let Inst{11} = idx{0}; 6421 let Inst{21} = 0; 6422 } 6423} 6424 6425multiclass SIMDFPIndexedSDTiedPatterns<string INST, SDPatternOperator OpNode> { 6426 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar. 6427 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 6428 (AArch64duplane32 (v4f32 V128:$Rm), 6429 VectorIndexS:$idx))), 6430 (!cast<Instruction>(INST # v2i32_indexed) 6431 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6432 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), 6433 (AArch64dup (f32 FPR32Op:$Rm)))), 6434 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn, 6435 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 6436 6437 6438 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar. 6439 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 6440 (AArch64duplane32 (v4f32 V128:$Rm), 6441 VectorIndexS:$idx))), 6442 (!cast<Instruction>(INST # "v4i32_indexed") 6443 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6444 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), 6445 (AArch64dup (f32 FPR32Op:$Rm)))), 6446 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn, 6447 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>; 6448 6449 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar. 6450 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 6451 (AArch64duplane64 (v2f64 V128:$Rm), 6452 VectorIndexD:$idx))), 6453 (!cast<Instruction>(INST # "v2i64_indexed") 6454 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>; 6455 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), 6456 (AArch64dup (f64 FPR64Op:$Rm)))), 6457 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn, 6458 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>; 6459 6460 // 2 variants for 32-bit scalar version: extract from .2s or from .4s 6461 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 6462 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))), 6463 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 6464 V128:$Rm, VectorIndexS:$idx)>; 6465 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn), 6466 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))), 6467 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn, 6468 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>; 6469 6470 // 1 variant for 64-bit scalar version: extract from .1d or from .2d 6471 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn), 6472 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))), 6473 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn, 6474 V128:$Rm, VectorIndexD:$idx)>; 6475} 6476 6477multiclass SIMDFPIndexedSDTied<bit U, bits<4> opc, string asm> { 6478 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64, 6479 V128, VectorIndexS, 6480 asm, ".2s", ".2s", ".2s", ".s", []> { 6481 bits<2> idx; 6482 let Inst{11} = idx{1}; 6483 let Inst{21} = idx{0}; 6484 } 6485 6486 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 6487 V128, V128, 6488 V128, VectorIndexS, 6489 asm, ".4s", ".4s", ".4s", ".s", []> { 6490 bits<2> idx; 6491 let Inst{11} = idx{1}; 6492 let Inst{21} = idx{0}; 6493 } 6494 6495 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc, 6496 V128, V128, 6497 V128, VectorIndexD, 6498 asm, ".2d", ".2d", ".2d", ".d", []> { 6499 bits<1> idx; 6500 let Inst{11} = idx{0}; 6501 let Inst{21} = 0; 6502 } 6503 6504 6505 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 6506 FPR32Op, FPR32Op, V128, VectorIndexS, 6507 asm, ".s", "", "", ".s", []> { 6508 bits<2> idx; 6509 let Inst{11} = idx{1}; 6510 let Inst{21} = idx{0}; 6511 } 6512 6513 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc, 6514 FPR64Op, FPR64Op, V128, VectorIndexD, 6515 asm, ".d", "", "", ".d", []> { 6516 bits<1> idx; 6517 let Inst{11} = idx{0}; 6518 let Inst{21} = 0; 6519 } 6520} 6521 6522multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm, 6523 SDPatternOperator OpNode> { 6524 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64, 6525 V128_lo, VectorIndexH, 6526 asm, ".4h", ".4h", ".4h", ".h", 6527 [(set (v4i16 V64:$Rd), 6528 (OpNode (v4i16 V64:$Rn), 6529 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6530 bits<3> idx; 6531 let Inst{11} = idx{2}; 6532 let Inst{21} = idx{1}; 6533 let Inst{20} = idx{0}; 6534 } 6535 6536 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 6537 V128, V128, 6538 V128_lo, VectorIndexH, 6539 asm, ".8h", ".8h", ".8h", ".h", 6540 [(set (v8i16 V128:$Rd), 6541 (OpNode (v8i16 V128:$Rn), 6542 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6543 bits<3> idx; 6544 let Inst{11} = idx{2}; 6545 let Inst{21} = idx{1}; 6546 let Inst{20} = idx{0}; 6547 } 6548 6549 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6550 V64, V64, 6551 V128, VectorIndexS, 6552 asm, ".2s", ".2s", ".2s", ".s", 6553 [(set (v2i32 V64:$Rd), 6554 (OpNode (v2i32 V64:$Rn), 6555 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6556 bits<2> idx; 6557 let Inst{11} = idx{1}; 6558 let Inst{21} = idx{0}; 6559 } 6560 6561 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6562 V128, V128, 6563 V128, VectorIndexS, 6564 asm, ".4s", ".4s", ".4s", ".s", 6565 [(set (v4i32 V128:$Rd), 6566 (OpNode (v4i32 V128:$Rn), 6567 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6568 bits<2> idx; 6569 let Inst{11} = idx{1}; 6570 let Inst{21} = idx{0}; 6571 } 6572 6573 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 6574 FPR16Op, FPR16Op, V128_lo, VectorIndexH, 6575 asm, ".h", "", "", ".h", []> { 6576 bits<3> idx; 6577 let Inst{11} = idx{2}; 6578 let Inst{21} = idx{1}; 6579 let Inst{20} = idx{0}; 6580 } 6581 6582 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 6583 FPR32Op, FPR32Op, V128, VectorIndexS, 6584 asm, ".s", "", "", ".s", 6585 [(set (i32 FPR32Op:$Rd), 6586 (OpNode FPR32Op:$Rn, 6587 (i32 (vector_extract (v4i32 V128:$Rm), 6588 VectorIndexS:$idx))))]> { 6589 bits<2> idx; 6590 let Inst{11} = idx{1}; 6591 let Inst{21} = idx{0}; 6592 } 6593} 6594 6595multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm, 6596 SDPatternOperator OpNode> { 6597 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 6598 V64, V64, 6599 V128_lo, VectorIndexH, 6600 asm, ".4h", ".4h", ".4h", ".h", 6601 [(set (v4i16 V64:$Rd), 6602 (OpNode (v4i16 V64:$Rn), 6603 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6604 bits<3> idx; 6605 let Inst{11} = idx{2}; 6606 let Inst{21} = idx{1}; 6607 let Inst{20} = idx{0}; 6608 } 6609 6610 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 6611 V128, V128, 6612 V128_lo, VectorIndexH, 6613 asm, ".8h", ".8h", ".8h", ".h", 6614 [(set (v8i16 V128:$Rd), 6615 (OpNode (v8i16 V128:$Rn), 6616 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6617 bits<3> idx; 6618 let Inst{11} = idx{2}; 6619 let Inst{21} = idx{1}; 6620 let Inst{20} = idx{0}; 6621 } 6622 6623 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6624 V64, V64, 6625 V128, VectorIndexS, 6626 asm, ".2s", ".2s", ".2s", ".s", 6627 [(set (v2i32 V64:$Rd), 6628 (OpNode (v2i32 V64:$Rn), 6629 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6630 bits<2> idx; 6631 let Inst{11} = idx{1}; 6632 let Inst{21} = idx{0}; 6633 } 6634 6635 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6636 V128, V128, 6637 V128, VectorIndexS, 6638 asm, ".4s", ".4s", ".4s", ".s", 6639 [(set (v4i32 V128:$Rd), 6640 (OpNode (v4i32 V128:$Rn), 6641 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6642 bits<2> idx; 6643 let Inst{11} = idx{1}; 6644 let Inst{21} = idx{0}; 6645 } 6646} 6647 6648multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm, 6649 SDPatternOperator OpNode> { 6650 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64, 6651 V128_lo, VectorIndexH, 6652 asm, ".4h", ".4h", ".4h", ".h", 6653 [(set (v4i16 V64:$dst), 6654 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn), 6655 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6656 bits<3> idx; 6657 let Inst{11} = idx{2}; 6658 let Inst{21} = idx{1}; 6659 let Inst{20} = idx{0}; 6660 } 6661 6662 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 6663 V128, V128, 6664 V128_lo, VectorIndexH, 6665 asm, ".8h", ".8h", ".8h", ".h", 6666 [(set (v8i16 V128:$dst), 6667 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 6668 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6669 bits<3> idx; 6670 let Inst{11} = idx{2}; 6671 let Inst{21} = idx{1}; 6672 let Inst{20} = idx{0}; 6673 } 6674 6675 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 6676 V64, V64, 6677 V128, VectorIndexS, 6678 asm, ".2s", ".2s", ".2s", ".s", 6679 [(set (v2i32 V64:$dst), 6680 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 6681 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6682 bits<2> idx; 6683 let Inst{11} = idx{1}; 6684 let Inst{21} = idx{0}; 6685 } 6686 6687 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 6688 V128, V128, 6689 V128, VectorIndexS, 6690 asm, ".4s", ".4s", ".4s", ".s", 6691 [(set (v4i32 V128:$dst), 6692 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 6693 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6694 bits<2> idx; 6695 let Inst{11} = idx{1}; 6696 let Inst{21} = idx{0}; 6697 } 6698} 6699 6700multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm, 6701 SDPatternOperator OpNode> { 6702 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 6703 V128, V64, 6704 V128_lo, VectorIndexH, 6705 asm, ".4s", ".4s", ".4h", ".h", 6706 [(set (v4i32 V128:$Rd), 6707 (OpNode (v4i16 V64:$Rn), 6708 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6709 bits<3> idx; 6710 let Inst{11} = idx{2}; 6711 let Inst{21} = idx{1}; 6712 let Inst{20} = idx{0}; 6713 } 6714 6715 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 6716 V128, V128, 6717 V128_lo, VectorIndexH, 6718 asm#"2", ".4s", ".4s", ".8h", ".h", 6719 [(set (v4i32 V128:$Rd), 6720 (OpNode (extract_high_v8i16 V128:$Rn), 6721 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 6722 VectorIndexH:$idx))))]> { 6723 6724 bits<3> idx; 6725 let Inst{11} = idx{2}; 6726 let Inst{21} = idx{1}; 6727 let Inst{20} = idx{0}; 6728 } 6729 6730 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6731 V128, V64, 6732 V128, VectorIndexS, 6733 asm, ".2d", ".2d", ".2s", ".s", 6734 [(set (v2i64 V128:$Rd), 6735 (OpNode (v2i32 V64:$Rn), 6736 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6737 bits<2> idx; 6738 let Inst{11} = idx{1}; 6739 let Inst{21} = idx{0}; 6740 } 6741 6742 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6743 V128, V128, 6744 V128, VectorIndexS, 6745 asm#"2", ".2d", ".2d", ".4s", ".s", 6746 [(set (v2i64 V128:$Rd), 6747 (OpNode (extract_high_v4i32 V128:$Rn), 6748 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 6749 VectorIndexS:$idx))))]> { 6750 bits<2> idx; 6751 let Inst{11} = idx{1}; 6752 let Inst{21} = idx{0}; 6753 } 6754 6755 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc, 6756 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 6757 asm, ".h", "", "", ".h", []> { 6758 bits<3> idx; 6759 let Inst{11} = idx{2}; 6760 let Inst{21} = idx{1}; 6761 let Inst{20} = idx{0}; 6762 } 6763 6764 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc, 6765 FPR64Op, FPR32Op, V128, VectorIndexS, 6766 asm, ".s", "", "", ".s", []> { 6767 bits<2> idx; 6768 let Inst{11} = idx{1}; 6769 let Inst{21} = idx{0}; 6770 } 6771} 6772 6773multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm, 6774 SDPatternOperator Accum> { 6775 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 6776 V128, V64, 6777 V128_lo, VectorIndexH, 6778 asm, ".4s", ".4s", ".4h", ".h", 6779 [(set (v4i32 V128:$dst), 6780 (Accum (v4i32 V128:$Rd), 6781 (v4i32 (int_aarch64_neon_sqdmull 6782 (v4i16 V64:$Rn), 6783 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 6784 VectorIndexH:$idx))))))]> { 6785 bits<3> idx; 6786 let Inst{11} = idx{2}; 6787 let Inst{21} = idx{1}; 6788 let Inst{20} = idx{0}; 6789 } 6790 6791 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an 6792 // intermediate EXTRACT_SUBREG would be untyped. 6793 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd), 6794 (i32 (vector_extract (v4i32 6795 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn), 6796 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 6797 VectorIndexH:$idx)))), 6798 (i64 0))))), 6799 (EXTRACT_SUBREG 6800 (!cast<Instruction>(NAME # v4i16_indexed) 6801 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn, 6802 V128_lo:$Rm, VectorIndexH:$idx), 6803 ssub)>; 6804 6805 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 6806 V128, V128, 6807 V128_lo, VectorIndexH, 6808 asm#"2", ".4s", ".4s", ".8h", ".h", 6809 [(set (v4i32 V128:$dst), 6810 (Accum (v4i32 V128:$Rd), 6811 (v4i32 (int_aarch64_neon_sqdmull 6812 (extract_high_v8i16 V128:$Rn), 6813 (extract_high_v8i16 6814 (AArch64duplane16 (v8i16 V128_lo:$Rm), 6815 VectorIndexH:$idx))))))]> { 6816 bits<3> idx; 6817 let Inst{11} = idx{2}; 6818 let Inst{21} = idx{1}; 6819 let Inst{20} = idx{0}; 6820 } 6821 6822 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 6823 V128, V64, 6824 V128, VectorIndexS, 6825 asm, ".2d", ".2d", ".2s", ".s", 6826 [(set (v2i64 V128:$dst), 6827 (Accum (v2i64 V128:$Rd), 6828 (v2i64 (int_aarch64_neon_sqdmull 6829 (v2i32 V64:$Rn), 6830 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), 6831 VectorIndexS:$idx))))))]> { 6832 bits<2> idx; 6833 let Inst{11} = idx{1}; 6834 let Inst{21} = idx{0}; 6835 } 6836 6837 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 6838 V128, V128, 6839 V128, VectorIndexS, 6840 asm#"2", ".2d", ".2d", ".4s", ".s", 6841 [(set (v2i64 V128:$dst), 6842 (Accum (v2i64 V128:$Rd), 6843 (v2i64 (int_aarch64_neon_sqdmull 6844 (extract_high_v4i32 V128:$Rn), 6845 (extract_high_v4i32 6846 (AArch64duplane32 (v4i32 V128:$Rm), 6847 VectorIndexS:$idx))))))]> { 6848 bits<2> idx; 6849 let Inst{11} = idx{1}; 6850 let Inst{21} = idx{0}; 6851 } 6852 6853 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc, 6854 FPR32Op, FPR16Op, V128_lo, VectorIndexH, 6855 asm, ".h", "", "", ".h", []> { 6856 bits<3> idx; 6857 let Inst{11} = idx{2}; 6858 let Inst{21} = idx{1}; 6859 let Inst{20} = idx{0}; 6860 } 6861 6862 6863 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc, 6864 FPR64Op, FPR32Op, V128, VectorIndexS, 6865 asm, ".s", "", "", ".s", 6866 [(set (i64 FPR64Op:$dst), 6867 (Accum (i64 FPR64Op:$Rd), 6868 (i64 (int_aarch64_neon_sqdmulls_scalar 6869 (i32 FPR32Op:$Rn), 6870 (i32 (vector_extract (v4i32 V128:$Rm), 6871 VectorIndexS:$idx))))))]> { 6872 6873 bits<2> idx; 6874 let Inst{11} = idx{1}; 6875 let Inst{21} = idx{0}; 6876 } 6877} 6878 6879multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm, 6880 SDPatternOperator OpNode> { 6881 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6882 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, 6883 V128, V64, 6884 V128_lo, VectorIndexH, 6885 asm, ".4s", ".4s", ".4h", ".h", 6886 [(set (v4i32 V128:$Rd), 6887 (OpNode (v4i16 V64:$Rn), 6888 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6889 bits<3> idx; 6890 let Inst{11} = idx{2}; 6891 let Inst{21} = idx{1}; 6892 let Inst{20} = idx{0}; 6893 } 6894 6895 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc, 6896 V128, V128, 6897 V128_lo, VectorIndexH, 6898 asm#"2", ".4s", ".4s", ".8h", ".h", 6899 [(set (v4i32 V128:$Rd), 6900 (OpNode (extract_high_v8i16 V128:$Rn), 6901 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 6902 VectorIndexH:$idx))))]> { 6903 6904 bits<3> idx; 6905 let Inst{11} = idx{2}; 6906 let Inst{21} = idx{1}; 6907 let Inst{20} = idx{0}; 6908 } 6909 6910 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc, 6911 V128, V64, 6912 V128, VectorIndexS, 6913 asm, ".2d", ".2d", ".2s", ".s", 6914 [(set (v2i64 V128:$Rd), 6915 (OpNode (v2i32 V64:$Rn), 6916 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6917 bits<2> idx; 6918 let Inst{11} = idx{1}; 6919 let Inst{21} = idx{0}; 6920 } 6921 6922 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc, 6923 V128, V128, 6924 V128, VectorIndexS, 6925 asm#"2", ".2d", ".2d", ".4s", ".s", 6926 [(set (v2i64 V128:$Rd), 6927 (OpNode (extract_high_v4i32 V128:$Rn), 6928 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 6929 VectorIndexS:$idx))))]> { 6930 bits<2> idx; 6931 let Inst{11} = idx{1}; 6932 let Inst{21} = idx{0}; 6933 } 6934 } 6935} 6936 6937multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm, 6938 SDPatternOperator OpNode> { 6939 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6940 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, 6941 V128, V64, 6942 V128_lo, VectorIndexH, 6943 asm, ".4s", ".4s", ".4h", ".h", 6944 [(set (v4i32 V128:$dst), 6945 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), 6946 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> { 6947 bits<3> idx; 6948 let Inst{11} = idx{2}; 6949 let Inst{21} = idx{1}; 6950 let Inst{20} = idx{0}; 6951 } 6952 6953 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc, 6954 V128, V128, 6955 V128_lo, VectorIndexH, 6956 asm#"2", ".4s", ".4s", ".8h", ".h", 6957 [(set (v4i32 V128:$dst), 6958 (OpNode (v4i32 V128:$Rd), 6959 (extract_high_v8i16 V128:$Rn), 6960 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), 6961 VectorIndexH:$idx))))]> { 6962 bits<3> idx; 6963 let Inst{11} = idx{2}; 6964 let Inst{21} = idx{1}; 6965 let Inst{20} = idx{0}; 6966 } 6967 6968 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, 6969 V128, V64, 6970 V128, VectorIndexS, 6971 asm, ".2d", ".2d", ".2s", ".s", 6972 [(set (v2i64 V128:$dst), 6973 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), 6974 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> { 6975 bits<2> idx; 6976 let Inst{11} = idx{1}; 6977 let Inst{21} = idx{0}; 6978 } 6979 6980 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc, 6981 V128, V128, 6982 V128, VectorIndexS, 6983 asm#"2", ".2d", ".2d", ".4s", ".s", 6984 [(set (v2i64 V128:$dst), 6985 (OpNode (v2i64 V128:$Rd), 6986 (extract_high_v4i32 V128:$Rn), 6987 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm), 6988 VectorIndexS:$idx))))]> { 6989 bits<2> idx; 6990 let Inst{11} = idx{1}; 6991 let Inst{21} = idx{0}; 6992 } 6993 } 6994} 6995 6996//---------------------------------------------------------------------------- 6997// AdvSIMD scalar shift by immediate 6998//---------------------------------------------------------------------------- 6999 7000let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7001class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm, 7002 RegisterClass regtype1, RegisterClass regtype2, 7003 Operand immtype, string asm, list<dag> pattern> 7004 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm), 7005 asm, "\t$Rd, $Rn, $imm", "", pattern>, 7006 Sched<[WriteV]> { 7007 bits<5> Rd; 7008 bits<5> Rn; 7009 bits<7> imm; 7010 let Inst{31-30} = 0b01; 7011 let Inst{29} = U; 7012 let Inst{28-23} = 0b111110; 7013 let Inst{22-16} = fixed_imm; 7014 let Inst{15-11} = opc; 7015 let Inst{10} = 1; 7016 let Inst{9-5} = Rn; 7017 let Inst{4-0} = Rd; 7018} 7019 7020let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7021class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm, 7022 RegisterClass regtype1, RegisterClass regtype2, 7023 Operand immtype, string asm, list<dag> pattern> 7024 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm), 7025 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>, 7026 Sched<[WriteV]> { 7027 bits<5> Rd; 7028 bits<5> Rn; 7029 bits<7> imm; 7030 let Inst{31-30} = 0b01; 7031 let Inst{29} = U; 7032 let Inst{28-23} = 0b111110; 7033 let Inst{22-16} = fixed_imm; 7034 let Inst{15-11} = opc; 7035 let Inst{10} = 1; 7036 let Inst{9-5} = Rn; 7037 let Inst{4-0} = Rd; 7038} 7039 7040 7041multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> { 7042 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7043 FPR32, FPR32, vecshiftR32, asm, []> { 7044 let Inst{20-16} = imm{4-0}; 7045 } 7046 7047 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7048 FPR64, FPR64, vecshiftR64, asm, []> { 7049 let Inst{21-16} = imm{5-0}; 7050 } 7051} 7052 7053multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm, 7054 SDPatternOperator OpNode> { 7055 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7056 FPR64, FPR64, vecshiftR64, asm, 7057 [(set (i64 FPR64:$Rd), 7058 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> { 7059 let Inst{21-16} = imm{5-0}; 7060 } 7061 7062 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))), 7063 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>; 7064} 7065 7066multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm, 7067 SDPatternOperator OpNode = null_frag> { 7068 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 7069 FPR64, FPR64, vecshiftR64, asm, 7070 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn), 7071 (i32 vecshiftR64:$imm)))]> { 7072 let Inst{21-16} = imm{5-0}; 7073 } 7074 7075 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn), 7076 (i32 vecshiftR64:$imm))), 7077 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn, 7078 vecshiftR64:$imm)>; 7079} 7080 7081multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm, 7082 SDPatternOperator OpNode> { 7083 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7084 FPR64, FPR64, vecshiftL64, asm, 7085 [(set (v1i64 FPR64:$Rd), 7086 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 7087 let Inst{21-16} = imm{5-0}; 7088 } 7089} 7090 7091let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7092multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> { 7093 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?}, 7094 FPR64, FPR64, vecshiftL64, asm, []> { 7095 let Inst{21-16} = imm{5-0}; 7096 } 7097} 7098 7099let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7100multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm, 7101 SDPatternOperator OpNode = null_frag> { 7102 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7103 FPR8, FPR16, vecshiftR8, asm, []> { 7104 let Inst{18-16} = imm{2-0}; 7105 } 7106 7107 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7108 FPR16, FPR32, vecshiftR16, asm, []> { 7109 let Inst{19-16} = imm{3-0}; 7110 } 7111 7112 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7113 FPR32, FPR64, vecshiftR32, asm, 7114 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> { 7115 let Inst{20-16} = imm{4-0}; 7116 } 7117} 7118 7119multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm, 7120 SDPatternOperator OpNode> { 7121 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7122 FPR8, FPR8, vecshiftL8, asm, []> { 7123 let Inst{18-16} = imm{2-0}; 7124 } 7125 7126 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7127 FPR16, FPR16, vecshiftL16, asm, []> { 7128 let Inst{19-16} = imm{3-0}; 7129 } 7130 7131 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7132 FPR32, FPR32, vecshiftL32, asm, 7133 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> { 7134 let Inst{20-16} = imm{4-0}; 7135 } 7136 7137 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7138 FPR64, FPR64, vecshiftL64, asm, 7139 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> { 7140 let Inst{21-16} = imm{5-0}; 7141 } 7142 7143 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))), 7144 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>; 7145} 7146 7147multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> { 7148 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?}, 7149 FPR8, FPR8, vecshiftR8, asm, []> { 7150 let Inst{18-16} = imm{2-0}; 7151 } 7152 7153 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?}, 7154 FPR16, FPR16, vecshiftR16, asm, []> { 7155 let Inst{19-16} = imm{3-0}; 7156 } 7157 7158 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?}, 7159 FPR32, FPR32, vecshiftR32, asm, []> { 7160 let Inst{20-16} = imm{4-0}; 7161 } 7162 7163 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?}, 7164 FPR64, FPR64, vecshiftR64, asm, []> { 7165 let Inst{21-16} = imm{5-0}; 7166 } 7167} 7168 7169//---------------------------------------------------------------------------- 7170// AdvSIMD vector x indexed element 7171//---------------------------------------------------------------------------- 7172 7173let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7174class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 7175 RegisterOperand dst_reg, RegisterOperand src_reg, 7176 Operand immtype, 7177 string asm, string dst_kind, string src_kind, 7178 list<dag> pattern> 7179 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm), 7180 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 7181 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>, 7182 Sched<[WriteV]> { 7183 bits<5> Rd; 7184 bits<5> Rn; 7185 let Inst{31} = 0; 7186 let Inst{30} = Q; 7187 let Inst{29} = U; 7188 let Inst{28-23} = 0b011110; 7189 let Inst{22-16} = fixed_imm; 7190 let Inst{15-11} = opc; 7191 let Inst{10} = 1; 7192 let Inst{9-5} = Rn; 7193 let Inst{4-0} = Rd; 7194} 7195 7196let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in 7197class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm, 7198 RegisterOperand vectype1, RegisterOperand vectype2, 7199 Operand immtype, 7200 string asm, string dst_kind, string src_kind, 7201 list<dag> pattern> 7202 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm), 7203 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" # 7204 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>, 7205 Sched<[WriteV]> { 7206 bits<5> Rd; 7207 bits<5> Rn; 7208 let Inst{31} = 0; 7209 let Inst{30} = Q; 7210 let Inst{29} = U; 7211 let Inst{28-23} = 0b011110; 7212 let Inst{22-16} = fixed_imm; 7213 let Inst{15-11} = opc; 7214 let Inst{10} = 1; 7215 let Inst{9-5} = Rn; 7216 let Inst{4-0} = Rd; 7217} 7218 7219multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm, 7220 Intrinsic OpNode> { 7221 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7222 V64, V64, vecshiftR32, 7223 asm, ".2s", ".2s", 7224 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> { 7225 bits<5> imm; 7226 let Inst{20-16} = imm; 7227 } 7228 7229 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7230 V128, V128, vecshiftR32, 7231 asm, ".4s", ".4s", 7232 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> { 7233 bits<5> imm; 7234 let Inst{20-16} = imm; 7235 } 7236 7237 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7238 V128, V128, vecshiftR64, 7239 asm, ".2d", ".2d", 7240 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> { 7241 bits<6> imm; 7242 let Inst{21-16} = imm; 7243 } 7244} 7245 7246multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm, 7247 Intrinsic OpNode> { 7248 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7249 V64, V64, vecshiftR32, 7250 asm, ".2s", ".2s", 7251 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> { 7252 bits<5> imm; 7253 let Inst{20-16} = imm; 7254 } 7255 7256 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7257 V128, V128, vecshiftR32, 7258 asm, ".4s", ".4s", 7259 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> { 7260 bits<5> imm; 7261 let Inst{20-16} = imm; 7262 } 7263 7264 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7265 V128, V128, vecshiftR64, 7266 asm, ".2d", ".2d", 7267 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> { 7268 bits<6> imm; 7269 let Inst{21-16} = imm; 7270 } 7271} 7272 7273multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm, 7274 SDPatternOperator OpNode> { 7275 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7276 V64, V128, vecshiftR16Narrow, 7277 asm, ".8b", ".8h", 7278 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> { 7279 bits<3> imm; 7280 let Inst{18-16} = imm; 7281 } 7282 7283 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 7284 V128, V128, vecshiftR16Narrow, 7285 asm#"2", ".16b", ".8h", []> { 7286 bits<3> imm; 7287 let Inst{18-16} = imm; 7288 let hasSideEffects = 0; 7289 } 7290 7291 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7292 V64, V128, vecshiftR32Narrow, 7293 asm, ".4h", ".4s", 7294 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> { 7295 bits<4> imm; 7296 let Inst{19-16} = imm; 7297 } 7298 7299 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 7300 V128, V128, vecshiftR32Narrow, 7301 asm#"2", ".8h", ".4s", []> { 7302 bits<4> imm; 7303 let Inst{19-16} = imm; 7304 let hasSideEffects = 0; 7305 } 7306 7307 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7308 V64, V128, vecshiftR64Narrow, 7309 asm, ".2s", ".2d", 7310 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> { 7311 bits<5> imm; 7312 let Inst{20-16} = imm; 7313 } 7314 7315 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 7316 V128, V128, vecshiftR64Narrow, 7317 asm#"2", ".4s", ".2d", []> { 7318 bits<5> imm; 7319 let Inst{20-16} = imm; 7320 let hasSideEffects = 0; 7321 } 7322 7323 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions 7324 // themselves, so put them here instead. 7325 7326 // Patterns involving what's effectively an insert high and a normal 7327 // intrinsic, represented by CONCAT_VECTORS. 7328 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn), 7329 vecshiftR16Narrow:$imm)), 7330 (!cast<Instruction>(NAME # "v16i8_shift") 7331 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7332 V128:$Rn, vecshiftR16Narrow:$imm)>; 7333 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), 7334 vecshiftR32Narrow:$imm)), 7335 (!cast<Instruction>(NAME # "v8i16_shift") 7336 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7337 V128:$Rn, vecshiftR32Narrow:$imm)>; 7338 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), 7339 vecshiftR64Narrow:$imm)), 7340 (!cast<Instruction>(NAME # "v4i32_shift") 7341 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), 7342 V128:$Rn, vecshiftR64Narrow:$imm)>; 7343} 7344 7345multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm, 7346 SDPatternOperator OpNode> { 7347 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7348 V64, V64, vecshiftL8, 7349 asm, ".8b", ".8b", 7350 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 7351 (i32 vecshiftL8:$imm)))]> { 7352 bits<3> imm; 7353 let Inst{18-16} = imm; 7354 } 7355 7356 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7357 V128, V128, vecshiftL8, 7358 asm, ".16b", ".16b", 7359 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 7360 (i32 vecshiftL8:$imm)))]> { 7361 bits<3> imm; 7362 let Inst{18-16} = imm; 7363 } 7364 7365 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7366 V64, V64, vecshiftL16, 7367 asm, ".4h", ".4h", 7368 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 7369 (i32 vecshiftL16:$imm)))]> { 7370 bits<4> imm; 7371 let Inst{19-16} = imm; 7372 } 7373 7374 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7375 V128, V128, vecshiftL16, 7376 asm, ".8h", ".8h", 7377 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7378 (i32 vecshiftL16:$imm)))]> { 7379 bits<4> imm; 7380 let Inst{19-16} = imm; 7381 } 7382 7383 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7384 V64, V64, vecshiftL32, 7385 asm, ".2s", ".2s", 7386 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 7387 (i32 vecshiftL32:$imm)))]> { 7388 bits<5> imm; 7389 let Inst{20-16} = imm; 7390 } 7391 7392 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7393 V128, V128, vecshiftL32, 7394 asm, ".4s", ".4s", 7395 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7396 (i32 vecshiftL32:$imm)))]> { 7397 bits<5> imm; 7398 let Inst{20-16} = imm; 7399 } 7400 7401 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7402 V128, V128, vecshiftL64, 7403 asm, ".2d", ".2d", 7404 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7405 (i32 vecshiftL64:$imm)))]> { 7406 bits<6> imm; 7407 let Inst{21-16} = imm; 7408 } 7409} 7410 7411multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm, 7412 SDPatternOperator OpNode> { 7413 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7414 V64, V64, vecshiftR8, 7415 asm, ".8b", ".8b", 7416 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), 7417 (i32 vecshiftR8:$imm)))]> { 7418 bits<3> imm; 7419 let Inst{18-16} = imm; 7420 } 7421 7422 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7423 V128, V128, vecshiftR8, 7424 asm, ".16b", ".16b", 7425 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), 7426 (i32 vecshiftR8:$imm)))]> { 7427 bits<3> imm; 7428 let Inst{18-16} = imm; 7429 } 7430 7431 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7432 V64, V64, vecshiftR16, 7433 asm, ".4h", ".4h", 7434 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), 7435 (i32 vecshiftR16:$imm)))]> { 7436 bits<4> imm; 7437 let Inst{19-16} = imm; 7438 } 7439 7440 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7441 V128, V128, vecshiftR16, 7442 asm, ".8h", ".8h", 7443 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), 7444 (i32 vecshiftR16:$imm)))]> { 7445 bits<4> imm; 7446 let Inst{19-16} = imm; 7447 } 7448 7449 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7450 V64, V64, vecshiftR32, 7451 asm, ".2s", ".2s", 7452 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), 7453 (i32 vecshiftR32:$imm)))]> { 7454 bits<5> imm; 7455 let Inst{20-16} = imm; 7456 } 7457 7458 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7459 V128, V128, vecshiftR32, 7460 asm, ".4s", ".4s", 7461 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), 7462 (i32 vecshiftR32:$imm)))]> { 7463 bits<5> imm; 7464 let Inst{20-16} = imm; 7465 } 7466 7467 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?}, 7468 V128, V128, vecshiftR64, 7469 asm, ".2d", ".2d", 7470 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), 7471 (i32 vecshiftR64:$imm)))]> { 7472 bits<6> imm; 7473 let Inst{21-16} = imm; 7474 } 7475} 7476 7477let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 7478multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm, 7479 SDPatternOperator OpNode = null_frag> { 7480 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 7481 V64, V64, vecshiftR8, asm, ".8b", ".8b", 7482 [(set (v8i8 V64:$dst), 7483 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 7484 (i32 vecshiftR8:$imm)))]> { 7485 bits<3> imm; 7486 let Inst{18-16} = imm; 7487 } 7488 7489 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 7490 V128, V128, vecshiftR8, asm, ".16b", ".16b", 7491 [(set (v16i8 V128:$dst), 7492 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 7493 (i32 vecshiftR8:$imm)))]> { 7494 bits<3> imm; 7495 let Inst{18-16} = imm; 7496 } 7497 7498 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 7499 V64, V64, vecshiftR16, asm, ".4h", ".4h", 7500 [(set (v4i16 V64:$dst), 7501 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 7502 (i32 vecshiftR16:$imm)))]> { 7503 bits<4> imm; 7504 let Inst{19-16} = imm; 7505 } 7506 7507 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 7508 V128, V128, vecshiftR16, asm, ".8h", ".8h", 7509 [(set (v8i16 V128:$dst), 7510 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 7511 (i32 vecshiftR16:$imm)))]> { 7512 bits<4> imm; 7513 let Inst{19-16} = imm; 7514 } 7515 7516 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 7517 V64, V64, vecshiftR32, asm, ".2s", ".2s", 7518 [(set (v2i32 V64:$dst), 7519 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 7520 (i32 vecshiftR32:$imm)))]> { 7521 bits<5> imm; 7522 let Inst{20-16} = imm; 7523 } 7524 7525 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 7526 V128, V128, vecshiftR32, asm, ".4s", ".4s", 7527 [(set (v4i32 V128:$dst), 7528 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 7529 (i32 vecshiftR32:$imm)))]> { 7530 bits<5> imm; 7531 let Inst{20-16} = imm; 7532 } 7533 7534 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 7535 V128, V128, vecshiftR64, 7536 asm, ".2d", ".2d", [(set (v2i64 V128:$dst), 7537 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 7538 (i32 vecshiftR64:$imm)))]> { 7539 bits<6> imm; 7540 let Inst{21-16} = imm; 7541 } 7542} 7543 7544multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm, 7545 SDPatternOperator OpNode = null_frag> { 7546 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?}, 7547 V64, V64, vecshiftL8, 7548 asm, ".8b", ".8b", 7549 [(set (v8i8 V64:$dst), 7550 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), 7551 (i32 vecshiftL8:$imm)))]> { 7552 bits<3> imm; 7553 let Inst{18-16} = imm; 7554 } 7555 7556 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?}, 7557 V128, V128, vecshiftL8, 7558 asm, ".16b", ".16b", 7559 [(set (v16i8 V128:$dst), 7560 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), 7561 (i32 vecshiftL8:$imm)))]> { 7562 bits<3> imm; 7563 let Inst{18-16} = imm; 7564 } 7565 7566 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?}, 7567 V64, V64, vecshiftL16, 7568 asm, ".4h", ".4h", 7569 [(set (v4i16 V64:$dst), 7570 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), 7571 (i32 vecshiftL16:$imm)))]> { 7572 bits<4> imm; 7573 let Inst{19-16} = imm; 7574 } 7575 7576 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?}, 7577 V128, V128, vecshiftL16, 7578 asm, ".8h", ".8h", 7579 [(set (v8i16 V128:$dst), 7580 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), 7581 (i32 vecshiftL16:$imm)))]> { 7582 bits<4> imm; 7583 let Inst{19-16} = imm; 7584 } 7585 7586 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?}, 7587 V64, V64, vecshiftL32, 7588 asm, ".2s", ".2s", 7589 [(set (v2i32 V64:$dst), 7590 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), 7591 (i32 vecshiftL32:$imm)))]> { 7592 bits<5> imm; 7593 let Inst{20-16} = imm; 7594 } 7595 7596 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?}, 7597 V128, V128, vecshiftL32, 7598 asm, ".4s", ".4s", 7599 [(set (v4i32 V128:$dst), 7600 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 7601 (i32 vecshiftL32:$imm)))]> { 7602 bits<5> imm; 7603 let Inst{20-16} = imm; 7604 } 7605 7606 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?}, 7607 V128, V128, vecshiftL64, 7608 asm, ".2d", ".2d", 7609 [(set (v2i64 V128:$dst), 7610 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn), 7611 (i32 vecshiftL64:$imm)))]> { 7612 bits<6> imm; 7613 let Inst{21-16} = imm; 7614 } 7615} 7616 7617multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm, 7618 SDPatternOperator OpNode> { 7619 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?}, 7620 V128, V64, vecshiftL8, asm, ".8h", ".8b", 7621 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> { 7622 bits<3> imm; 7623 let Inst{18-16} = imm; 7624 } 7625 7626 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?}, 7627 V128, V128, vecshiftL8, 7628 asm#"2", ".8h", ".16b", 7629 [(set (v8i16 V128:$Rd), 7630 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> { 7631 bits<3> imm; 7632 let Inst{18-16} = imm; 7633 } 7634 7635 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?}, 7636 V128, V64, vecshiftL16, asm, ".4s", ".4h", 7637 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> { 7638 bits<4> imm; 7639 let Inst{19-16} = imm; 7640 } 7641 7642 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?}, 7643 V128, V128, vecshiftL16, 7644 asm#"2", ".4s", ".8h", 7645 [(set (v4i32 V128:$Rd), 7646 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> { 7647 7648 bits<4> imm; 7649 let Inst{19-16} = imm; 7650 } 7651 7652 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?}, 7653 V128, V64, vecshiftL32, asm, ".2d", ".2s", 7654 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> { 7655 bits<5> imm; 7656 let Inst{20-16} = imm; 7657 } 7658 7659 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?}, 7660 V128, V128, vecshiftL32, 7661 asm#"2", ".2d", ".4s", 7662 [(set (v2i64 V128:$Rd), 7663 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> { 7664 bits<5> imm; 7665 let Inst{20-16} = imm; 7666 } 7667} 7668 7669 7670//--- 7671// Vector load/store 7672//--- 7673// SIMD ldX/stX no-index memory references don't allow the optional 7674// ", #0" constant and handle post-indexing explicitly, so we use 7675// a more specialized parse method for them. Otherwise, it's the same as 7676// the general GPR64sp handling. 7677 7678class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size, 7679 string asm, dag oops, dag iops, list<dag> pattern> 7680 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> { 7681 bits<5> Vt; 7682 bits<5> Rn; 7683 let Inst{31} = 0; 7684 let Inst{30} = Q; 7685 let Inst{29-23} = 0b0011000; 7686 let Inst{22} = L; 7687 let Inst{21-16} = 0b000000; 7688 let Inst{15-12} = opcode; 7689 let Inst{11-10} = size; 7690 let Inst{9-5} = Rn; 7691 let Inst{4-0} = Vt; 7692} 7693 7694class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size, 7695 string asm, dag oops, dag iops> 7696 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> { 7697 bits<5> Vt; 7698 bits<5> Rn; 7699 bits<5> Xm; 7700 let Inst{31} = 0; 7701 let Inst{30} = Q; 7702 let Inst{29-23} = 0b0011001; 7703 let Inst{22} = L; 7704 let Inst{21} = 0; 7705 let Inst{20-16} = Xm; 7706 let Inst{15-12} = opcode; 7707 let Inst{11-10} = size; 7708 let Inst{9-5} = Rn; 7709 let Inst{4-0} = Vt; 7710} 7711 7712// The immediate form of AdvSIMD post-indexed addressing is encoded with 7713// register post-index addressing from the zero register. 7714multiclass SIMDLdStAliases<string asm, string layout, string Count, 7715 int Offset, int Size> { 7716 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" 7717 // "ld1\t$Vt, [$Rn], #16" 7718 // may get mapped to 7719 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) 7720 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 7721 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 7722 GPR64sp:$Rn, 7723 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 7724 XZR), 1>; 7725 7726 // E.g. "ld1.8b { v0, v1 }, [x1], #16" 7727 // "ld1.8b\t$Vt, [$Rn], #16" 7728 // may get mapped to 7729 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) 7730 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 7731 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 7732 GPR64sp:$Rn, 7733 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 7734 XZR), 0>; 7735 7736 // E.g. "ld1.8b { v0, v1 }, [x1]" 7737 // "ld1\t$Vt, [$Rn]" 7738 // may get mapped to 7739 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) 7740 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 7741 (!cast<Instruction>(NAME # Count # "v" # layout) 7742 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 7743 GPR64sp:$Rn), 0>; 7744 7745 // E.g. "ld1.8b { v0, v1 }, [x1], x2" 7746 // "ld1\t$Vt, [$Rn], $Xm" 7747 // may get mapped to 7748 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) 7749 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 7750 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST") 7751 GPR64sp:$Rn, 7752 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 7753 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 7754} 7755 7756multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128, 7757 int Offset64, bits<4> opcode> { 7758 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 7759 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, 7760 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt), 7761 (ins GPR64sp:$Rn), []>; 7762 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm, 7763 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt), 7764 (ins GPR64sp:$Rn), []>; 7765 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm, 7766 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt), 7767 (ins GPR64sp:$Rn), []>; 7768 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm, 7769 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt), 7770 (ins GPR64sp:$Rn), []>; 7771 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm, 7772 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt), 7773 (ins GPR64sp:$Rn), []>; 7774 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm, 7775 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt), 7776 (ins GPR64sp:$Rn), []>; 7777 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm, 7778 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt), 7779 (ins GPR64sp:$Rn), []>; 7780 7781 7782 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm, 7783 (outs GPR64sp:$wback, 7784 !cast<RegisterOperand>(veclist # "16b"):$Vt), 7785 (ins GPR64sp:$Rn, 7786 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7787 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm, 7788 (outs GPR64sp:$wback, 7789 !cast<RegisterOperand>(veclist # "8h"):$Vt), 7790 (ins GPR64sp:$Rn, 7791 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7792 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm, 7793 (outs GPR64sp:$wback, 7794 !cast<RegisterOperand>(veclist # "4s"):$Vt), 7795 (ins GPR64sp:$Rn, 7796 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7797 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm, 7798 (outs GPR64sp:$wback, 7799 !cast<RegisterOperand>(veclist # "2d"):$Vt), 7800 (ins GPR64sp:$Rn, 7801 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7802 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm, 7803 (outs GPR64sp:$wback, 7804 !cast<RegisterOperand>(veclist # "8b"):$Vt), 7805 (ins GPR64sp:$Rn, 7806 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7807 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm, 7808 (outs GPR64sp:$wback, 7809 !cast<RegisterOperand>(veclist # "4h"):$Vt), 7810 (ins GPR64sp:$Rn, 7811 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7812 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm, 7813 (outs GPR64sp:$wback, 7814 !cast<RegisterOperand>(veclist # "2s"):$Vt), 7815 (ins GPR64sp:$Rn, 7816 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7817 } 7818 7819 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>; 7820 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>; 7821 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>; 7822 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>; 7823 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>; 7824 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>; 7825 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>; 7826} 7827 7828// Only ld1/st1 has a v1d version. 7829multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128, 7830 int Offset64, bits<4> opcode> { 7831 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { 7832 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), 7833 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 7834 GPR64sp:$Rn), []>; 7835 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs), 7836 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 7837 GPR64sp:$Rn), []>; 7838 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs), 7839 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 7840 GPR64sp:$Rn), []>; 7841 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs), 7842 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 7843 GPR64sp:$Rn), []>; 7844 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs), 7845 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 7846 GPR64sp:$Rn), []>; 7847 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs), 7848 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 7849 GPR64sp:$Rn), []>; 7850 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs), 7851 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 7852 GPR64sp:$Rn), []>; 7853 7854 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, 7855 (outs GPR64sp:$wback), 7856 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt, 7857 GPR64sp:$Rn, 7858 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7859 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, 7860 (outs GPR64sp:$wback), 7861 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt, 7862 GPR64sp:$Rn, 7863 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7864 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, 7865 (outs GPR64sp:$wback), 7866 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt, 7867 GPR64sp:$Rn, 7868 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7869 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, 7870 (outs GPR64sp:$wback), 7871 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt, 7872 GPR64sp:$Rn, 7873 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>; 7874 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, 7875 (outs GPR64sp:$wback), 7876 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt, 7877 GPR64sp:$Rn, 7878 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7879 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, 7880 (outs GPR64sp:$wback), 7881 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt, 7882 GPR64sp:$Rn, 7883 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7884 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, 7885 (outs GPR64sp:$wback), 7886 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt, 7887 GPR64sp:$Rn, 7888 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7889 } 7890 7891 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>; 7892 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>; 7893 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>; 7894 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>; 7895 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>; 7896 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>; 7897 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>; 7898} 7899 7900multiclass BaseSIMDLd1<string Count, string asm, string veclist, 7901 int Offset128, int Offset64, bits<4> opcode> 7902 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> { 7903 7904 // LD1 instructions have extra "1d" variants. 7905 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 7906 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm, 7907 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt), 7908 (ins GPR64sp:$Rn), []>; 7909 7910 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm, 7911 (outs GPR64sp:$wback, 7912 !cast<RegisterOperand>(veclist # "1d"):$Vt), 7913 (ins GPR64sp:$Rn, 7914 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7915 } 7916 7917 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>; 7918} 7919 7920multiclass BaseSIMDSt1<string Count, string asm, string veclist, 7921 int Offset128, int Offset64, bits<4> opcode> 7922 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> { 7923 7924 // ST1 instructions have extra "1d" variants. 7925 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 7926 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs), 7927 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 7928 GPR64sp:$Rn), []>; 7929 7930 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, 7931 (outs GPR64sp:$wback), 7932 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt, 7933 GPR64sp:$Rn, 7934 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>; 7935 } 7936 7937 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>; 7938} 7939 7940multiclass SIMDLd1Multiple<string asm> { 7941 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>; 7942 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; 7943 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>; 7944 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>; 7945} 7946 7947multiclass SIMDSt1Multiple<string asm> { 7948 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>; 7949 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; 7950 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>; 7951 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>; 7952} 7953 7954multiclass SIMDLd2Multiple<string asm> { 7955 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; 7956} 7957 7958multiclass SIMDSt2Multiple<string asm> { 7959 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; 7960} 7961 7962multiclass SIMDLd3Multiple<string asm> { 7963 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>; 7964} 7965 7966multiclass SIMDSt3Multiple<string asm> { 7967 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>; 7968} 7969 7970multiclass SIMDLd4Multiple<string asm> { 7971 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>; 7972} 7973 7974multiclass SIMDSt4Multiple<string asm> { 7975 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>; 7976} 7977 7978//--- 7979// AdvSIMD Load/store single-element 7980//--- 7981 7982class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode, 7983 string asm, string operands, string cst, 7984 dag oops, dag iops, list<dag> pattern> 7985 : I<oops, iops, asm, operands, cst, pattern> { 7986 bits<5> Vt; 7987 bits<5> Rn; 7988 let Inst{31} = 0; 7989 let Inst{29-24} = 0b001101; 7990 let Inst{22} = L; 7991 let Inst{21} = R; 7992 let Inst{15-13} = opcode; 7993 let Inst{9-5} = Rn; 7994 let Inst{4-0} = Vt; 7995} 7996 7997class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode, 7998 string asm, string operands, string cst, 7999 dag oops, dag iops, list<dag> pattern> 8000 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> { 8001 bits<5> Vt; 8002 bits<5> Rn; 8003 let Inst{31} = 0; 8004 let Inst{29-24} = 0b001101; 8005 let Inst{22} = L; 8006 let Inst{21} = R; 8007 let Inst{15-13} = opcode; 8008 let Inst{9-5} = Rn; 8009 let Inst{4-0} = Vt; 8010} 8011 8012 8013let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8014class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm, 8015 Operand listtype> 8016 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "", 8017 (outs listtype:$Vt), (ins GPR64sp:$Rn), 8018 []> { 8019 let Inst{30} = Q; 8020 let Inst{23} = 0; 8021 let Inst{20-16} = 0b00000; 8022 let Inst{12} = S; 8023 let Inst{11-10} = size; 8024} 8025let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8026class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, 8027 string asm, Operand listtype, Operand GPR64pi> 8028 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm", 8029 "$Rn = $wback", 8030 (outs GPR64sp:$wback, listtype:$Vt), 8031 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> { 8032 bits<5> Xm; 8033 let Inst{30} = Q; 8034 let Inst{23} = 1; 8035 let Inst{20-16} = Xm; 8036 let Inst{12} = S; 8037 let Inst{11-10} = size; 8038} 8039 8040multiclass SIMDLdrAliases<string asm, string layout, string Count, 8041 int Offset, int Size> { 8042 // E.g. "ld1r { v0.8b }, [x1], #1" 8043 // "ld1r.8b\t$Vt, [$Rn], #1" 8044 // may get mapped to 8045 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 8046 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset, 8047 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8048 GPR64sp:$Rn, 8049 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8050 XZR), 1>; 8051 8052 // E.g. "ld1r.8b { v0 }, [x1], #1" 8053 // "ld1r.8b\t$Vt, [$Rn], #1" 8054 // may get mapped to 8055 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 8056 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset, 8057 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8058 GPR64sp:$Rn, 8059 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8060 XZR), 0>; 8061 8062 // E.g. "ld1r.8b { v0 }, [x1]" 8063 // "ld1r.8b\t$Vt, [$Rn]" 8064 // may get mapped to 8065 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 8066 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]", 8067 (!cast<Instruction>(NAME # "v" # layout) 8068 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8069 GPR64sp:$Rn), 0>; 8070 8071 // E.g. "ld1r.8b { v0 }, [x1], x2" 8072 // "ld1r.8b\t$Vt, [$Rn], $Xm" 8073 // may get mapped to 8074 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 8075 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm", 8076 (!cast<Instruction>(NAME # "v" # layout # "_POST") 8077 GPR64sp:$Rn, 8078 !cast<RegisterOperand>("VecList" # Count # Size):$Vt, 8079 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 8080} 8081 8082multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count, 8083 int Offset1, int Offset2, int Offset4, int Offset8> { 8084 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm, 8085 !cast<Operand>("VecList" # Count # "8b")>; 8086 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm, 8087 !cast<Operand>("VecList" # Count #"16b")>; 8088 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm, 8089 !cast<Operand>("VecList" # Count #"4h")>; 8090 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm, 8091 !cast<Operand>("VecList" # Count #"8h")>; 8092 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm, 8093 !cast<Operand>("VecList" # Count #"2s")>; 8094 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm, 8095 !cast<Operand>("VecList" # Count #"4s")>; 8096 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm, 8097 !cast<Operand>("VecList" # Count #"1d")>; 8098 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm, 8099 !cast<Operand>("VecList" # Count #"2d")>; 8100 8101 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm, 8102 !cast<Operand>("VecList" # Count # "8b"), 8103 !cast<Operand>("GPR64pi" # Offset1)>; 8104 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm, 8105 !cast<Operand>("VecList" # Count # "16b"), 8106 !cast<Operand>("GPR64pi" # Offset1)>; 8107 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm, 8108 !cast<Operand>("VecList" # Count # "4h"), 8109 !cast<Operand>("GPR64pi" # Offset2)>; 8110 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm, 8111 !cast<Operand>("VecList" # Count # "8h"), 8112 !cast<Operand>("GPR64pi" # Offset2)>; 8113 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm, 8114 !cast<Operand>("VecList" # Count # "2s"), 8115 !cast<Operand>("GPR64pi" # Offset4)>; 8116 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm, 8117 !cast<Operand>("VecList" # Count # "4s"), 8118 !cast<Operand>("GPR64pi" # Offset4)>; 8119 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm, 8120 !cast<Operand>("VecList" # Count # "1d"), 8121 !cast<Operand>("GPR64pi" # Offset8)>; 8122 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm, 8123 !cast<Operand>("VecList" # Count # "2d"), 8124 !cast<Operand>("GPR64pi" # Offset8)>; 8125 8126 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>; 8127 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>; 8128 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>; 8129 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>; 8130 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>; 8131 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>; 8132 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>; 8133 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>; 8134} 8135 8136class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm, 8137 dag oops, dag iops, list<dag> pattern> 8138 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8139 pattern> { 8140 // idx encoded in Q:S:size fields. 8141 bits<4> idx; 8142 let Inst{30} = idx{3}; 8143 let Inst{23} = 0; 8144 let Inst{20-16} = 0b00000; 8145 let Inst{12} = idx{2}; 8146 let Inst{11-10} = idx{1-0}; 8147} 8148class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm, 8149 dag oops, dag iops, list<dag> pattern> 8150 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8151 oops, iops, pattern> { 8152 // idx encoded in Q:S:size fields. 8153 bits<4> idx; 8154 let Inst{30} = idx{3}; 8155 let Inst{23} = 0; 8156 let Inst{20-16} = 0b00000; 8157 let Inst{12} = idx{2}; 8158 let Inst{11-10} = idx{1-0}; 8159} 8160class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm, 8161 dag oops, dag iops> 8162 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8163 "$Rn = $wback", oops, iops, []> { 8164 // idx encoded in Q:S:size fields. 8165 bits<4> idx; 8166 bits<5> Xm; 8167 let Inst{30} = idx{3}; 8168 let Inst{23} = 1; 8169 let Inst{20-16} = Xm; 8170 let Inst{12} = idx{2}; 8171 let Inst{11-10} = idx{1-0}; 8172} 8173class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm, 8174 dag oops, dag iops> 8175 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8176 "$Rn = $wback", oops, iops, []> { 8177 // idx encoded in Q:S:size fields. 8178 bits<4> idx; 8179 bits<5> Xm; 8180 let Inst{30} = idx{3}; 8181 let Inst{23} = 1; 8182 let Inst{20-16} = Xm; 8183 let Inst{12} = idx{2}; 8184 let Inst{11-10} = idx{1-0}; 8185} 8186 8187class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm, 8188 dag oops, dag iops, list<dag> pattern> 8189 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8190 pattern> { 8191 // idx encoded in Q:S:size<1> fields. 8192 bits<3> idx; 8193 let Inst{30} = idx{2}; 8194 let Inst{23} = 0; 8195 let Inst{20-16} = 0b00000; 8196 let Inst{12} = idx{1}; 8197 let Inst{11} = idx{0}; 8198 let Inst{10} = size; 8199} 8200class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm, 8201 dag oops, dag iops, list<dag> pattern> 8202 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8203 oops, iops, pattern> { 8204 // idx encoded in Q:S:size<1> fields. 8205 bits<3> idx; 8206 let Inst{30} = idx{2}; 8207 let Inst{23} = 0; 8208 let Inst{20-16} = 0b00000; 8209 let Inst{12} = idx{1}; 8210 let Inst{11} = idx{0}; 8211 let Inst{10} = size; 8212} 8213 8214class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm, 8215 dag oops, dag iops> 8216 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8217 "$Rn = $wback", oops, iops, []> { 8218 // idx encoded in Q:S:size<1> fields. 8219 bits<3> idx; 8220 bits<5> Xm; 8221 let Inst{30} = idx{2}; 8222 let Inst{23} = 1; 8223 let Inst{20-16} = Xm; 8224 let Inst{12} = idx{1}; 8225 let Inst{11} = idx{0}; 8226 let Inst{10} = size; 8227} 8228class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm, 8229 dag oops, dag iops> 8230 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8231 "$Rn = $wback", oops, iops, []> { 8232 // idx encoded in Q:S:size<1> fields. 8233 bits<3> idx; 8234 bits<5> Xm; 8235 let Inst{30} = idx{2}; 8236 let Inst{23} = 1; 8237 let Inst{20-16} = Xm; 8238 let Inst{12} = idx{1}; 8239 let Inst{11} = idx{0}; 8240 let Inst{10} = size; 8241} 8242class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8243 dag oops, dag iops, list<dag> pattern> 8244 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8245 pattern> { 8246 // idx encoded in Q:S fields. 8247 bits<2> idx; 8248 let Inst{30} = idx{1}; 8249 let Inst{23} = 0; 8250 let Inst{20-16} = 0b00000; 8251 let Inst{12} = idx{0}; 8252 let Inst{11-10} = size; 8253} 8254class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8255 dag oops, dag iops, list<dag> pattern> 8256 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8257 oops, iops, pattern> { 8258 // idx encoded in Q:S fields. 8259 bits<2> idx; 8260 let Inst{30} = idx{1}; 8261 let Inst{23} = 0; 8262 let Inst{20-16} = 0b00000; 8263 let Inst{12} = idx{0}; 8264 let Inst{11-10} = size; 8265} 8266class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size, 8267 string asm, dag oops, dag iops> 8268 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8269 "$Rn = $wback", oops, iops, []> { 8270 // idx encoded in Q:S fields. 8271 bits<2> idx; 8272 bits<5> Xm; 8273 let Inst{30} = idx{1}; 8274 let Inst{23} = 1; 8275 let Inst{20-16} = Xm; 8276 let Inst{12} = idx{0}; 8277 let Inst{11-10} = size; 8278} 8279class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 8280 string asm, dag oops, dag iops> 8281 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8282 "$Rn = $wback", oops, iops, []> { 8283 // idx encoded in Q:S fields. 8284 bits<2> idx; 8285 bits<5> Xm; 8286 let Inst{30} = idx{1}; 8287 let Inst{23} = 1; 8288 let Inst{20-16} = Xm; 8289 let Inst{12} = idx{0}; 8290 let Inst{11-10} = size; 8291} 8292class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8293 dag oops, dag iops, list<dag> pattern> 8294 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops, 8295 pattern> { 8296 // idx encoded in Q field. 8297 bits<1> idx; 8298 let Inst{30} = idx; 8299 let Inst{23} = 0; 8300 let Inst{20-16} = 0b00000; 8301 let Inst{12} = 0; 8302 let Inst{11-10} = size; 8303} 8304class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm, 8305 dag oops, dag iops, list<dag> pattern> 8306 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", 8307 oops, iops, pattern> { 8308 // idx encoded in Q field. 8309 bits<1> idx; 8310 let Inst{30} = idx; 8311 let Inst{23} = 0; 8312 let Inst{20-16} = 0b00000; 8313 let Inst{12} = 0; 8314 let Inst{11-10} = size; 8315} 8316class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size, 8317 string asm, dag oops, dag iops> 8318 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8319 "$Rn = $wback", oops, iops, []> { 8320 // idx encoded in Q field. 8321 bits<1> idx; 8322 bits<5> Xm; 8323 let Inst{30} = idx; 8324 let Inst{23} = 1; 8325 let Inst{20-16} = Xm; 8326 let Inst{12} = 0; 8327 let Inst{11-10} = size; 8328} 8329class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size, 8330 string asm, dag oops, dag iops> 8331 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm", 8332 "$Rn = $wback", oops, iops, []> { 8333 // idx encoded in Q field. 8334 bits<1> idx; 8335 bits<5> Xm; 8336 let Inst{30} = idx; 8337 let Inst{23} = 1; 8338 let Inst{20-16} = Xm; 8339 let Inst{12} = 0; 8340 let Inst{11-10} = size; 8341} 8342 8343let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8344multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm, 8345 RegisterOperand listtype, 8346 RegisterOperand GPR64pi> { 8347 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm, 8348 (outs listtype:$dst), 8349 (ins listtype:$Vt, VectorIndexB:$idx, 8350 GPR64sp:$Rn), []>; 8351 8352 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm, 8353 (outs GPR64sp:$wback, listtype:$dst), 8354 (ins listtype:$Vt, VectorIndexB:$idx, 8355 GPR64sp:$Rn, GPR64pi:$Xm)>; 8356} 8357let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8358multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm, 8359 RegisterOperand listtype, 8360 RegisterOperand GPR64pi> { 8361 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm, 8362 (outs listtype:$dst), 8363 (ins listtype:$Vt, VectorIndexH:$idx, 8364 GPR64sp:$Rn), []>; 8365 8366 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm, 8367 (outs GPR64sp:$wback, listtype:$dst), 8368 (ins listtype:$Vt, VectorIndexH:$idx, 8369 GPR64sp:$Rn, GPR64pi:$Xm)>; 8370} 8371let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8372multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm, 8373 RegisterOperand listtype, 8374 RegisterOperand GPR64pi> { 8375 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm, 8376 (outs listtype:$dst), 8377 (ins listtype:$Vt, VectorIndexS:$idx, 8378 GPR64sp:$Rn), []>; 8379 8380 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm, 8381 (outs GPR64sp:$wback, listtype:$dst), 8382 (ins listtype:$Vt, VectorIndexS:$idx, 8383 GPR64sp:$Rn, GPR64pi:$Xm)>; 8384} 8385let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in 8386multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm, 8387 RegisterOperand listtype, RegisterOperand GPR64pi> { 8388 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm, 8389 (outs listtype:$dst), 8390 (ins listtype:$Vt, VectorIndexD:$idx, 8391 GPR64sp:$Rn), []>; 8392 8393 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm, 8394 (outs GPR64sp:$wback, listtype:$dst), 8395 (ins listtype:$Vt, VectorIndexD:$idx, 8396 GPR64sp:$Rn, GPR64pi:$Xm)>; 8397} 8398let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8399multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm, 8400 RegisterOperand listtype, RegisterOperand GPR64pi> { 8401 def i8 : SIMDLdStSingleB<0, R, opcode, asm, 8402 (outs), (ins listtype:$Vt, VectorIndexB:$idx, 8403 GPR64sp:$Rn), []>; 8404 8405 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm, 8406 (outs GPR64sp:$wback), 8407 (ins listtype:$Vt, VectorIndexB:$idx, 8408 GPR64sp:$Rn, GPR64pi:$Xm)>; 8409} 8410let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8411multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm, 8412 RegisterOperand listtype, RegisterOperand GPR64pi> { 8413 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm, 8414 (outs), (ins listtype:$Vt, VectorIndexH:$idx, 8415 GPR64sp:$Rn), []>; 8416 8417 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm, 8418 (outs GPR64sp:$wback), 8419 (ins listtype:$Vt, VectorIndexH:$idx, 8420 GPR64sp:$Rn, GPR64pi:$Xm)>; 8421} 8422let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8423multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm, 8424 RegisterOperand listtype, RegisterOperand GPR64pi> { 8425 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm, 8426 (outs), (ins listtype:$Vt, VectorIndexS:$idx, 8427 GPR64sp:$Rn), []>; 8428 8429 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm, 8430 (outs GPR64sp:$wback), 8431 (ins listtype:$Vt, VectorIndexS:$idx, 8432 GPR64sp:$Rn, GPR64pi:$Xm)>; 8433} 8434let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in 8435multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm, 8436 RegisterOperand listtype, RegisterOperand GPR64pi> { 8437 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm, 8438 (outs), (ins listtype:$Vt, VectorIndexD:$idx, 8439 GPR64sp:$Rn), []>; 8440 8441 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm, 8442 (outs GPR64sp:$wback), 8443 (ins listtype:$Vt, VectorIndexD:$idx, 8444 GPR64sp:$Rn, GPR64pi:$Xm)>; 8445} 8446 8447multiclass SIMDLdStSingleAliases<string asm, string layout, string Type, 8448 string Count, int Offset, Operand idxtype> { 8449 // E.g. "ld1 { v0.8b }[0], [x1], #1" 8450 // "ld1\t$Vt, [$Rn], #1" 8451 // may get mapped to 8452 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) 8453 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset, 8454 (!cast<Instruction>(NAME # Type # "_POST") 8455 GPR64sp:$Rn, 8456 !cast<RegisterOperand>("VecList" # Count # layout):$Vt, 8457 idxtype:$idx, XZR), 1>; 8458 8459 // E.g. "ld1.8b { v0 }[0], [x1], #1" 8460 // "ld1.8b\t$Vt, [$Rn], #1" 8461 // may get mapped to 8462 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) 8463 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset, 8464 (!cast<Instruction>(NAME # Type # "_POST") 8465 GPR64sp:$Rn, 8466 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 8467 idxtype:$idx, XZR), 0>; 8468 8469 // E.g. "ld1.8b { v0 }[0], [x1]" 8470 // "ld1.8b\t$Vt, [$Rn]" 8471 // may get mapped to 8472 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) 8473 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]", 8474 (!cast<Instruction>(NAME # Type) 8475 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 8476 idxtype:$idx, GPR64sp:$Rn), 0>; 8477 8478 // E.g. "ld1.8b { v0 }[0], [x1], x2" 8479 // "ld1.8b\t$Vt, [$Rn], $Xm" 8480 // may get mapped to 8481 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) 8482 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm", 8483 (!cast<Instruction>(NAME # Type # "_POST") 8484 GPR64sp:$Rn, 8485 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt, 8486 idxtype:$idx, 8487 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>; 8488} 8489 8490multiclass SIMDLdSt1SingleAliases<string asm> { 8491 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>; 8492 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>; 8493 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>; 8494 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>; 8495} 8496 8497multiclass SIMDLdSt2SingleAliases<string asm> { 8498 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>; 8499 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>; 8500 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>; 8501 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>; 8502} 8503 8504multiclass SIMDLdSt3SingleAliases<string asm> { 8505 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>; 8506 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>; 8507 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>; 8508 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>; 8509} 8510 8511multiclass SIMDLdSt4SingleAliases<string asm> { 8512 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>; 8513 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>; 8514 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>; 8515 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>; 8516} 8517} // end of 'let Predicates = [HasNEON]' 8518 8519//---------------------------------------------------------------------------- 8520// Crypto extensions 8521//---------------------------------------------------------------------------- 8522 8523let Predicates = [HasCrypto] in { 8524let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8525class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr, 8526 list<dag> pat> 8527 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>, 8528 Sched<[WriteV]>{ 8529 bits<5> Rd; 8530 bits<5> Rn; 8531 let Inst{31-16} = 0b0100111000101000; 8532 let Inst{15-12} = opc; 8533 let Inst{11-10} = 0b10; 8534 let Inst{9-5} = Rn; 8535 let Inst{4-0} = Rd; 8536} 8537 8538class AESInst<bits<4> opc, string asm, Intrinsic OpNode> 8539 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "", 8540 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>; 8541 8542class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode> 8543 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn), 8544 "$Rd = $dst", 8545 [(set (v16i8 V128:$dst), 8546 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>; 8547 8548let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8549class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind, 8550 dag oops, dag iops, list<dag> pat> 8551 : I<oops, iops, asm, 8552 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" # 8553 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>, 8554 Sched<[WriteV]>{ 8555 bits<5> Rd; 8556 bits<5> Rn; 8557 bits<5> Rm; 8558 let Inst{31-21} = 0b01011110000; 8559 let Inst{20-16} = Rm; 8560 let Inst{15} = 0; 8561 let Inst{14-12} = opc; 8562 let Inst{11-10} = 0b00; 8563 let Inst{9-5} = Rn; 8564 let Inst{4-0} = Rd; 8565} 8566 8567class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode> 8568 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 8569 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm), 8570 [(set (v4i32 FPR128:$dst), 8571 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn), 8572 (v4i32 V128:$Rm)))]>; 8573 8574class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode> 8575 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst), 8576 (ins V128:$Rd, V128:$Rn, V128:$Rm), 8577 [(set (v4i32 V128:$dst), 8578 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), 8579 (v4i32 V128:$Rm)))]>; 8580 8581class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode> 8582 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst), 8583 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm), 8584 [(set (v4i32 FPR128:$dst), 8585 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn), 8586 (v4i32 V128:$Rm)))]>; 8587 8588let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in 8589class SHA2OpInst<bits<4> opc, string asm, string kind, 8590 string cstr, dag oops, dag iops, 8591 list<dag> pat> 8592 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind # 8593 "|" # kind # "\t$Rd, $Rn}", cstr, pat>, 8594 Sched<[WriteV]>{ 8595 bits<5> Rd; 8596 bits<5> Rn; 8597 let Inst{31-16} = 0b0101111000101000; 8598 let Inst{15-12} = opc; 8599 let Inst{11-10} = 0b10; 8600 let Inst{9-5} = Rn; 8601 let Inst{4-0} = Rd; 8602} 8603 8604class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode> 8605 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst), 8606 (ins V128:$Rd, V128:$Rn), 8607 [(set (v4i32 V128:$dst), 8608 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>; 8609 8610class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode> 8611 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn), 8612 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>; 8613} // end of 'let Predicates = [HasCrypto]' 8614 8615// Allow the size specifier tokens to be upper case, not just lower. 8616def : TokenAlias<".8B", ".8b">; 8617def : TokenAlias<".4H", ".4h">; 8618def : TokenAlias<".2S", ".2s">; 8619def : TokenAlias<".1D", ".1d">; 8620def : TokenAlias<".16B", ".16b">; 8621def : TokenAlias<".8H", ".8h">; 8622def : TokenAlias<".4S", ".4s">; 8623def : TokenAlias<".2D", ".2d">; 8624def : TokenAlias<".1Q", ".1q">; 8625def : TokenAlias<".B", ".b">; 8626def : TokenAlias<".H", ".h">; 8627def : TokenAlias<".S", ".s">; 8628def : TokenAlias<".D", ".d">; 8629def : TokenAlias<".Q", ".q">; 8630