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