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