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