1//===-- ARMInstrNEON.td - NEON support for ARM -------------*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the ARM NEON instruction set. 10// 11//===----------------------------------------------------------------------===// 12 13 14//===----------------------------------------------------------------------===// 15// NEON-specific Operands. 16//===----------------------------------------------------------------------===// 17def nModImm : Operand<i32> { 18 let PrintMethod = "printVMOVModImmOperand"; 19} 20 21def nImmSplatI8AsmOperand : AsmOperandClass { let Name = "NEONi8splat"; } 22def nImmSplatI8 : Operand<i32> { 23 let PrintMethod = "printVMOVModImmOperand"; 24 let ParserMatchClass = nImmSplatI8AsmOperand; 25} 26def nImmSplatI16AsmOperand : AsmOperandClass { let Name = "NEONi16splat"; } 27def nImmSplatI16 : Operand<i32> { 28 let PrintMethod = "printVMOVModImmOperand"; 29 let ParserMatchClass = nImmSplatI16AsmOperand; 30} 31def nImmSplatI32AsmOperand : AsmOperandClass { let Name = "NEONi32splat"; } 32def nImmSplatI32 : Operand<i32> { 33 let PrintMethod = "printVMOVModImmOperand"; 34 let ParserMatchClass = nImmSplatI32AsmOperand; 35} 36def nImmSplatNotI16AsmOperand : AsmOperandClass { let Name = "NEONi16splatNot"; } 37def nImmSplatNotI16 : Operand<i32> { 38 let ParserMatchClass = nImmSplatNotI16AsmOperand; 39} 40def nImmSplatNotI32AsmOperand : AsmOperandClass { let Name = "NEONi32splatNot"; } 41def nImmSplatNotI32 : Operand<i32> { 42 let ParserMatchClass = nImmSplatNotI32AsmOperand; 43} 44def nImmVMOVI32AsmOperand : AsmOperandClass { let Name = "NEONi32vmov"; } 45def nImmVMOVI32 : Operand<i32> { 46 let PrintMethod = "printVMOVModImmOperand"; 47 let ParserMatchClass = nImmVMOVI32AsmOperand; 48} 49 50class nImmVMOVIAsmOperandReplicate<ValueType From, ValueType To> 51 : AsmOperandClass { 52 let Name = "NEONi" # To.Size # "vmovi" # From.Size # "Replicate"; 53 let PredicateMethod = "isNEONmovReplicate<" # From.Size # ", " # To.Size # ">"; 54 let RenderMethod = "addNEONvmovi" # From.Size # "ReplicateOperands"; 55} 56 57class nImmVINVIAsmOperandReplicate<ValueType From, ValueType To> 58 : AsmOperandClass { 59 let Name = "NEONi" # To.Size # "invi" # From.Size # "Replicate"; 60 let PredicateMethod = "isNEONinvReplicate<" # From.Size # ", " # To.Size # ">"; 61 let RenderMethod = "addNEONinvi" # From.Size # "ReplicateOperands"; 62} 63 64class nImmVMOVIReplicate<ValueType From, ValueType To> : Operand<i32> { 65 let PrintMethod = "printVMOVModImmOperand"; 66 let ParserMatchClass = nImmVMOVIAsmOperandReplicate<From, To>; 67} 68 69class nImmVINVIReplicate<ValueType From, ValueType To> : Operand<i32> { 70 let PrintMethod = "printVMOVModImmOperand"; 71 let ParserMatchClass = nImmVINVIAsmOperandReplicate<From, To>; 72} 73 74def nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; } 75def nImmVMOVI32Neg : Operand<i32> { 76 let PrintMethod = "printVMOVModImmOperand"; 77 let ParserMatchClass = nImmVMOVI32NegAsmOperand; 78} 79def nImmVMOVF32 : Operand<i32> { 80 let PrintMethod = "printFPImmOperand"; 81 let ParserMatchClass = FPImmOperand; 82} 83def nImmSplatI64AsmOperand : AsmOperandClass { let Name = "NEONi64splat"; } 84def nImmSplatI64 : Operand<i32> { 85 let PrintMethod = "printVMOVModImmOperand"; 86 let ParserMatchClass = nImmSplatI64AsmOperand; 87} 88 89def VectorIndex8Operand : AsmOperandClass { let Name = "VectorIndex8"; } 90def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; } 91def VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; } 92def VectorIndex64Operand : AsmOperandClass { let Name = "VectorIndex64"; } 93def VectorIndex8 : Operand<i32>, ImmLeaf<i32, [{ 94 return ((uint64_t)Imm) < 8; 95}]> { 96 let ParserMatchClass = VectorIndex8Operand; 97 let PrintMethod = "printVectorIndex"; 98 let MIOperandInfo = (ops i32imm); 99} 100def VectorIndex16 : Operand<i32>, ImmLeaf<i32, [{ 101 return ((uint64_t)Imm) < 4; 102}]> { 103 let ParserMatchClass = VectorIndex16Operand; 104 let PrintMethod = "printVectorIndex"; 105 let MIOperandInfo = (ops i32imm); 106} 107def VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{ 108 return ((uint64_t)Imm) < 2; 109}]> { 110 let ParserMatchClass = VectorIndex32Operand; 111 let PrintMethod = "printVectorIndex"; 112 let MIOperandInfo = (ops i32imm); 113} 114def VectorIndex64 : Operand<i32>, ImmLeaf<i32, [{ 115 return ((uint64_t)Imm) < 1; 116}]> { 117 let ParserMatchClass = VectorIndex64Operand; 118 let PrintMethod = "printVectorIndex"; 119 let MIOperandInfo = (ops i32imm); 120} 121 122// Register list of one D register. 123def VecListOneDAsmOperand : AsmOperandClass { 124 let Name = "VecListOneD"; 125 let ParserMethod = "parseVectorList"; 126 let RenderMethod = "addVecListOperands"; 127} 128def VecListOneD : RegisterOperand<DPR, "printVectorListOne"> { 129 let ParserMatchClass = VecListOneDAsmOperand; 130} 131// Register list of two sequential D registers. 132def VecListDPairAsmOperand : AsmOperandClass { 133 let Name = "VecListDPair"; 134 let ParserMethod = "parseVectorList"; 135 let RenderMethod = "addVecListOperands"; 136} 137def VecListDPair : RegisterOperand<DPair, "printVectorListTwo"> { 138 let ParserMatchClass = VecListDPairAsmOperand; 139} 140// Register list of three sequential D registers. 141def VecListThreeDAsmOperand : AsmOperandClass { 142 let Name = "VecListThreeD"; 143 let ParserMethod = "parseVectorList"; 144 let RenderMethod = "addVecListOperands"; 145} 146def VecListThreeD : RegisterOperand<DPR, "printVectorListThree"> { 147 let ParserMatchClass = VecListThreeDAsmOperand; 148} 149// Register list of four sequential D registers. 150def VecListFourDAsmOperand : AsmOperandClass { 151 let Name = "VecListFourD"; 152 let ParserMethod = "parseVectorList"; 153 let RenderMethod = "addVecListOperands"; 154} 155def VecListFourD : RegisterOperand<DPR, "printVectorListFour"> { 156 let ParserMatchClass = VecListFourDAsmOperand; 157} 158// Register list of two D registers spaced by 2 (two sequential Q registers). 159def VecListDPairSpacedAsmOperand : AsmOperandClass { 160 let Name = "VecListDPairSpaced"; 161 let ParserMethod = "parseVectorList"; 162 let RenderMethod = "addVecListOperands"; 163} 164def VecListDPairSpaced : RegisterOperand<DPair, "printVectorListTwoSpaced"> { 165 let ParserMatchClass = VecListDPairSpacedAsmOperand; 166} 167// Register list of three D registers spaced by 2 (three Q registers). 168def VecListThreeQAsmOperand : AsmOperandClass { 169 let Name = "VecListThreeQ"; 170 let ParserMethod = "parseVectorList"; 171 let RenderMethod = "addVecListOperands"; 172} 173def VecListThreeQ : RegisterOperand<DPR, "printVectorListThreeSpaced"> { 174 let ParserMatchClass = VecListThreeQAsmOperand; 175} 176// Register list of three D registers spaced by 2 (three Q registers). 177def VecListFourQAsmOperand : AsmOperandClass { 178 let Name = "VecListFourQ"; 179 let ParserMethod = "parseVectorList"; 180 let RenderMethod = "addVecListOperands"; 181} 182def VecListFourQ : RegisterOperand<DPR, "printVectorListFourSpaced"> { 183 let ParserMatchClass = VecListFourQAsmOperand; 184} 185 186// Register list of one D register, with "all lanes" subscripting. 187def VecListOneDAllLanesAsmOperand : AsmOperandClass { 188 let Name = "VecListOneDAllLanes"; 189 let ParserMethod = "parseVectorList"; 190 let RenderMethod = "addVecListOperands"; 191} 192def VecListOneDAllLanes : RegisterOperand<DPR, "printVectorListOneAllLanes"> { 193 let ParserMatchClass = VecListOneDAllLanesAsmOperand; 194} 195// Register list of two D registers, with "all lanes" subscripting. 196def VecListDPairAllLanesAsmOperand : AsmOperandClass { 197 let Name = "VecListDPairAllLanes"; 198 let ParserMethod = "parseVectorList"; 199 let RenderMethod = "addVecListOperands"; 200} 201def VecListDPairAllLanes : RegisterOperand<DPair, 202 "printVectorListTwoAllLanes"> { 203 let ParserMatchClass = VecListDPairAllLanesAsmOperand; 204} 205// Register list of two D registers spaced by 2 (two sequential Q registers). 206def VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass { 207 let Name = "VecListDPairSpacedAllLanes"; 208 let ParserMethod = "parseVectorList"; 209 let RenderMethod = "addVecListOperands"; 210} 211def VecListDPairSpacedAllLanes : RegisterOperand<DPairSpc, 212 "printVectorListTwoSpacedAllLanes"> { 213 let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand; 214} 215// Register list of three D registers, with "all lanes" subscripting. 216def VecListThreeDAllLanesAsmOperand : AsmOperandClass { 217 let Name = "VecListThreeDAllLanes"; 218 let ParserMethod = "parseVectorList"; 219 let RenderMethod = "addVecListOperands"; 220} 221def VecListThreeDAllLanes : RegisterOperand<DPR, 222 "printVectorListThreeAllLanes"> { 223 let ParserMatchClass = VecListThreeDAllLanesAsmOperand; 224} 225// Register list of three D registers spaced by 2 (three sequential Q regs). 226def VecListThreeQAllLanesAsmOperand : AsmOperandClass { 227 let Name = "VecListThreeQAllLanes"; 228 let ParserMethod = "parseVectorList"; 229 let RenderMethod = "addVecListOperands"; 230} 231def VecListThreeQAllLanes : RegisterOperand<DPR, 232 "printVectorListThreeSpacedAllLanes"> { 233 let ParserMatchClass = VecListThreeQAllLanesAsmOperand; 234} 235// Register list of four D registers, with "all lanes" subscripting. 236def VecListFourDAllLanesAsmOperand : AsmOperandClass { 237 let Name = "VecListFourDAllLanes"; 238 let ParserMethod = "parseVectorList"; 239 let RenderMethod = "addVecListOperands"; 240} 241def VecListFourDAllLanes : RegisterOperand<DPR, "printVectorListFourAllLanes"> { 242 let ParserMatchClass = VecListFourDAllLanesAsmOperand; 243} 244// Register list of four D registers spaced by 2 (four sequential Q regs). 245def VecListFourQAllLanesAsmOperand : AsmOperandClass { 246 let Name = "VecListFourQAllLanes"; 247 let ParserMethod = "parseVectorList"; 248 let RenderMethod = "addVecListOperands"; 249} 250def VecListFourQAllLanes : RegisterOperand<DPR, 251 "printVectorListFourSpacedAllLanes"> { 252 let ParserMatchClass = VecListFourQAllLanesAsmOperand; 253} 254 255 256// Register list of one D register, with byte lane subscripting. 257def VecListOneDByteIndexAsmOperand : AsmOperandClass { 258 let Name = "VecListOneDByteIndexed"; 259 let ParserMethod = "parseVectorList"; 260 let RenderMethod = "addVecListIndexedOperands"; 261} 262def VecListOneDByteIndexed : Operand<i32> { 263 let ParserMatchClass = VecListOneDByteIndexAsmOperand; 264 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 265} 266// ...with half-word lane subscripting. 267def VecListOneDHWordIndexAsmOperand : AsmOperandClass { 268 let Name = "VecListOneDHWordIndexed"; 269 let ParserMethod = "parseVectorList"; 270 let RenderMethod = "addVecListIndexedOperands"; 271} 272def VecListOneDHWordIndexed : Operand<i32> { 273 let ParserMatchClass = VecListOneDHWordIndexAsmOperand; 274 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 275} 276// ...with word lane subscripting. 277def VecListOneDWordIndexAsmOperand : AsmOperandClass { 278 let Name = "VecListOneDWordIndexed"; 279 let ParserMethod = "parseVectorList"; 280 let RenderMethod = "addVecListIndexedOperands"; 281} 282def VecListOneDWordIndexed : Operand<i32> { 283 let ParserMatchClass = VecListOneDWordIndexAsmOperand; 284 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 285} 286 287// Register list of two D registers with byte lane subscripting. 288def VecListTwoDByteIndexAsmOperand : AsmOperandClass { 289 let Name = "VecListTwoDByteIndexed"; 290 let ParserMethod = "parseVectorList"; 291 let RenderMethod = "addVecListIndexedOperands"; 292} 293def VecListTwoDByteIndexed : Operand<i32> { 294 let ParserMatchClass = VecListTwoDByteIndexAsmOperand; 295 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 296} 297// ...with half-word lane subscripting. 298def VecListTwoDHWordIndexAsmOperand : AsmOperandClass { 299 let Name = "VecListTwoDHWordIndexed"; 300 let ParserMethod = "parseVectorList"; 301 let RenderMethod = "addVecListIndexedOperands"; 302} 303def VecListTwoDHWordIndexed : Operand<i32> { 304 let ParserMatchClass = VecListTwoDHWordIndexAsmOperand; 305 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 306} 307// ...with word lane subscripting. 308def VecListTwoDWordIndexAsmOperand : AsmOperandClass { 309 let Name = "VecListTwoDWordIndexed"; 310 let ParserMethod = "parseVectorList"; 311 let RenderMethod = "addVecListIndexedOperands"; 312} 313def VecListTwoDWordIndexed : Operand<i32> { 314 let ParserMatchClass = VecListTwoDWordIndexAsmOperand; 315 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 316} 317// Register list of two Q registers with half-word lane subscripting. 318def VecListTwoQHWordIndexAsmOperand : AsmOperandClass { 319 let Name = "VecListTwoQHWordIndexed"; 320 let ParserMethod = "parseVectorList"; 321 let RenderMethod = "addVecListIndexedOperands"; 322} 323def VecListTwoQHWordIndexed : Operand<i32> { 324 let ParserMatchClass = VecListTwoQHWordIndexAsmOperand; 325 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 326} 327// ...with word lane subscripting. 328def VecListTwoQWordIndexAsmOperand : AsmOperandClass { 329 let Name = "VecListTwoQWordIndexed"; 330 let ParserMethod = "parseVectorList"; 331 let RenderMethod = "addVecListIndexedOperands"; 332} 333def VecListTwoQWordIndexed : Operand<i32> { 334 let ParserMatchClass = VecListTwoQWordIndexAsmOperand; 335 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 336} 337 338 339// Register list of three D registers with byte lane subscripting. 340def VecListThreeDByteIndexAsmOperand : AsmOperandClass { 341 let Name = "VecListThreeDByteIndexed"; 342 let ParserMethod = "parseVectorList"; 343 let RenderMethod = "addVecListIndexedOperands"; 344} 345def VecListThreeDByteIndexed : Operand<i32> { 346 let ParserMatchClass = VecListThreeDByteIndexAsmOperand; 347 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 348} 349// ...with half-word lane subscripting. 350def VecListThreeDHWordIndexAsmOperand : AsmOperandClass { 351 let Name = "VecListThreeDHWordIndexed"; 352 let ParserMethod = "parseVectorList"; 353 let RenderMethod = "addVecListIndexedOperands"; 354} 355def VecListThreeDHWordIndexed : Operand<i32> { 356 let ParserMatchClass = VecListThreeDHWordIndexAsmOperand; 357 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 358} 359// ...with word lane subscripting. 360def VecListThreeDWordIndexAsmOperand : AsmOperandClass { 361 let Name = "VecListThreeDWordIndexed"; 362 let ParserMethod = "parseVectorList"; 363 let RenderMethod = "addVecListIndexedOperands"; 364} 365def VecListThreeDWordIndexed : Operand<i32> { 366 let ParserMatchClass = VecListThreeDWordIndexAsmOperand; 367 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 368} 369// Register list of three Q registers with half-word lane subscripting. 370def VecListThreeQHWordIndexAsmOperand : AsmOperandClass { 371 let Name = "VecListThreeQHWordIndexed"; 372 let ParserMethod = "parseVectorList"; 373 let RenderMethod = "addVecListIndexedOperands"; 374} 375def VecListThreeQHWordIndexed : Operand<i32> { 376 let ParserMatchClass = VecListThreeQHWordIndexAsmOperand; 377 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 378} 379// ...with word lane subscripting. 380def VecListThreeQWordIndexAsmOperand : AsmOperandClass { 381 let Name = "VecListThreeQWordIndexed"; 382 let ParserMethod = "parseVectorList"; 383 let RenderMethod = "addVecListIndexedOperands"; 384} 385def VecListThreeQWordIndexed : Operand<i32> { 386 let ParserMatchClass = VecListThreeQWordIndexAsmOperand; 387 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 388} 389 390// Register list of four D registers with byte lane subscripting. 391def VecListFourDByteIndexAsmOperand : AsmOperandClass { 392 let Name = "VecListFourDByteIndexed"; 393 let ParserMethod = "parseVectorList"; 394 let RenderMethod = "addVecListIndexedOperands"; 395} 396def VecListFourDByteIndexed : Operand<i32> { 397 let ParserMatchClass = VecListFourDByteIndexAsmOperand; 398 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 399} 400// ...with half-word lane subscripting. 401def VecListFourDHWordIndexAsmOperand : AsmOperandClass { 402 let Name = "VecListFourDHWordIndexed"; 403 let ParserMethod = "parseVectorList"; 404 let RenderMethod = "addVecListIndexedOperands"; 405} 406def VecListFourDHWordIndexed : Operand<i32> { 407 let ParserMatchClass = VecListFourDHWordIndexAsmOperand; 408 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 409} 410// ...with word lane subscripting. 411def VecListFourDWordIndexAsmOperand : AsmOperandClass { 412 let Name = "VecListFourDWordIndexed"; 413 let ParserMethod = "parseVectorList"; 414 let RenderMethod = "addVecListIndexedOperands"; 415} 416def VecListFourDWordIndexed : Operand<i32> { 417 let ParserMatchClass = VecListFourDWordIndexAsmOperand; 418 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 419} 420// Register list of four Q registers with half-word lane subscripting. 421def VecListFourQHWordIndexAsmOperand : AsmOperandClass { 422 let Name = "VecListFourQHWordIndexed"; 423 let ParserMethod = "parseVectorList"; 424 let RenderMethod = "addVecListIndexedOperands"; 425} 426def VecListFourQHWordIndexed : Operand<i32> { 427 let ParserMatchClass = VecListFourQHWordIndexAsmOperand; 428 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 429} 430// ...with word lane subscripting. 431def VecListFourQWordIndexAsmOperand : AsmOperandClass { 432 let Name = "VecListFourQWordIndexed"; 433 let ParserMethod = "parseVectorList"; 434 let RenderMethod = "addVecListIndexedOperands"; 435} 436def VecListFourQWordIndexed : Operand<i32> { 437 let ParserMatchClass = VecListFourQWordIndexAsmOperand; 438 let MIOperandInfo = (ops DPR:$Vd, i32imm:$idx); 439} 440 441def dword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 442 return cast<LoadSDNode>(N)->getAlignment() >= 8; 443}]>; 444def dword_alignedstore : PatFrag<(ops node:$val, node:$ptr), 445 (store node:$val, node:$ptr), [{ 446 return cast<StoreSDNode>(N)->getAlignment() >= 8; 447}]>; 448def word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 449 return cast<LoadSDNode>(N)->getAlignment() == 4; 450}]>; 451def word_alignedstore : PatFrag<(ops node:$val, node:$ptr), 452 (store node:$val, node:$ptr), [{ 453 return cast<StoreSDNode>(N)->getAlignment() == 4; 454}]>; 455def hword_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 456 return cast<LoadSDNode>(N)->getAlignment() == 2; 457}]>; 458def hword_alignedstore : PatFrag<(ops node:$val, node:$ptr), 459 (store node:$val, node:$ptr), [{ 460 return cast<StoreSDNode>(N)->getAlignment() == 2; 461}]>; 462def byte_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 463 return cast<LoadSDNode>(N)->getAlignment() == 1; 464}]>; 465def byte_alignedstore : PatFrag<(ops node:$val, node:$ptr), 466 (store node:$val, node:$ptr), [{ 467 return cast<StoreSDNode>(N)->getAlignment() == 1; 468}]>; 469def non_word_alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 470 return cast<LoadSDNode>(N)->getAlignment() < 4; 471}]>; 472def non_word_alignedstore : PatFrag<(ops node:$val, node:$ptr), 473 (store node:$val, node:$ptr), [{ 474 return cast<StoreSDNode>(N)->getAlignment() < 4; 475}]>; 476 477//===----------------------------------------------------------------------===// 478// NEON-specific DAG Nodes. 479//===----------------------------------------------------------------------===// 480 481def SDTARMVTST : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 2>]>; 482def NEONvtst : SDNode<"ARMISD::VTST", SDTARMVTST>; 483 484// Types for vector shift by immediates. The "SHX" version is for long and 485// narrow operations where the source and destination vectors have different 486// types. The "SHINS" version is for shift and insert operations. 487def SDTARMVSHXIMM : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, 488 SDTCisVT<2, i32>]>; 489def SDTARMVSHINSIMM : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, 490 SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>; 491 492def NEONvshrnImm : SDNode<"ARMISD::VSHRNIMM", SDTARMVSHXIMM>; 493 494def NEONvrshrsImm : SDNode<"ARMISD::VRSHRsIMM", SDTARMVSHIMM>; 495def NEONvrshruImm : SDNode<"ARMISD::VRSHRuIMM", SDTARMVSHIMM>; 496def NEONvrshrnImm : SDNode<"ARMISD::VRSHRNIMM", SDTARMVSHXIMM>; 497 498def NEONvqshlsImm : SDNode<"ARMISD::VQSHLsIMM", SDTARMVSHIMM>; 499def NEONvqshluImm : SDNode<"ARMISD::VQSHLuIMM", SDTARMVSHIMM>; 500def NEONvqshlsuImm : SDNode<"ARMISD::VQSHLsuIMM", SDTARMVSHIMM>; 501def NEONvqshrnsImm : SDNode<"ARMISD::VQSHRNsIMM", SDTARMVSHXIMM>; 502def NEONvqshrnuImm : SDNode<"ARMISD::VQSHRNuIMM", SDTARMVSHXIMM>; 503def NEONvqshrnsuImm : SDNode<"ARMISD::VQSHRNsuIMM", SDTARMVSHXIMM>; 504 505def NEONvqrshrnsImm : SDNode<"ARMISD::VQRSHRNsIMM", SDTARMVSHXIMM>; 506def NEONvqrshrnuImm : SDNode<"ARMISD::VQRSHRNuIMM", SDTARMVSHXIMM>; 507def NEONvqrshrnsuImm : SDNode<"ARMISD::VQRSHRNsuIMM", SDTARMVSHXIMM>; 508 509def NEONvsliImm : SDNode<"ARMISD::VSLIIMM", SDTARMVSHINSIMM>; 510def NEONvsriImm : SDNode<"ARMISD::VSRIIMM", SDTARMVSHINSIMM>; 511 512def NEONvbsl : SDNode<"ARMISD::VBSL", 513 SDTypeProfile<1, 3, [SDTCisVec<0>, 514 SDTCisSameAs<0, 1>, 515 SDTCisSameAs<0, 2>, 516 SDTCisSameAs<0, 3>]>>; 517 518def SDTARMVEXT : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 519 SDTCisSameAs<0, 2>, SDTCisVT<3, i32>]>; 520def NEONvext : SDNode<"ARMISD::VEXT", SDTARMVEXT>; 521 522def SDTARMVSHUF2 : SDTypeProfile<2, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 523 SDTCisSameAs<0, 2>, 524 SDTCisSameAs<0, 3>]>; 525def NEONzip : SDNode<"ARMISD::VZIP", SDTARMVSHUF2>; 526def NEONuzp : SDNode<"ARMISD::VUZP", SDTARMVSHUF2>; 527def NEONtrn : SDNode<"ARMISD::VTRN", SDTARMVSHUF2>; 528 529def SDTARMVTBL1 : SDTypeProfile<1, 2, [SDTCisVT<0, v8i8>, SDTCisVT<1, v8i8>, 530 SDTCisVT<2, v8i8>]>; 531def SDTARMVTBL2 : SDTypeProfile<1, 3, [SDTCisVT<0, v8i8>, SDTCisVT<1, v8i8>, 532 SDTCisVT<2, v8i8>, SDTCisVT<3, v8i8>]>; 533def NEONvtbl1 : SDNode<"ARMISD::VTBL1", SDTARMVTBL1>; 534def NEONvtbl2 : SDNode<"ARMISD::VTBL2", SDTARMVTBL2>; 535 536 537def NEONimmAllZerosV: PatLeaf<(ARMvmovImm (i32 timm)), [{ 538 ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0)); 539 unsigned EltBits = 0; 540 uint64_t EltVal = ARM_AM::decodeVMOVModImm(ConstVal->getZExtValue(), EltBits); 541 return (EltBits == 32 && EltVal == 0); 542}]>; 543 544def NEONimmAllOnesV: PatLeaf<(ARMvmovImm (i32 timm)), [{ 545 ConstantSDNode *ConstVal = cast<ConstantSDNode>(N->getOperand(0)); 546 unsigned EltBits = 0; 547 uint64_t EltVal = ARM_AM::decodeVMOVModImm(ConstVal->getZExtValue(), EltBits); 548 return (EltBits == 8 && EltVal == 0xff); 549}]>; 550 551//===----------------------------------------------------------------------===// 552// NEON load / store instructions 553//===----------------------------------------------------------------------===// 554 555// Use VLDM to load a Q register as a D register pair. 556// This is a pseudo instruction that is expanded to VLDMD after reg alloc. 557def VLDMQIA 558 : PseudoVFPLdStM<(outs DPair:$dst), (ins GPR:$Rn), 559 IIC_fpLoad_m, "", 560 [(set DPair:$dst, (v2f64 (word_alignedload GPR:$Rn)))]>; 561 562// Use VSTM to store a Q register as a D register pair. 563// This is a pseudo instruction that is expanded to VSTMD after reg alloc. 564def VSTMQIA 565 : PseudoVFPLdStM<(outs), (ins DPair:$src, GPR:$Rn), 566 IIC_fpStore_m, "", 567 [(word_alignedstore (v2f64 DPair:$src), GPR:$Rn)]>; 568 569// Classes for VLD* pseudo-instructions with multi-register operands. 570// These are expanded to real instructions after register allocation. 571class VLDQPseudo<InstrItinClass itin> 572 : PseudoNLdSt<(outs QPR:$dst), (ins addrmode6:$addr), itin, "">; 573class VLDQWBPseudo<InstrItinClass itin> 574 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 575 (ins addrmode6:$addr, am6offset:$offset), itin, 576 "$addr.addr = $wb">; 577class VLDQWBfixedPseudo<InstrItinClass itin> 578 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 579 (ins addrmode6:$addr), itin, 580 "$addr.addr = $wb">; 581class VLDQWBregisterPseudo<InstrItinClass itin> 582 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 583 (ins addrmode6:$addr, rGPR:$offset), itin, 584 "$addr.addr = $wb">; 585 586class VLDQQPseudo<InstrItinClass itin> 587 : PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr), itin, "">; 588class VLDQQWBPseudo<InstrItinClass itin> 589 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 590 (ins addrmode6:$addr, am6offset:$offset), itin, 591 "$addr.addr = $wb">; 592class VLDQQWBfixedPseudo<InstrItinClass itin> 593 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 594 (ins addrmode6:$addr), itin, 595 "$addr.addr = $wb">; 596class VLDQQWBregisterPseudo<InstrItinClass itin> 597 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 598 (ins addrmode6:$addr, rGPR:$offset), itin, 599 "$addr.addr = $wb">; 600 601 602class VLDQQQQPseudo<InstrItinClass itin> 603 : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin, 604 "$src = $dst">; 605class VLDQQQQWBPseudo<InstrItinClass itin> 606 : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb), 607 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin, 608 "$addr.addr = $wb, $src = $dst">; 609 610let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in { 611 612// VLD1 : Vector Load (multiple single elements) 613class VLD1D<bits<4> op7_4, string Dt, Operand AddrMode> 614 : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd), 615 (ins AddrMode:$Rn), IIC_VLD1, 616 "vld1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVLD1]> { 617 let Rm = 0b1111; 618 let Inst{4} = Rn{4}; 619 let DecoderMethod = "DecodeVLDST1Instruction"; 620} 621class VLD1Q<bits<4> op7_4, string Dt, Operand AddrMode> 622 : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd), 623 (ins AddrMode:$Rn), IIC_VLD1x2, 624 "vld1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVLD2]> { 625 let Rm = 0b1111; 626 let Inst{5-4} = Rn{5-4}; 627 let DecoderMethod = "DecodeVLDST1Instruction"; 628} 629 630def VLD1d8 : VLD1D<{0,0,0,?}, "8", addrmode6align64>; 631def VLD1d16 : VLD1D<{0,1,0,?}, "16", addrmode6align64>; 632def VLD1d32 : VLD1D<{1,0,0,?}, "32", addrmode6align64>; 633def VLD1d64 : VLD1D<{1,1,0,?}, "64", addrmode6align64>; 634 635def VLD1q8 : VLD1Q<{0,0,?,?}, "8", addrmode6align64or128>; 636def VLD1q16 : VLD1Q<{0,1,?,?}, "16", addrmode6align64or128>; 637def VLD1q32 : VLD1Q<{1,0,?,?}, "32", addrmode6align64or128>; 638def VLD1q64 : VLD1Q<{1,1,?,?}, "64", addrmode6align64or128>; 639 640// ...with address register writeback: 641multiclass VLD1DWB<bits<4> op7_4, string Dt, Operand AddrMode> { 642 def _fixed : NLdSt<0,0b10, 0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb), 643 (ins AddrMode:$Rn), IIC_VLD1u, 644 "vld1", Dt, "$Vd, $Rn!", 645 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> { 646 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 647 let Inst{4} = Rn{4}; 648 let DecoderMethod = "DecodeVLDST1Instruction"; 649 } 650 def _register : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb), 651 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1u, 652 "vld1", Dt, "$Vd, $Rn, $Rm", 653 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> { 654 let Inst{4} = Rn{4}; 655 let DecoderMethod = "DecodeVLDST1Instruction"; 656 } 657} 658multiclass VLD1QWB<bits<4> op7_4, string Dt, Operand AddrMode> { 659 def _fixed : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb), 660 (ins AddrMode:$Rn), IIC_VLD1x2u, 661 "vld1", Dt, "$Vd, $Rn!", 662 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> { 663 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 664 let Inst{5-4} = Rn{5-4}; 665 let DecoderMethod = "DecodeVLDST1Instruction"; 666 } 667 def _register : NLdSt<0,0b10,0b1010,op7_4, (outs VecListDPair:$Vd, GPR:$wb), 668 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u, 669 "vld1", Dt, "$Vd, $Rn, $Rm", 670 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> { 671 let Inst{5-4} = Rn{5-4}; 672 let DecoderMethod = "DecodeVLDST1Instruction"; 673 } 674} 675 676defm VLD1d8wb : VLD1DWB<{0,0,0,?}, "8", addrmode6align64>; 677defm VLD1d16wb : VLD1DWB<{0,1,0,?}, "16", addrmode6align64>; 678defm VLD1d32wb : VLD1DWB<{1,0,0,?}, "32", addrmode6align64>; 679defm VLD1d64wb : VLD1DWB<{1,1,0,?}, "64", addrmode6align64>; 680defm VLD1q8wb : VLD1QWB<{0,0,?,?}, "8", addrmode6align64or128>; 681defm VLD1q16wb : VLD1QWB<{0,1,?,?}, "16", addrmode6align64or128>; 682defm VLD1q32wb : VLD1QWB<{1,0,?,?}, "32", addrmode6align64or128>; 683defm VLD1q64wb : VLD1QWB<{1,1,?,?}, "64", addrmode6align64or128>; 684 685// ...with 3 registers 686class VLD1D3<bits<4> op7_4, string Dt, Operand AddrMode> 687 : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd), 688 (ins AddrMode:$Rn), IIC_VLD1x3, "vld1", Dt, 689 "$Vd, $Rn", "", []>, Sched<[WriteVLD3]> { 690 let Rm = 0b1111; 691 let Inst{4} = Rn{4}; 692 let DecoderMethod = "DecodeVLDST1Instruction"; 693} 694multiclass VLD1D3WB<bits<4> op7_4, string Dt, Operand AddrMode> { 695 def _fixed : NLdSt<0,0b10,0b0110, op7_4, (outs VecListThreeD:$Vd, GPR:$wb), 696 (ins AddrMode:$Rn), IIC_VLD1x2u, 697 "vld1", Dt, "$Vd, $Rn!", 698 "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> { 699 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 700 let Inst{4} = Rn{4}; 701 let DecoderMethod = "DecodeVLDST1Instruction"; 702 } 703 def _register : NLdSt<0,0b10,0b0110,op7_4, (outs VecListThreeD:$Vd, GPR:$wb), 704 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u, 705 "vld1", Dt, "$Vd, $Rn, $Rm", 706 "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> { 707 let Inst{4} = Rn{4}; 708 let DecoderMethod = "DecodeVLDST1Instruction"; 709 } 710} 711 712def VLD1d8T : VLD1D3<{0,0,0,?}, "8", addrmode6align64>; 713def VLD1d16T : VLD1D3<{0,1,0,?}, "16", addrmode6align64>; 714def VLD1d32T : VLD1D3<{1,0,0,?}, "32", addrmode6align64>; 715def VLD1d64T : VLD1D3<{1,1,0,?}, "64", addrmode6align64>; 716 717defm VLD1d8Twb : VLD1D3WB<{0,0,0,?}, "8", addrmode6align64>; 718defm VLD1d16Twb : VLD1D3WB<{0,1,0,?}, "16", addrmode6align64>; 719defm VLD1d32Twb : VLD1D3WB<{1,0,0,?}, "32", addrmode6align64>; 720defm VLD1d64Twb : VLD1D3WB<{1,1,0,?}, "64", addrmode6align64>; 721 722def VLD1d8TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 723def VLD1d16TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 724def VLD1d32TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 725def VLD1d64TPseudo : VLDQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 726def VLD1d64TPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 727def VLD1d64TPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 728 729def VLD1q8HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 730def VLD1q8LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 731def VLD1q16HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 732def VLD1q16LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 733def VLD1q32HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 734def VLD1q32LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 735def VLD1q64HighTPseudo : VLDQQQQPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 736def VLD1q64LowTPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x3>, Sched<[WriteVLD3]>; 737 738// ...with 4 registers 739class VLD1D4<bits<4> op7_4, string Dt, Operand AddrMode> 740 : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd), 741 (ins AddrMode:$Rn), IIC_VLD1x4, "vld1", Dt, 742 "$Vd, $Rn", "", []>, Sched<[WriteVLD4]> { 743 let Rm = 0b1111; 744 let Inst{5-4} = Rn{5-4}; 745 let DecoderMethod = "DecodeVLDST1Instruction"; 746} 747multiclass VLD1D4WB<bits<4> op7_4, string Dt, Operand AddrMode> { 748 def _fixed : NLdSt<0,0b10,0b0010, op7_4, (outs VecListFourD:$Vd, GPR:$wb), 749 (ins AddrMode:$Rn), IIC_VLD1x2u, 750 "vld1", Dt, "$Vd, $Rn!", 751 "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> { 752 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 753 let Inst{5-4} = Rn{5-4}; 754 let DecoderMethod = "DecodeVLDST1Instruction"; 755 } 756 def _register : NLdSt<0,0b10,0b0010,op7_4, (outs VecListFourD:$Vd, GPR:$wb), 757 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1x2u, 758 "vld1", Dt, "$Vd, $Rn, $Rm", 759 "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> { 760 let Inst{5-4} = Rn{5-4}; 761 let DecoderMethod = "DecodeVLDST1Instruction"; 762 } 763} 764 765def VLD1d8Q : VLD1D4<{0,0,?,?}, "8", addrmode6align64or128or256>; 766def VLD1d16Q : VLD1D4<{0,1,?,?}, "16", addrmode6align64or128or256>; 767def VLD1d32Q : VLD1D4<{1,0,?,?}, "32", addrmode6align64or128or256>; 768def VLD1d64Q : VLD1D4<{1,1,?,?}, "64", addrmode6align64or128or256>; 769 770defm VLD1d8Qwb : VLD1D4WB<{0,0,?,?}, "8", addrmode6align64or128or256>; 771defm VLD1d16Qwb : VLD1D4WB<{0,1,?,?}, "16", addrmode6align64or128or256>; 772defm VLD1d32Qwb : VLD1D4WB<{1,0,?,?}, "32", addrmode6align64or128or256>; 773defm VLD1d64Qwb : VLD1D4WB<{1,1,?,?}, "64", addrmode6align64or128or256>; 774 775def VLD1d8QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 776def VLD1d16QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 777def VLD1d32QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 778def VLD1d64QPseudo : VLDQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 779def VLD1d64QPseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 780def VLD1d64QPseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 781 782def VLD1q8LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 783def VLD1q8HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 784def VLD1q16LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 785def VLD1q16HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 786def VLD1q32LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 787def VLD1q32HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 788def VLD1q64LowQPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 789def VLD1q64HighQPseudo : VLDQQQQPseudo<IIC_VLD1x4>, Sched<[WriteVLD4]>; 790 791// VLD2 : Vector Load (multiple 2-element structures) 792class VLD2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy, 793 InstrItinClass itin, Operand AddrMode> 794 : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd), 795 (ins AddrMode:$Rn), itin, 796 "vld2", Dt, "$Vd, $Rn", "", []> { 797 let Rm = 0b1111; 798 let Inst{5-4} = Rn{5-4}; 799 let DecoderMethod = "DecodeVLDST2Instruction"; 800} 801 802def VLD2d8 : VLD2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2, 803 addrmode6align64or128>, Sched<[WriteVLD2]>; 804def VLD2d16 : VLD2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2, 805 addrmode6align64or128>, Sched<[WriteVLD2]>; 806def VLD2d32 : VLD2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2, 807 addrmode6align64or128>, Sched<[WriteVLD2]>; 808 809def VLD2q8 : VLD2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2, 810 addrmode6align64or128or256>, Sched<[WriteVLD4]>; 811def VLD2q16 : VLD2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2, 812 addrmode6align64or128or256>, Sched<[WriteVLD4]>; 813def VLD2q32 : VLD2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2, 814 addrmode6align64or128or256>, Sched<[WriteVLD4]>; 815 816def VLD2q8Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>; 817def VLD2q16Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>; 818def VLD2q32Pseudo : VLDQQPseudo<IIC_VLD2x2>, Sched<[WriteVLD4]>; 819 820// ...with address register writeback: 821multiclass VLD2WB<bits<4> op11_8, bits<4> op7_4, string Dt, 822 RegisterOperand VdTy, InstrItinClass itin, Operand AddrMode> { 823 def _fixed : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb), 824 (ins AddrMode:$Rn), itin, 825 "vld2", Dt, "$Vd, $Rn!", 826 "$Rn.addr = $wb", []> { 827 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 828 let Inst{5-4} = Rn{5-4}; 829 let DecoderMethod = "DecodeVLDST2Instruction"; 830 } 831 def _register : NLdSt<0, 0b10, op11_8, op7_4, (outs VdTy:$Vd, GPR:$wb), 832 (ins AddrMode:$Rn, rGPR:$Rm), itin, 833 "vld2", Dt, "$Vd, $Rn, $Rm", 834 "$Rn.addr = $wb", []> { 835 let Inst{5-4} = Rn{5-4}; 836 let DecoderMethod = "DecodeVLDST2Instruction"; 837 } 838} 839 840defm VLD2d8wb : VLD2WB<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VLD2u, 841 addrmode6align64or128>, Sched<[WriteVLD2]>; 842defm VLD2d16wb : VLD2WB<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VLD2u, 843 addrmode6align64or128>, Sched<[WriteVLD2]>; 844defm VLD2d32wb : VLD2WB<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VLD2u, 845 addrmode6align64or128>, Sched<[WriteVLD2]>; 846 847defm VLD2q8wb : VLD2WB<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VLD2x2u, 848 addrmode6align64or128or256>, Sched<[WriteVLD4]>; 849defm VLD2q16wb : VLD2WB<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VLD2x2u, 850 addrmode6align64or128or256>, Sched<[WriteVLD4]>; 851defm VLD2q32wb : VLD2WB<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VLD2x2u, 852 addrmode6align64or128or256>, Sched<[WriteVLD4]>; 853 854def VLD2q8PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>; 855def VLD2q16PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>; 856def VLD2q32PseudoWB_fixed : VLDQQWBfixedPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>; 857def VLD2q8PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>; 858def VLD2q16PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>; 859def VLD2q32PseudoWB_register : VLDQQWBregisterPseudo<IIC_VLD2x2u>, Sched<[WriteVLD4]>; 860 861// ...with double-spaced registers 862def VLD2b8 : VLD2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2, 863 addrmode6align64or128>, Sched<[WriteVLD2]>; 864def VLD2b16 : VLD2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2, 865 addrmode6align64or128>, Sched<[WriteVLD2]>; 866def VLD2b32 : VLD2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2, 867 addrmode6align64or128>, Sched<[WriteVLD2]>; 868defm VLD2b8wb : VLD2WB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VLD2u, 869 addrmode6align64or128>, Sched<[WriteVLD2]>; 870defm VLD2b16wb : VLD2WB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VLD2u, 871 addrmode6align64or128>, Sched<[WriteVLD2]>; 872defm VLD2b32wb : VLD2WB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VLD2u, 873 addrmode6align64or128>, Sched<[WriteVLD2]>; 874 875// VLD3 : Vector Load (multiple 3-element structures) 876class VLD3D<bits<4> op11_8, bits<4> op7_4, string Dt> 877 : NLdSt<0, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3), 878 (ins addrmode6:$Rn), IIC_VLD3, 879 "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []>, Sched<[WriteVLD3]> { 880 let Rm = 0b1111; 881 let Inst{4} = Rn{4}; 882 let DecoderMethod = "DecodeVLDST3Instruction"; 883} 884 885def VLD3d8 : VLD3D<0b0100, {0,0,0,?}, "8">; 886def VLD3d16 : VLD3D<0b0100, {0,1,0,?}, "16">; 887def VLD3d32 : VLD3D<0b0100, {1,0,0,?}, "32">; 888 889def VLD3d8Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>; 890def VLD3d16Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>; 891def VLD3d32Pseudo : VLDQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>; 892 893// ...with address register writeback: 894class VLD3DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 895 : NLdSt<0, 0b10, op11_8, op7_4, 896 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), 897 (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD3u, 898 "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm", 899 "$Rn.addr = $wb", []>, Sched<[WriteVLD3]> { 900 let Inst{4} = Rn{4}; 901 let DecoderMethod = "DecodeVLDST3Instruction"; 902} 903 904def VLD3d8_UPD : VLD3DWB<0b0100, {0,0,0,?}, "8">; 905def VLD3d16_UPD : VLD3DWB<0b0100, {0,1,0,?}, "16">; 906def VLD3d32_UPD : VLD3DWB<0b0100, {1,0,0,?}, "32">; 907 908def VLD3d8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 909def VLD3d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 910def VLD3d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 911 912// ...with double-spaced registers: 913def VLD3q8 : VLD3D<0b0101, {0,0,0,?}, "8">; 914def VLD3q16 : VLD3D<0b0101, {0,1,0,?}, "16">; 915def VLD3q32 : VLD3D<0b0101, {1,0,0,?}, "32">; 916def VLD3q8_UPD : VLD3DWB<0b0101, {0,0,0,?}, "8">; 917def VLD3q16_UPD : VLD3DWB<0b0101, {0,1,0,?}, "16">; 918def VLD3q32_UPD : VLD3DWB<0b0101, {1,0,0,?}, "32">; 919 920def VLD3q8Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 921def VLD3q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 922def VLD3q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 923 924// ...alternate versions to be allocated odd register numbers: 925def VLD3q8oddPseudo : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>; 926def VLD3q16oddPseudo : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>; 927def VLD3q32oddPseudo : VLDQQQQPseudo<IIC_VLD3>, Sched<[WriteVLD3]>; 928 929def VLD3q8oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 930def VLD3q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 931def VLD3q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD3u>, Sched<[WriteVLD3]>; 932 933// VLD4 : Vector Load (multiple 4-element structures) 934class VLD4D<bits<4> op11_8, bits<4> op7_4, string Dt> 935 : NLdSt<0, 0b10, op11_8, op7_4, 936 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4), 937 (ins addrmode6:$Rn), IIC_VLD4, 938 "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []>, 939 Sched<[WriteVLD4]> { 940 let Rm = 0b1111; 941 let Inst{5-4} = Rn{5-4}; 942 let DecoderMethod = "DecodeVLDST4Instruction"; 943} 944 945def VLD4d8 : VLD4D<0b0000, {0,0,?,?}, "8">; 946def VLD4d16 : VLD4D<0b0000, {0,1,?,?}, "16">; 947def VLD4d32 : VLD4D<0b0000, {1,0,?,?}, "32">; 948 949def VLD4d8Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>; 950def VLD4d16Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>; 951def VLD4d32Pseudo : VLDQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>; 952 953// ...with address register writeback: 954class VLD4DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 955 : NLdSt<0, 0b10, op11_8, op7_4, 956 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), 957 (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD4u, 958 "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", 959 "$Rn.addr = $wb", []>, Sched<[WriteVLD4]> { 960 let Inst{5-4} = Rn{5-4}; 961 let DecoderMethod = "DecodeVLDST4Instruction"; 962} 963 964def VLD4d8_UPD : VLD4DWB<0b0000, {0,0,?,?}, "8">; 965def VLD4d16_UPD : VLD4DWB<0b0000, {0,1,?,?}, "16">; 966def VLD4d32_UPD : VLD4DWB<0b0000, {1,0,?,?}, "32">; 967 968def VLD4d8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 969def VLD4d16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 970def VLD4d32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 971 972// ...with double-spaced registers: 973def VLD4q8 : VLD4D<0b0001, {0,0,?,?}, "8">; 974def VLD4q16 : VLD4D<0b0001, {0,1,?,?}, "16">; 975def VLD4q32 : VLD4D<0b0001, {1,0,?,?}, "32">; 976def VLD4q8_UPD : VLD4DWB<0b0001, {0,0,?,?}, "8">; 977def VLD4q16_UPD : VLD4DWB<0b0001, {0,1,?,?}, "16">; 978def VLD4q32_UPD : VLD4DWB<0b0001, {1,0,?,?}, "32">; 979 980def VLD4q8Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 981def VLD4q16Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 982def VLD4q32Pseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 983 984// ...alternate versions to be allocated odd register numbers: 985def VLD4q8oddPseudo : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>; 986def VLD4q16oddPseudo : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>; 987def VLD4q32oddPseudo : VLDQQQQPseudo<IIC_VLD4>, Sched<[WriteVLD4]>; 988 989def VLD4q8oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 990def VLD4q16oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 991def VLD4q32oddPseudo_UPD : VLDQQQQWBPseudo<IIC_VLD4u>, Sched<[WriteVLD4]>; 992 993} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 994 995// Classes for VLD*LN pseudo-instructions with multi-register operands. 996// These are expanded to real instructions after register allocation. 997class VLDQLNPseudo<InstrItinClass itin> 998 : PseudoNLdSt<(outs QPR:$dst), 999 (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane), 1000 itin, "$src = $dst">; 1001class VLDQLNWBPseudo<InstrItinClass itin> 1002 : PseudoNLdSt<(outs QPR:$dst, GPR:$wb), 1003 (ins addrmode6:$addr, am6offset:$offset, QPR:$src, 1004 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">; 1005class VLDQQLNPseudo<InstrItinClass itin> 1006 : PseudoNLdSt<(outs QQPR:$dst), 1007 (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane), 1008 itin, "$src = $dst">; 1009class VLDQQLNWBPseudo<InstrItinClass itin> 1010 : PseudoNLdSt<(outs QQPR:$dst, GPR:$wb), 1011 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src, 1012 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">; 1013class VLDQQQQLNPseudo<InstrItinClass itin> 1014 : PseudoNLdSt<(outs QQQQPR:$dst), 1015 (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane), 1016 itin, "$src = $dst">; 1017class VLDQQQQLNWBPseudo<InstrItinClass itin> 1018 : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb), 1019 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src, 1020 nohash_imm:$lane), itin, "$addr.addr = $wb, $src = $dst">; 1021 1022// VLD1LN : Vector Load (single element to one lane) 1023class VLD1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 1024 PatFrag LoadOp> 1025 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd), 1026 (ins addrmode6:$Rn, DPR:$src, nohash_imm:$lane), 1027 IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn", 1028 "$src = $Vd", 1029 [(set DPR:$Vd, (vector_insert (Ty DPR:$src), 1030 (i32 (LoadOp addrmode6:$Rn)), 1031 imm:$lane))]> { 1032 let Rm = 0b1111; 1033 let DecoderMethod = "DecodeVLD1LN"; 1034} 1035class VLD1LN32<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 1036 PatFrag LoadOp> 1037 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd), 1038 (ins addrmode6oneL32:$Rn, DPR:$src, nohash_imm:$lane), 1039 IIC_VLD1ln, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn", 1040 "$src = $Vd", 1041 [(set DPR:$Vd, (vector_insert (Ty DPR:$src), 1042 (i32 (LoadOp addrmode6oneL32:$Rn)), 1043 imm:$lane))]>, Sched<[WriteVLD1]> { 1044 let Rm = 0b1111; 1045 let DecoderMethod = "DecodeVLD1LN"; 1046} 1047class VLD1QLNPseudo<ValueType Ty, PatFrag LoadOp> : VLDQLNPseudo<IIC_VLD1ln>, 1048 Sched<[WriteVLD1]> { 1049 let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src), 1050 (i32 (LoadOp addrmode6:$addr)), 1051 imm:$lane))]; 1052} 1053 1054def VLD1LNd8 : VLD1LN<0b0000, {?,?,?,0}, "8", v8i8, extloadi8> { 1055 let Inst{7-5} = lane{2-0}; 1056} 1057def VLD1LNd16 : VLD1LN<0b0100, {?,?,0,?}, "16", v4i16, extloadi16> { 1058 let Inst{7-6} = lane{1-0}; 1059 let Inst{5-4} = Rn{5-4}; 1060} 1061def VLD1LNd32 : VLD1LN32<0b1000, {?,0,?,?}, "32", v2i32, load> { 1062 let Inst{7} = lane{0}; 1063 let Inst{5-4} = Rn{5-4}; 1064} 1065 1066def VLD1LNq8Pseudo : VLD1QLNPseudo<v16i8, extloadi8>; 1067def VLD1LNq16Pseudo : VLD1QLNPseudo<v8i16, extloadi16>; 1068def VLD1LNq32Pseudo : VLD1QLNPseudo<v4i32, load>; 1069 1070let Predicates = [HasNEON] in { 1071def : Pat<(vector_insert (v4f16 DPR:$src), 1072 (f16 (load addrmode6:$addr)), imm:$lane), 1073 (VLD1LNd16 addrmode6:$addr, DPR:$src, imm:$lane)>; 1074def : Pat<(vector_insert (v8f16 QPR:$src), 1075 (f16 (load addrmode6:$addr)), imm:$lane), 1076 (VLD1LNq16Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>; 1077def : Pat<(vector_insert (v2f32 DPR:$src), 1078 (f32 (load addrmode6:$addr)), imm:$lane), 1079 (VLD1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>; 1080def : Pat<(vector_insert (v4f32 QPR:$src), 1081 (f32 (load addrmode6:$addr)), imm:$lane), 1082 (VLD1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>; 1083 1084// A 64-bit subvector insert to the first 128-bit vector position 1085// is a subregister copy that needs no instruction. 1086def : Pat<(insert_subvector undef, (v1i64 DPR:$src), (i32 0)), 1087 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 1088def : Pat<(insert_subvector undef, (v2i32 DPR:$src), (i32 0)), 1089 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 1090def : Pat<(insert_subvector undef, (v2f32 DPR:$src), (i32 0)), 1091 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 1092def : Pat<(insert_subvector undef, (v4i16 DPR:$src), (i32 0)), 1093 (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 1094def : Pat<(insert_subvector undef, (v4f16 DPR:$src), (i32 0)), 1095 (INSERT_SUBREG (v8f16 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 1096def : Pat<(insert_subvector (v16i8 undef), (v8i8 DPR:$src), (i32 0)), 1097 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 1098} 1099 1100 1101let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in { 1102 1103// ...with address register writeback: 1104class VLD1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1105 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, GPR:$wb), 1106 (ins addrmode6:$Rn, am6offset:$Rm, 1107 DPR:$src, nohash_imm:$lane), IIC_VLD1lnu, "vld1", Dt, 1108 "\\{$Vd[$lane]\\}, $Rn$Rm", 1109 "$src = $Vd, $Rn.addr = $wb", []>, Sched<[WriteVLD1]> { 1110 let DecoderMethod = "DecodeVLD1LN"; 1111} 1112 1113def VLD1LNd8_UPD : VLD1LNWB<0b0000, {?,?,?,0}, "8"> { 1114 let Inst{7-5} = lane{2-0}; 1115} 1116def VLD1LNd16_UPD : VLD1LNWB<0b0100, {?,?,0,?}, "16"> { 1117 let Inst{7-6} = lane{1-0}; 1118 let Inst{4} = Rn{4}; 1119} 1120def VLD1LNd32_UPD : VLD1LNWB<0b1000, {?,0,?,?}, "32"> { 1121 let Inst{7} = lane{0}; 1122 let Inst{5} = Rn{4}; 1123 let Inst{4} = Rn{4}; 1124} 1125 1126def VLD1LNq8Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>; 1127def VLD1LNq16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>; 1128def VLD1LNq32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD1lnu>, Sched<[WriteVLD1]>; 1129 1130// VLD2LN : Vector Load (single 2-element structure to one lane) 1131class VLD2LN<bits<4> op11_8, bits<4> op7_4, string Dt> 1132 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2), 1133 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, nohash_imm:$lane), 1134 IIC_VLD2ln, "vld2", Dt, "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn", 1135 "$src1 = $Vd, $src2 = $dst2", []>, Sched<[WriteVLD1]> { 1136 let Rm = 0b1111; 1137 let Inst{4} = Rn{4}; 1138 let DecoderMethod = "DecodeVLD2LN"; 1139} 1140 1141def VLD2LNd8 : VLD2LN<0b0001, {?,?,?,?}, "8"> { 1142 let Inst{7-5} = lane{2-0}; 1143} 1144def VLD2LNd16 : VLD2LN<0b0101, {?,?,0,?}, "16"> { 1145 let Inst{7-6} = lane{1-0}; 1146} 1147def VLD2LNd32 : VLD2LN<0b1001, {?,0,0,?}, "32"> { 1148 let Inst{7} = lane{0}; 1149} 1150 1151def VLD2LNd8Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>; 1152def VLD2LNd16Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>; 1153def VLD2LNd32Pseudo : VLDQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>; 1154 1155// ...with double-spaced registers: 1156def VLD2LNq16 : VLD2LN<0b0101, {?,?,1,?}, "16"> { 1157 let Inst{7-6} = lane{1-0}; 1158} 1159def VLD2LNq32 : VLD2LN<0b1001, {?,1,0,?}, "32"> { 1160 let Inst{7} = lane{0}; 1161} 1162 1163def VLD2LNq16Pseudo : VLDQQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>; 1164def VLD2LNq32Pseudo : VLDQQLNPseudo<IIC_VLD2ln>, Sched<[WriteVLD1]>; 1165 1166// ...with address register writeback: 1167class VLD2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1168 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb), 1169 (ins addrmode6:$Rn, am6offset:$Rm, 1170 DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VLD2lnu, "vld2", Dt, 1171 "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn$Rm", 1172 "$src1 = $Vd, $src2 = $dst2, $Rn.addr = $wb", []> { 1173 let Inst{4} = Rn{4}; 1174 let DecoderMethod = "DecodeVLD2LN"; 1175} 1176 1177def VLD2LNd8_UPD : VLD2LNWB<0b0001, {?,?,?,?}, "8"> { 1178 let Inst{7-5} = lane{2-0}; 1179} 1180def VLD2LNd16_UPD : VLD2LNWB<0b0101, {?,?,0,?}, "16"> { 1181 let Inst{7-6} = lane{1-0}; 1182} 1183def VLD2LNd32_UPD : VLD2LNWB<0b1001, {?,0,0,?}, "32"> { 1184 let Inst{7} = lane{0}; 1185} 1186 1187def VLD2LNd8Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>; 1188def VLD2LNd16Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>; 1189def VLD2LNd32Pseudo_UPD : VLDQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>; 1190 1191def VLD2LNq16_UPD : VLD2LNWB<0b0101, {?,?,1,?}, "16"> { 1192 let Inst{7-6} = lane{1-0}; 1193} 1194def VLD2LNq32_UPD : VLD2LNWB<0b1001, {?,1,0,?}, "32"> { 1195 let Inst{7} = lane{0}; 1196} 1197 1198def VLD2LNq16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>; 1199def VLD2LNq32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD2lnu>, Sched<[WriteVLD1]>; 1200 1201// VLD3LN : Vector Load (single 3-element structure to one lane) 1202class VLD3LN<bits<4> op11_8, bits<4> op7_4, string Dt> 1203 : NLdStLn<1, 0b10, op11_8, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3), 1204 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, 1205 nohash_imm:$lane), IIC_VLD3ln, "vld3", Dt, 1206 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn", 1207 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3", []>, Sched<[WriteVLD2]> { 1208 let Rm = 0b1111; 1209 let DecoderMethod = "DecodeVLD3LN"; 1210} 1211 1212def VLD3LNd8 : VLD3LN<0b0010, {?,?,?,0}, "8"> { 1213 let Inst{7-5} = lane{2-0}; 1214} 1215def VLD3LNd16 : VLD3LN<0b0110, {?,?,0,0}, "16"> { 1216 let Inst{7-6} = lane{1-0}; 1217} 1218def VLD3LNd32 : VLD3LN<0b1010, {?,0,0,0}, "32"> { 1219 let Inst{7} = lane{0}; 1220} 1221 1222def VLD3LNd8Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>; 1223def VLD3LNd16Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>; 1224def VLD3LNd32Pseudo : VLDQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>; 1225 1226// ...with double-spaced registers: 1227def VLD3LNq16 : VLD3LN<0b0110, {?,?,1,0}, "16"> { 1228 let Inst{7-6} = lane{1-0}; 1229} 1230def VLD3LNq32 : VLD3LN<0b1010, {?,1,0,0}, "32"> { 1231 let Inst{7} = lane{0}; 1232} 1233 1234def VLD3LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>; 1235def VLD3LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD3ln>, Sched<[WriteVLD2]>; 1236 1237// ...with address register writeback: 1238class VLD3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1239 : NLdStLn<1, 0b10, op11_8, op7_4, 1240 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), 1241 (ins addrmode6:$Rn, am6offset:$Rm, 1242 DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane), 1243 IIC_VLD3lnu, "vld3", Dt, 1244 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn$Rm", 1245 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $Rn.addr = $wb", 1246 []>, Sched<[WriteVLD2]> { 1247 let DecoderMethod = "DecodeVLD3LN"; 1248} 1249 1250def VLD3LNd8_UPD : VLD3LNWB<0b0010, {?,?,?,0}, "8"> { 1251 let Inst{7-5} = lane{2-0}; 1252} 1253def VLD3LNd16_UPD : VLD3LNWB<0b0110, {?,?,0,0}, "16"> { 1254 let Inst{7-6} = lane{1-0}; 1255} 1256def VLD3LNd32_UPD : VLD3LNWB<0b1010, {?,0,0,0}, "32"> { 1257 let Inst{7} = lane{0}; 1258} 1259 1260def VLD3LNd8Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>; 1261def VLD3LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>; 1262def VLD3LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>; 1263 1264def VLD3LNq16_UPD : VLD3LNWB<0b0110, {?,?,1,0}, "16"> { 1265 let Inst{7-6} = lane{1-0}; 1266} 1267def VLD3LNq32_UPD : VLD3LNWB<0b1010, {?,1,0,0}, "32"> { 1268 let Inst{7} = lane{0}; 1269} 1270 1271def VLD3LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>; 1272def VLD3LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD3lnu>, Sched<[WriteVLD2]>; 1273 1274// VLD4LN : Vector Load (single 4-element structure to one lane) 1275class VLD4LN<bits<4> op11_8, bits<4> op7_4, string Dt> 1276 : NLdStLn<1, 0b10, op11_8, op7_4, 1277 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4), 1278 (ins addrmode6:$Rn, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, 1279 nohash_imm:$lane), IIC_VLD4ln, "vld4", Dt, 1280 "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn", 1281 "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>, 1282 Sched<[WriteVLD2]> { 1283 let Rm = 0b1111; 1284 let Inst{4} = Rn{4}; 1285 let DecoderMethod = "DecodeVLD4LN"; 1286} 1287 1288def VLD4LNd8 : VLD4LN<0b0011, {?,?,?,?}, "8"> { 1289 let Inst{7-5} = lane{2-0}; 1290} 1291def VLD4LNd16 : VLD4LN<0b0111, {?,?,0,?}, "16"> { 1292 let Inst{7-6} = lane{1-0}; 1293} 1294def VLD4LNd32 : VLD4LN<0b1011, {?,0,?,?}, "32"> { 1295 let Inst{7} = lane{0}; 1296 let Inst{5} = Rn{5}; 1297} 1298 1299def VLD4LNd8Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>; 1300def VLD4LNd16Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>; 1301def VLD4LNd32Pseudo : VLDQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>; 1302 1303// ...with double-spaced registers: 1304def VLD4LNq16 : VLD4LN<0b0111, {?,?,1,?}, "16"> { 1305 let Inst{7-6} = lane{1-0}; 1306} 1307def VLD4LNq32 : VLD4LN<0b1011, {?,1,?,?}, "32"> { 1308 let Inst{7} = lane{0}; 1309 let Inst{5} = Rn{5}; 1310} 1311 1312def VLD4LNq16Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>; 1313def VLD4LNq32Pseudo : VLDQQQQLNPseudo<IIC_VLD4ln>, Sched<[WriteVLD2]>; 1314 1315// ...with address register writeback: 1316class VLD4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1317 : NLdStLn<1, 0b10, op11_8, op7_4, 1318 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), 1319 (ins addrmode6:$Rn, am6offset:$Rm, 1320 DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane), 1321 IIC_VLD4lnu, "vld4", Dt, 1322"\\{$Vd[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $Rn$Rm", 1323"$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4, $Rn.addr = $wb", 1324 []> { 1325 let Inst{4} = Rn{4}; 1326 let DecoderMethod = "DecodeVLD4LN" ; 1327} 1328 1329def VLD4LNd8_UPD : VLD4LNWB<0b0011, {?,?,?,?}, "8"> { 1330 let Inst{7-5} = lane{2-0}; 1331} 1332def VLD4LNd16_UPD : VLD4LNWB<0b0111, {?,?,0,?}, "16"> { 1333 let Inst{7-6} = lane{1-0}; 1334} 1335def VLD4LNd32_UPD : VLD4LNWB<0b1011, {?,0,?,?}, "32"> { 1336 let Inst{7} = lane{0}; 1337 let Inst{5} = Rn{5}; 1338} 1339 1340def VLD4LNd8Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>; 1341def VLD4LNd16Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>; 1342def VLD4LNd32Pseudo_UPD : VLDQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>; 1343 1344def VLD4LNq16_UPD : VLD4LNWB<0b0111, {?,?,1,?}, "16"> { 1345 let Inst{7-6} = lane{1-0}; 1346} 1347def VLD4LNq32_UPD : VLD4LNWB<0b1011, {?,1,?,?}, "32"> { 1348 let Inst{7} = lane{0}; 1349 let Inst{5} = Rn{5}; 1350} 1351 1352def VLD4LNq16Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>; 1353def VLD4LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>, Sched<[WriteVLD2]>; 1354 1355} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 1356 1357// VLD1DUP : Vector Load (single element to all lanes) 1358class VLD1DUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp, 1359 Operand AddrMode> 1360 : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListOneDAllLanes:$Vd), 1361 (ins AddrMode:$Rn), 1362 IIC_VLD1dup, "vld1", Dt, "$Vd, $Rn", "", 1363 [(set VecListOneDAllLanes:$Vd, 1364 (Ty (ARMvdup (i32 (LoadOp AddrMode:$Rn)))))]>, 1365 Sched<[WriteVLD2]> { 1366 let Rm = 0b1111; 1367 let Inst{4} = Rn{4}; 1368 let DecoderMethod = "DecodeVLD1DupInstruction"; 1369} 1370def VLD1DUPd8 : VLD1DUP<{0,0,0,?}, "8", v8i8, extloadi8, 1371 addrmode6dupalignNone>; 1372def VLD1DUPd16 : VLD1DUP<{0,1,0,?}, "16", v4i16, extloadi16, 1373 addrmode6dupalign16>; 1374def VLD1DUPd32 : VLD1DUP<{1,0,0,?}, "32", v2i32, load, 1375 addrmode6dupalign32>; 1376 1377let Predicates = [HasNEON] in { 1378def : Pat<(v2f32 (ARMvdup (f32 (load addrmode6dup:$addr)))), 1379 (VLD1DUPd32 addrmode6:$addr)>; 1380} 1381 1382class VLD1QDUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp, 1383 Operand AddrMode> 1384 : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListDPairAllLanes:$Vd), 1385 (ins AddrMode:$Rn), IIC_VLD1dup, 1386 "vld1", Dt, "$Vd, $Rn", "", 1387 [(set VecListDPairAllLanes:$Vd, 1388 (Ty (ARMvdup (i32 (LoadOp AddrMode:$Rn)))))]> { 1389 let Rm = 0b1111; 1390 let Inst{4} = Rn{4}; 1391 let DecoderMethod = "DecodeVLD1DupInstruction"; 1392} 1393 1394def VLD1DUPq8 : VLD1QDUP<{0,0,1,0}, "8", v16i8, extloadi8, 1395 addrmode6dupalignNone>; 1396def VLD1DUPq16 : VLD1QDUP<{0,1,1,?}, "16", v8i16, extloadi16, 1397 addrmode6dupalign16>; 1398def VLD1DUPq32 : VLD1QDUP<{1,0,1,?}, "32", v4i32, load, 1399 addrmode6dupalign32>; 1400 1401let Predicates = [HasNEON] in { 1402def : Pat<(v4f32 (ARMvdup (f32 (load addrmode6dup:$addr)))), 1403 (VLD1DUPq32 addrmode6:$addr)>; 1404} 1405 1406let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in { 1407// ...with address register writeback: 1408multiclass VLD1DUPWB<bits<4> op7_4, string Dt, Operand AddrMode> { 1409 def _fixed : NLdSt<1, 0b10, 0b1100, op7_4, 1410 (outs VecListOneDAllLanes:$Vd, GPR:$wb), 1411 (ins AddrMode:$Rn), IIC_VLD1dupu, 1412 "vld1", Dt, "$Vd, $Rn!", 1413 "$Rn.addr = $wb", []> { 1414 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1415 let Inst{4} = Rn{4}; 1416 let DecoderMethod = "DecodeVLD1DupInstruction"; 1417 } 1418 def _register : NLdSt<1, 0b10, 0b1100, op7_4, 1419 (outs VecListOneDAllLanes:$Vd, GPR:$wb), 1420 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1dupu, 1421 "vld1", Dt, "$Vd, $Rn, $Rm", 1422 "$Rn.addr = $wb", []> { 1423 let Inst{4} = Rn{4}; 1424 let DecoderMethod = "DecodeVLD1DupInstruction"; 1425 } 1426} 1427multiclass VLD1QDUPWB<bits<4> op7_4, string Dt, Operand AddrMode> { 1428 def _fixed : NLdSt<1, 0b10, 0b1100, op7_4, 1429 (outs VecListDPairAllLanes:$Vd, GPR:$wb), 1430 (ins AddrMode:$Rn), IIC_VLD1dupu, 1431 "vld1", Dt, "$Vd, $Rn!", 1432 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> { 1433 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1434 let Inst{4} = Rn{4}; 1435 let DecoderMethod = "DecodeVLD1DupInstruction"; 1436 } 1437 def _register : NLdSt<1, 0b10, 0b1100, op7_4, 1438 (outs VecListDPairAllLanes:$Vd, GPR:$wb), 1439 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD1dupu, 1440 "vld1", Dt, "$Vd, $Rn, $Rm", 1441 "$Rn.addr = $wb", []> { 1442 let Inst{4} = Rn{4}; 1443 let DecoderMethod = "DecodeVLD1DupInstruction"; 1444 } 1445} 1446 1447defm VLD1DUPd8wb : VLD1DUPWB<{0,0,0,0}, "8", addrmode6dupalignNone>; 1448defm VLD1DUPd16wb : VLD1DUPWB<{0,1,0,?}, "16", addrmode6dupalign16>; 1449defm VLD1DUPd32wb : VLD1DUPWB<{1,0,0,?}, "32", addrmode6dupalign32>; 1450 1451defm VLD1DUPq8wb : VLD1QDUPWB<{0,0,1,0}, "8", addrmode6dupalignNone>; 1452defm VLD1DUPq16wb : VLD1QDUPWB<{0,1,1,?}, "16", addrmode6dupalign16>; 1453defm VLD1DUPq32wb : VLD1QDUPWB<{1,0,1,?}, "32", addrmode6dupalign32>; 1454 1455// VLD2DUP : Vector Load (single 2-element structure to all lanes) 1456class VLD2DUP<bits<4> op7_4, string Dt, RegisterOperand VdTy, Operand AddrMode> 1457 : NLdSt<1, 0b10, 0b1101, op7_4, (outs VdTy:$Vd), 1458 (ins AddrMode:$Rn), IIC_VLD2dup, 1459 "vld2", Dt, "$Vd, $Rn", "", []> { 1460 let Rm = 0b1111; 1461 let Inst{4} = Rn{4}; 1462 let DecoderMethod = "DecodeVLD2DupInstruction"; 1463} 1464 1465def VLD2DUPd8 : VLD2DUP<{0,0,0,?}, "8", VecListDPairAllLanes, 1466 addrmode6dupalign16>; 1467def VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes, 1468 addrmode6dupalign32>; 1469def VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes, 1470 addrmode6dupalign64>; 1471 1472// HACK this one, VLD2DUPd8x2 must be changed at the same time with VLD2b8 or 1473// "vld2.8 {d0[], d2[]}, [r4:32]" will become "vld2.8 {d0, d2}, [r4:32]". 1474// ...with double-spaced registers 1475def VLD2DUPd8x2 : VLD2DUP<{0,0,1,?}, "8", VecListDPairSpacedAllLanes, 1476 addrmode6dupalign16>; 1477def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes, 1478 addrmode6dupalign32>; 1479def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes, 1480 addrmode6dupalign64>; 1481 1482def VLD2DUPq8EvenPseudo : VLDQQPseudo<IIC_VLD2dup>, Sched<[WriteVLD2]>; 1483def VLD2DUPq8OddPseudo : VLDQQPseudo<IIC_VLD2dup>, Sched<[WriteVLD2]>; 1484def VLD2DUPq16EvenPseudo : VLDQQPseudo<IIC_VLD2dup>, Sched<[WriteVLD2]>; 1485def VLD2DUPq16OddPseudo : VLDQQPseudo<IIC_VLD2dup>, Sched<[WriteVLD2]>; 1486def VLD2DUPq32EvenPseudo : VLDQQPseudo<IIC_VLD2dup>, Sched<[WriteVLD2]>; 1487def VLD2DUPq32OddPseudo : VLDQQPseudo<IIC_VLD2dup>, Sched<[WriteVLD2]>; 1488 1489// ...with address register writeback: 1490multiclass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy, 1491 Operand AddrMode> { 1492 def _fixed : NLdSt<1, 0b10, 0b1101, op7_4, 1493 (outs VdTy:$Vd, GPR:$wb), 1494 (ins AddrMode:$Rn), IIC_VLD2dupu, 1495 "vld2", Dt, "$Vd, $Rn!", 1496 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> { 1497 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1498 let Inst{4} = Rn{4}; 1499 let DecoderMethod = "DecodeVLD2DupInstruction"; 1500 } 1501 def _register : NLdSt<1, 0b10, 0b1101, op7_4, 1502 (outs VdTy:$Vd, GPR:$wb), 1503 (ins AddrMode:$Rn, rGPR:$Rm), IIC_VLD2dupu, 1504 "vld2", Dt, "$Vd, $Rn, $Rm", 1505 "$Rn.addr = $wb", []>, Sched<[WriteVLD1]> { 1506 let Inst{4} = Rn{4}; 1507 let DecoderMethod = "DecodeVLD2DupInstruction"; 1508 } 1509} 1510 1511defm VLD2DUPd8wb : VLD2DUPWB<{0,0,0,0}, "8", VecListDPairAllLanes, 1512 addrmode6dupalign16>; 1513defm VLD2DUPd16wb : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes, 1514 addrmode6dupalign32>; 1515defm VLD2DUPd32wb : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes, 1516 addrmode6dupalign64>; 1517 1518defm VLD2DUPd8x2wb : VLD2DUPWB<{0,0,1,0}, "8", VecListDPairSpacedAllLanes, 1519 addrmode6dupalign16>; 1520defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes, 1521 addrmode6dupalign32>; 1522defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes, 1523 addrmode6dupalign64>; 1524 1525// VLD3DUP : Vector Load (single 3-element structure to all lanes) 1526class VLD3DUP<bits<4> op7_4, string Dt> 1527 : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3), 1528 (ins addrmode6dup:$Rn), IIC_VLD3dup, 1529 "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []>, 1530 Sched<[WriteVLD2]> { 1531 let Rm = 0b1111; 1532 let Inst{4} = 0; 1533 let DecoderMethod = "DecodeVLD3DupInstruction"; 1534} 1535 1536def VLD3DUPd8 : VLD3DUP<{0,0,0,?}, "8">; 1537def VLD3DUPd16 : VLD3DUP<{0,1,0,?}, "16">; 1538def VLD3DUPd32 : VLD3DUP<{1,0,0,?}, "32">; 1539 1540def VLD3DUPd8Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1541def VLD3DUPd16Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1542def VLD3DUPd32Pseudo : VLDQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1543 1544// ...with double-spaced registers (not used for codegen): 1545def VLD3DUPq8 : VLD3DUP<{0,0,1,?}, "8">; 1546def VLD3DUPq16 : VLD3DUP<{0,1,1,?}, "16">; 1547def VLD3DUPq32 : VLD3DUP<{1,0,1,?}, "32">; 1548 1549def VLD3DUPq8EvenPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1550def VLD3DUPq8OddPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1551def VLD3DUPq16EvenPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1552def VLD3DUPq16OddPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1553def VLD3DUPq32EvenPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1554def VLD3DUPq32OddPseudo : VLDQQQQPseudo<IIC_VLD3dup>, Sched<[WriteVLD2]>; 1555 1556// ...with address register writeback: 1557class VLD3DUPWB<bits<4> op7_4, string Dt, Operand AddrMode> 1558 : NLdSt<1, 0b10, 0b1110, op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), 1559 (ins AddrMode:$Rn, am6offset:$Rm), IIC_VLD3dupu, 1560 "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm", 1561 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> { 1562 let Inst{4} = 0; 1563 let DecoderMethod = "DecodeVLD3DupInstruction"; 1564} 1565 1566def VLD3DUPd8_UPD : VLD3DUPWB<{0,0,0,0}, "8", addrmode6dupalign64>; 1567def VLD3DUPd16_UPD : VLD3DUPWB<{0,1,0,?}, "16", addrmode6dupalign64>; 1568def VLD3DUPd32_UPD : VLD3DUPWB<{1,0,0,?}, "32", addrmode6dupalign64>; 1569 1570def VLD3DUPq8_UPD : VLD3DUPWB<{0,0,1,0}, "8", addrmode6dupalign64>; 1571def VLD3DUPq16_UPD : VLD3DUPWB<{0,1,1,?}, "16", addrmode6dupalign64>; 1572def VLD3DUPq32_UPD : VLD3DUPWB<{1,0,1,?}, "32", addrmode6dupalign64>; 1573 1574def VLD3DUPd8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>; 1575def VLD3DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>; 1576def VLD3DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD3dupu>, Sched<[WriteVLD2]>; 1577 1578// VLD4DUP : Vector Load (single 4-element structure to all lanes) 1579class VLD4DUP<bits<4> op7_4, string Dt> 1580 : NLdSt<1, 0b10, 0b1111, op7_4, 1581 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4), 1582 (ins addrmode6dup:$Rn), IIC_VLD4dup, 1583 "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> { 1584 let Rm = 0b1111; 1585 let Inst{4} = Rn{4}; 1586 let DecoderMethod = "DecodeVLD4DupInstruction"; 1587} 1588 1589def VLD4DUPd8 : VLD4DUP<{0,0,0,?}, "8">; 1590def VLD4DUPd16 : VLD4DUP<{0,1,0,?}, "16">; 1591def VLD4DUPd32 : VLD4DUP<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; } 1592 1593def VLD4DUPd8Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1594def VLD4DUPd16Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1595def VLD4DUPd32Pseudo : VLDQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1596 1597// ...with double-spaced registers (not used for codegen): 1598def VLD4DUPq8 : VLD4DUP<{0,0,1,?}, "8">; 1599def VLD4DUPq16 : VLD4DUP<{0,1,1,?}, "16">; 1600def VLD4DUPq32 : VLD4DUP<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; } 1601 1602def VLD4DUPq8EvenPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1603def VLD4DUPq8OddPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1604def VLD4DUPq16EvenPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1605def VLD4DUPq16OddPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1606def VLD4DUPq32EvenPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1607def VLD4DUPq32OddPseudo : VLDQQQQPseudo<IIC_VLD4dup>, Sched<[WriteVLD2]>; 1608 1609// ...with address register writeback: 1610class VLD4DUPWB<bits<4> op7_4, string Dt> 1611 : NLdSt<1, 0b10, 0b1111, op7_4, 1612 (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), 1613 (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD4dupu, 1614 "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm", 1615 "$Rn.addr = $wb", []>, Sched<[WriteVLD2]> { 1616 let Inst{4} = Rn{4}; 1617 let DecoderMethod = "DecodeVLD4DupInstruction"; 1618} 1619 1620def VLD4DUPd8_UPD : VLD4DUPWB<{0,0,0,0}, "8">; 1621def VLD4DUPd16_UPD : VLD4DUPWB<{0,1,0,?}, "16">; 1622def VLD4DUPd32_UPD : VLD4DUPWB<{1,?,0,?}, "32"> { let Inst{6} = Rn{5}; } 1623 1624def VLD4DUPq8_UPD : VLD4DUPWB<{0,0,1,0}, "8">; 1625def VLD4DUPq16_UPD : VLD4DUPWB<{0,1,1,?}, "16">; 1626def VLD4DUPq32_UPD : VLD4DUPWB<{1,?,1,?}, "32"> { let Inst{6} = Rn{5}; } 1627 1628def VLD4DUPd8Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>; 1629def VLD4DUPd16Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>; 1630def VLD4DUPd32Pseudo_UPD : VLDQQWBPseudo<IIC_VLD4dupu>, Sched<[WriteVLD2]>; 1631 1632} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 1633 1634let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in { 1635 1636// Classes for VST* pseudo-instructions with multi-register operands. 1637// These are expanded to real instructions after register allocation. 1638class VSTQPseudo<InstrItinClass itin> 1639 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src), itin, "">; 1640class VSTQWBPseudo<InstrItinClass itin> 1641 : PseudoNLdSt<(outs GPR:$wb), 1642 (ins addrmode6:$addr, am6offset:$offset, QPR:$src), itin, 1643 "$addr.addr = $wb">; 1644class VSTQWBfixedPseudo<InstrItinClass itin> 1645 : PseudoNLdSt<(outs GPR:$wb), 1646 (ins addrmode6:$addr, QPR:$src), itin, 1647 "$addr.addr = $wb">; 1648class VSTQWBregisterPseudo<InstrItinClass itin> 1649 : PseudoNLdSt<(outs GPR:$wb), 1650 (ins addrmode6:$addr, rGPR:$offset, QPR:$src), itin, 1651 "$addr.addr = $wb">; 1652class VSTQQPseudo<InstrItinClass itin> 1653 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src), itin, "">; 1654class VSTQQWBPseudo<InstrItinClass itin> 1655 : PseudoNLdSt<(outs GPR:$wb), 1656 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src), itin, 1657 "$addr.addr = $wb">; 1658class VSTQQWBfixedPseudo<InstrItinClass itin> 1659 : PseudoNLdSt<(outs GPR:$wb), 1660 (ins addrmode6:$addr, QQPR:$src), itin, 1661 "$addr.addr = $wb">; 1662class VSTQQWBregisterPseudo<InstrItinClass itin> 1663 : PseudoNLdSt<(outs GPR:$wb), 1664 (ins addrmode6:$addr, rGPR:$offset, QQPR:$src), itin, 1665 "$addr.addr = $wb">; 1666 1667class VSTQQQQPseudo<InstrItinClass itin> 1668 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src), itin, "">; 1669class VSTQQQQWBPseudo<InstrItinClass itin> 1670 : PseudoNLdSt<(outs GPR:$wb), 1671 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin, 1672 "$addr.addr = $wb">; 1673 1674// VST1 : Vector Store (multiple single elements) 1675class VST1D<bits<4> op7_4, string Dt, Operand AddrMode> 1676 : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins AddrMode:$Rn, VecListOneD:$Vd), 1677 IIC_VST1, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST1]> { 1678 let Rm = 0b1111; 1679 let Inst{4} = Rn{4}; 1680 let DecoderMethod = "DecodeVLDST1Instruction"; 1681} 1682class VST1Q<bits<4> op7_4, string Dt, Operand AddrMode> 1683 : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins AddrMode:$Rn, VecListDPair:$Vd), 1684 IIC_VST1x2, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST2]> { 1685 let Rm = 0b1111; 1686 let Inst{5-4} = Rn{5-4}; 1687 let DecoderMethod = "DecodeVLDST1Instruction"; 1688} 1689 1690def VST1d8 : VST1D<{0,0,0,?}, "8", addrmode6align64>; 1691def VST1d16 : VST1D<{0,1,0,?}, "16", addrmode6align64>; 1692def VST1d32 : VST1D<{1,0,0,?}, "32", addrmode6align64>; 1693def VST1d64 : VST1D<{1,1,0,?}, "64", addrmode6align64>; 1694 1695def VST1q8 : VST1Q<{0,0,?,?}, "8", addrmode6align64or128>; 1696def VST1q16 : VST1Q<{0,1,?,?}, "16", addrmode6align64or128>; 1697def VST1q32 : VST1Q<{1,0,?,?}, "32", addrmode6align64or128>; 1698def VST1q64 : VST1Q<{1,1,?,?}, "64", addrmode6align64or128>; 1699 1700// ...with address register writeback: 1701multiclass VST1DWB<bits<4> op7_4, string Dt, Operand AddrMode> { 1702 def _fixed : NLdSt<0,0b00, 0b0111,op7_4, (outs GPR:$wb), 1703 (ins AddrMode:$Rn, VecListOneD:$Vd), IIC_VLD1u, 1704 "vst1", Dt, "$Vd, $Rn!", 1705 "$Rn.addr = $wb", []>, Sched<[WriteVST1]> { 1706 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1707 let Inst{4} = Rn{4}; 1708 let DecoderMethod = "DecodeVLDST1Instruction"; 1709 } 1710 def _register : NLdSt<0,0b00,0b0111,op7_4, (outs GPR:$wb), 1711 (ins AddrMode:$Rn, rGPR:$Rm, VecListOneD:$Vd), 1712 IIC_VLD1u, 1713 "vst1", Dt, "$Vd, $Rn, $Rm", 1714 "$Rn.addr = $wb", []>, Sched<[WriteVST1]> { 1715 let Inst{4} = Rn{4}; 1716 let DecoderMethod = "DecodeVLDST1Instruction"; 1717 } 1718} 1719multiclass VST1QWB<bits<4> op7_4, string Dt, Operand AddrMode> { 1720 def _fixed : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), 1721 (ins AddrMode:$Rn, VecListDPair:$Vd), IIC_VLD1x2u, 1722 "vst1", Dt, "$Vd, $Rn!", 1723 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> { 1724 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1725 let Inst{5-4} = Rn{5-4}; 1726 let DecoderMethod = "DecodeVLDST1Instruction"; 1727 } 1728 def _register : NLdSt<0,0b00,0b1010,op7_4, (outs GPR:$wb), 1729 (ins AddrMode:$Rn, rGPR:$Rm, VecListDPair:$Vd), 1730 IIC_VLD1x2u, 1731 "vst1", Dt, "$Vd, $Rn, $Rm", 1732 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> { 1733 let Inst{5-4} = Rn{5-4}; 1734 let DecoderMethod = "DecodeVLDST1Instruction"; 1735 } 1736} 1737 1738defm VST1d8wb : VST1DWB<{0,0,0,?}, "8", addrmode6align64>; 1739defm VST1d16wb : VST1DWB<{0,1,0,?}, "16", addrmode6align64>; 1740defm VST1d32wb : VST1DWB<{1,0,0,?}, "32", addrmode6align64>; 1741defm VST1d64wb : VST1DWB<{1,1,0,?}, "64", addrmode6align64>; 1742 1743defm VST1q8wb : VST1QWB<{0,0,?,?}, "8", addrmode6align64or128>; 1744defm VST1q16wb : VST1QWB<{0,1,?,?}, "16", addrmode6align64or128>; 1745defm VST1q32wb : VST1QWB<{1,0,?,?}, "32", addrmode6align64or128>; 1746defm VST1q64wb : VST1QWB<{1,1,?,?}, "64", addrmode6align64or128>; 1747 1748// ...with 3 registers 1749class VST1D3<bits<4> op7_4, string Dt, Operand AddrMode> 1750 : NLdSt<0, 0b00, 0b0110, op7_4, (outs), 1751 (ins AddrMode:$Rn, VecListThreeD:$Vd), 1752 IIC_VST1x3, "vst1", Dt, "$Vd, $Rn", "", []>, Sched<[WriteVST3]> { 1753 let Rm = 0b1111; 1754 let Inst{4} = Rn{4}; 1755 let DecoderMethod = "DecodeVLDST1Instruction"; 1756} 1757multiclass VST1D3WB<bits<4> op7_4, string Dt, Operand AddrMode> { 1758 def _fixed : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb), 1759 (ins AddrMode:$Rn, VecListThreeD:$Vd), IIC_VLD1x3u, 1760 "vst1", Dt, "$Vd, $Rn!", 1761 "$Rn.addr = $wb", []>, Sched<[WriteVST3]> { 1762 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1763 let Inst{5-4} = Rn{5-4}; 1764 let DecoderMethod = "DecodeVLDST1Instruction"; 1765 } 1766 def _register : NLdSt<0,0b00,0b0110,op7_4, (outs GPR:$wb), 1767 (ins AddrMode:$Rn, rGPR:$Rm, VecListThreeD:$Vd), 1768 IIC_VLD1x3u, 1769 "vst1", Dt, "$Vd, $Rn, $Rm", 1770 "$Rn.addr = $wb", []>, Sched<[WriteVST3]> { 1771 let Inst{5-4} = Rn{5-4}; 1772 let DecoderMethod = "DecodeVLDST1Instruction"; 1773 } 1774} 1775 1776def VST1d8T : VST1D3<{0,0,0,?}, "8", addrmode6align64>; 1777def VST1d16T : VST1D3<{0,1,0,?}, "16", addrmode6align64>; 1778def VST1d32T : VST1D3<{1,0,0,?}, "32", addrmode6align64>; 1779def VST1d64T : VST1D3<{1,1,0,?}, "64", addrmode6align64>; 1780 1781defm VST1d8Twb : VST1D3WB<{0,0,0,?}, "8", addrmode6align64>; 1782defm VST1d16Twb : VST1D3WB<{0,1,0,?}, "16", addrmode6align64>; 1783defm VST1d32Twb : VST1D3WB<{1,0,0,?}, "32", addrmode6align64>; 1784defm VST1d64Twb : VST1D3WB<{1,1,0,?}, "64", addrmode6align64>; 1785 1786def VST1d8TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1787def VST1d16TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1788def VST1d32TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1789def VST1d64TPseudo : VSTQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1790def VST1d64TPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>; 1791def VST1d64TPseudoWB_register : VSTQQWBPseudo<IIC_VST1x3u>, Sched<[WriteVST3]>; 1792 1793def VST1q8HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1794def VST1q8LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1795def VST1q16HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1796def VST1q16LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1797def VST1q32HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1798def VST1q32LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1799def VST1q64HighTPseudo : VSTQQQQPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1800def VST1q64LowTPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x3>, Sched<[WriteVST3]>; 1801 1802// ...with 4 registers 1803class VST1D4<bits<4> op7_4, string Dt, Operand AddrMode> 1804 : NLdSt<0, 0b00, 0b0010, op7_4, (outs), 1805 (ins AddrMode:$Rn, VecListFourD:$Vd), 1806 IIC_VST1x4, "vst1", Dt, "$Vd, $Rn", "", 1807 []>, Sched<[WriteVST4]> { 1808 let Rm = 0b1111; 1809 let Inst{5-4} = Rn{5-4}; 1810 let DecoderMethod = "DecodeVLDST1Instruction"; 1811} 1812multiclass VST1D4WB<bits<4> op7_4, string Dt, Operand AddrMode> { 1813 def _fixed : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb), 1814 (ins AddrMode:$Rn, VecListFourD:$Vd), IIC_VLD1x4u, 1815 "vst1", Dt, "$Vd, $Rn!", 1816 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> { 1817 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1818 let Inst{5-4} = Rn{5-4}; 1819 let DecoderMethod = "DecodeVLDST1Instruction"; 1820 } 1821 def _register : NLdSt<0,0b00,0b0010,op7_4, (outs GPR:$wb), 1822 (ins AddrMode:$Rn, rGPR:$Rm, VecListFourD:$Vd), 1823 IIC_VLD1x4u, 1824 "vst1", Dt, "$Vd, $Rn, $Rm", 1825 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> { 1826 let Inst{5-4} = Rn{5-4}; 1827 let DecoderMethod = "DecodeVLDST1Instruction"; 1828 } 1829} 1830 1831def VST1d8Q : VST1D4<{0,0,?,?}, "8", addrmode6align64or128or256>; 1832def VST1d16Q : VST1D4<{0,1,?,?}, "16", addrmode6align64or128or256>; 1833def VST1d32Q : VST1D4<{1,0,?,?}, "32", addrmode6align64or128or256>; 1834def VST1d64Q : VST1D4<{1,1,?,?}, "64", addrmode6align64or128or256>; 1835 1836defm VST1d8Qwb : VST1D4WB<{0,0,?,?}, "8", addrmode6align64or128or256>; 1837defm VST1d16Qwb : VST1D4WB<{0,1,?,?}, "16", addrmode6align64or128or256>; 1838defm VST1d32Qwb : VST1D4WB<{1,0,?,?}, "32", addrmode6align64or128or256>; 1839defm VST1d64Qwb : VST1D4WB<{1,1,?,?}, "64", addrmode6align64or128or256>; 1840 1841def VST1d8QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1842def VST1d16QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1843def VST1d32QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1844def VST1d64QPseudo : VSTQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1845def VST1d64QPseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>; 1846def VST1d64QPseudoWB_register : VSTQQWBPseudo<IIC_VST1x4u>, Sched<[WriteVST4]>; 1847 1848def VST1q8HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1849def VST1q8LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1850def VST1q16HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1851def VST1q16LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1852def VST1q32HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1853def VST1q32LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1854def VST1q64HighQPseudo : VSTQQQQPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1855def VST1q64LowQPseudo_UPD : VSTQQQQWBPseudo<IIC_VST1x4>, Sched<[WriteVST4]>; 1856 1857// VST2 : Vector Store (multiple 2-element structures) 1858class VST2<bits<4> op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy, 1859 InstrItinClass itin, Operand AddrMode> 1860 : NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins AddrMode:$Rn, VdTy:$Vd), 1861 itin, "vst2", Dt, "$Vd, $Rn", "", []> { 1862 let Rm = 0b1111; 1863 let Inst{5-4} = Rn{5-4}; 1864 let DecoderMethod = "DecodeVLDST2Instruction"; 1865} 1866 1867def VST2d8 : VST2<0b1000, {0,0,?,?}, "8", VecListDPair, IIC_VST2, 1868 addrmode6align64or128>, Sched<[WriteVST2]>; 1869def VST2d16 : VST2<0b1000, {0,1,?,?}, "16", VecListDPair, IIC_VST2, 1870 addrmode6align64or128>, Sched<[WriteVST2]>; 1871def VST2d32 : VST2<0b1000, {1,0,?,?}, "32", VecListDPair, IIC_VST2, 1872 addrmode6align64or128>, Sched<[WriteVST2]>; 1873 1874def VST2q8 : VST2<0b0011, {0,0,?,?}, "8", VecListFourD, IIC_VST2x2, 1875 addrmode6align64or128or256>, Sched<[WriteVST4]>; 1876def VST2q16 : VST2<0b0011, {0,1,?,?}, "16", VecListFourD, IIC_VST2x2, 1877 addrmode6align64or128or256>, Sched<[WriteVST4]>; 1878def VST2q32 : VST2<0b0011, {1,0,?,?}, "32", VecListFourD, IIC_VST2x2, 1879 addrmode6align64or128or256>, Sched<[WriteVST4]>; 1880 1881def VST2q8Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>; 1882def VST2q16Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>; 1883def VST2q32Pseudo : VSTQQPseudo<IIC_VST2x2>, Sched<[WriteVST4]>; 1884 1885// ...with address register writeback: 1886multiclass VST2DWB<bits<4> op11_8, bits<4> op7_4, string Dt, 1887 RegisterOperand VdTy, Operand AddrMode> { 1888 def _fixed : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1889 (ins AddrMode:$Rn, VdTy:$Vd), IIC_VLD1u, 1890 "vst2", Dt, "$Vd, $Rn!", 1891 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> { 1892 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1893 let Inst{5-4} = Rn{5-4}; 1894 let DecoderMethod = "DecodeVLDST2Instruction"; 1895 } 1896 def _register : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1897 (ins AddrMode:$Rn, rGPR:$Rm, VdTy:$Vd), IIC_VLD1u, 1898 "vst2", Dt, "$Vd, $Rn, $Rm", 1899 "$Rn.addr = $wb", []>, Sched<[WriteVST2]> { 1900 let Inst{5-4} = Rn{5-4}; 1901 let DecoderMethod = "DecodeVLDST2Instruction"; 1902 } 1903} 1904multiclass VST2QWB<bits<4> op7_4, string Dt, Operand AddrMode> { 1905 def _fixed : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), 1906 (ins AddrMode:$Rn, VecListFourD:$Vd), IIC_VLD1u, 1907 "vst2", Dt, "$Vd, $Rn!", 1908 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> { 1909 let Rm = 0b1101; // NLdSt will assign to the right encoding bits. 1910 let Inst{5-4} = Rn{5-4}; 1911 let DecoderMethod = "DecodeVLDST2Instruction"; 1912 } 1913 def _register : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), 1914 (ins AddrMode:$Rn, rGPR:$Rm, VecListFourD:$Vd), 1915 IIC_VLD1u, 1916 "vst2", Dt, "$Vd, $Rn, $Rm", 1917 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> { 1918 let Inst{5-4} = Rn{5-4}; 1919 let DecoderMethod = "DecodeVLDST2Instruction"; 1920 } 1921} 1922 1923defm VST2d8wb : VST2DWB<0b1000, {0,0,?,?}, "8", VecListDPair, 1924 addrmode6align64or128>; 1925defm VST2d16wb : VST2DWB<0b1000, {0,1,?,?}, "16", VecListDPair, 1926 addrmode6align64or128>; 1927defm VST2d32wb : VST2DWB<0b1000, {1,0,?,?}, "32", VecListDPair, 1928 addrmode6align64or128>; 1929 1930defm VST2q8wb : VST2QWB<{0,0,?,?}, "8", addrmode6align64or128or256>; 1931defm VST2q16wb : VST2QWB<{0,1,?,?}, "16", addrmode6align64or128or256>; 1932defm VST2q32wb : VST2QWB<{1,0,?,?}, "32", addrmode6align64or128or256>; 1933 1934def VST2q8PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>; 1935def VST2q16PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>; 1936def VST2q32PseudoWB_fixed : VSTQQWBfixedPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>; 1937def VST2q8PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>; 1938def VST2q16PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>; 1939def VST2q32PseudoWB_register : VSTQQWBregisterPseudo<IIC_VST2x2u>, Sched<[WriteVST4]>; 1940 1941// ...with double-spaced registers 1942def VST2b8 : VST2<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, IIC_VST2, 1943 addrmode6align64or128>; 1944def VST2b16 : VST2<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, IIC_VST2, 1945 addrmode6align64or128>; 1946def VST2b32 : VST2<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, IIC_VST2, 1947 addrmode6align64or128>; 1948defm VST2b8wb : VST2DWB<0b1001, {0,0,?,?}, "8", VecListDPairSpaced, 1949 addrmode6align64or128>; 1950defm VST2b16wb : VST2DWB<0b1001, {0,1,?,?}, "16", VecListDPairSpaced, 1951 addrmode6align64or128>; 1952defm VST2b32wb : VST2DWB<0b1001, {1,0,?,?}, "32", VecListDPairSpaced, 1953 addrmode6align64or128>; 1954 1955// VST3 : Vector Store (multiple 3-element structures) 1956class VST3D<bits<4> op11_8, bits<4> op7_4, string Dt> 1957 : NLdSt<0, 0b00, op11_8, op7_4, (outs), 1958 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3, 1959 "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []>, Sched<[WriteVST3]> { 1960 let Rm = 0b1111; 1961 let Inst{4} = Rn{4}; 1962 let DecoderMethod = "DecodeVLDST3Instruction"; 1963} 1964 1965def VST3d8 : VST3D<0b0100, {0,0,0,?}, "8">; 1966def VST3d16 : VST3D<0b0100, {0,1,0,?}, "16">; 1967def VST3d32 : VST3D<0b0100, {1,0,0,?}, "32">; 1968 1969def VST3d8Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>; 1970def VST3d16Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>; 1971def VST3d32Pseudo : VSTQQPseudo<IIC_VST3>, Sched<[WriteVST3]>; 1972 1973// ...with address register writeback: 1974class VST3DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 1975 : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 1976 (ins addrmode6:$Rn, am6offset:$Rm, 1977 DPR:$Vd, DPR:$src2, DPR:$src3), IIC_VST3u, 1978 "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm", 1979 "$Rn.addr = $wb", []>, Sched<[WriteVST3]> { 1980 let Inst{4} = Rn{4}; 1981 let DecoderMethod = "DecodeVLDST3Instruction"; 1982} 1983 1984def VST3d8_UPD : VST3DWB<0b0100, {0,0,0,?}, "8">; 1985def VST3d16_UPD : VST3DWB<0b0100, {0,1,0,?}, "16">; 1986def VST3d32_UPD : VST3DWB<0b0100, {1,0,0,?}, "32">; 1987 1988def VST3d8Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 1989def VST3d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 1990def VST3d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 1991 1992// ...with double-spaced registers: 1993def VST3q8 : VST3D<0b0101, {0,0,0,?}, "8">; 1994def VST3q16 : VST3D<0b0101, {0,1,0,?}, "16">; 1995def VST3q32 : VST3D<0b0101, {1,0,0,?}, "32">; 1996def VST3q8_UPD : VST3DWB<0b0101, {0,0,0,?}, "8">; 1997def VST3q16_UPD : VST3DWB<0b0101, {0,1,0,?}, "16">; 1998def VST3q32_UPD : VST3DWB<0b0101, {1,0,0,?}, "32">; 1999 2000def VST3q8Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 2001def VST3q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 2002def VST3q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 2003 2004// ...alternate versions to be allocated odd register numbers: 2005def VST3q8oddPseudo : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>; 2006def VST3q16oddPseudo : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>; 2007def VST3q32oddPseudo : VSTQQQQPseudo<IIC_VST3>, Sched<[WriteVST3]>; 2008 2009def VST3q8oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 2010def VST3q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 2011def VST3q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST3u>, Sched<[WriteVST3]>; 2012 2013// VST4 : Vector Store (multiple 4-element structures) 2014class VST4D<bits<4> op11_8, bits<4> op7_4, string Dt> 2015 : NLdSt<0, 0b00, op11_8, op7_4, (outs), 2016 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), 2017 IIC_VST4, "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn", 2018 "", []>, Sched<[WriteVST4]> { 2019 let Rm = 0b1111; 2020 let Inst{5-4} = Rn{5-4}; 2021 let DecoderMethod = "DecodeVLDST4Instruction"; 2022} 2023 2024def VST4d8 : VST4D<0b0000, {0,0,?,?}, "8">; 2025def VST4d16 : VST4D<0b0000, {0,1,?,?}, "16">; 2026def VST4d32 : VST4D<0b0000, {1,0,?,?}, "32">; 2027 2028def VST4d8Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>; 2029def VST4d16Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>; 2030def VST4d32Pseudo : VSTQQPseudo<IIC_VST4>, Sched<[WriteVST4]>; 2031 2032// ...with address register writeback: 2033class VST4DWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2034 : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), 2035 (ins addrmode6:$Rn, am6offset:$Rm, 2036 DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST4u, 2037 "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", 2038 "$Rn.addr = $wb", []>, Sched<[WriteVST4]> { 2039 let Inst{5-4} = Rn{5-4}; 2040 let DecoderMethod = "DecodeVLDST4Instruction"; 2041} 2042 2043def VST4d8_UPD : VST4DWB<0b0000, {0,0,?,?}, "8">; 2044def VST4d16_UPD : VST4DWB<0b0000, {0,1,?,?}, "16">; 2045def VST4d32_UPD : VST4DWB<0b0000, {1,0,?,?}, "32">; 2046 2047def VST4d8Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2048def VST4d16Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2049def VST4d32Pseudo_UPD : VSTQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2050 2051// ...with double-spaced registers: 2052def VST4q8 : VST4D<0b0001, {0,0,?,?}, "8">; 2053def VST4q16 : VST4D<0b0001, {0,1,?,?}, "16">; 2054def VST4q32 : VST4D<0b0001, {1,0,?,?}, "32">; 2055def VST4q8_UPD : VST4DWB<0b0001, {0,0,?,?}, "8">; 2056def VST4q16_UPD : VST4DWB<0b0001, {0,1,?,?}, "16">; 2057def VST4q32_UPD : VST4DWB<0b0001, {1,0,?,?}, "32">; 2058 2059def VST4q8Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2060def VST4q16Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2061def VST4q32Pseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2062 2063// ...alternate versions to be allocated odd register numbers: 2064def VST4q8oddPseudo : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>; 2065def VST4q16oddPseudo : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>; 2066def VST4q32oddPseudo : VSTQQQQPseudo<IIC_VST4>, Sched<[WriteVST4]>; 2067 2068def VST4q8oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2069def VST4q16oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2070def VST4q32oddPseudo_UPD : VSTQQQQWBPseudo<IIC_VST4u>, Sched<[WriteVST4]>; 2071 2072} // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 2073 2074// Classes for VST*LN pseudo-instructions with multi-register operands. 2075// These are expanded to real instructions after register allocation. 2076class VSTQLNPseudo<InstrItinClass itin> 2077 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QPR:$src, nohash_imm:$lane), 2078 itin, "">; 2079class VSTQLNWBPseudo<InstrItinClass itin> 2080 : PseudoNLdSt<(outs GPR:$wb), 2081 (ins addrmode6:$addr, am6offset:$offset, QPR:$src, 2082 nohash_imm:$lane), itin, "$addr.addr = $wb">; 2083class VSTQQLNPseudo<InstrItinClass itin> 2084 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQPR:$src, nohash_imm:$lane), 2085 itin, "">; 2086class VSTQQLNWBPseudo<InstrItinClass itin> 2087 : PseudoNLdSt<(outs GPR:$wb), 2088 (ins addrmode6:$addr, am6offset:$offset, QQPR:$src, 2089 nohash_imm:$lane), itin, "$addr.addr = $wb">; 2090class VSTQQQQLNPseudo<InstrItinClass itin> 2091 : PseudoNLdSt<(outs), (ins addrmode6:$addr, QQQQPR:$src, nohash_imm:$lane), 2092 itin, "">; 2093class VSTQQQQLNWBPseudo<InstrItinClass itin> 2094 : PseudoNLdSt<(outs GPR:$wb), 2095 (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src, 2096 nohash_imm:$lane), itin, "$addr.addr = $wb">; 2097 2098// VST1LN : Vector Store (single element from one lane) 2099class VST1LN<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 2100 PatFrag StoreOp, SDNode ExtractOp, Operand AddrMode> 2101 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2102 (ins AddrMode:$Rn, DPR:$Vd, nohash_imm:$lane), 2103 IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "", 2104 [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), AddrMode:$Rn)]>, 2105 Sched<[WriteVST1]> { 2106 let Rm = 0b1111; 2107 let DecoderMethod = "DecodeVST1LN"; 2108} 2109class VST1QLNPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp> 2110 : VSTQLNPseudo<IIC_VST1ln>, Sched<[WriteVST1]> { 2111 let Pattern = [(StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), 2112 addrmode6:$addr)]; 2113} 2114 2115def VST1LNd8 : VST1LN<0b0000, {?,?,?,0}, "8", v8i8, truncstorei8, 2116 ARMvgetlaneu, addrmode6> { 2117 let Inst{7-5} = lane{2-0}; 2118} 2119def VST1LNd16 : VST1LN<0b0100, {?,?,0,?}, "16", v4i16, truncstorei16, 2120 ARMvgetlaneu, addrmode6> { 2121 let Inst{7-6} = lane{1-0}; 2122 let Inst{4} = Rn{4}; 2123} 2124 2125def VST1LNd32 : VST1LN<0b1000, {?,0,?,?}, "32", v2i32, store, extractelt, 2126 addrmode6oneL32> { 2127 let Inst{7} = lane{0}; 2128 let Inst{5-4} = Rn{5-4}; 2129} 2130 2131def VST1LNq8Pseudo : VST1QLNPseudo<v16i8, truncstorei8, ARMvgetlaneu>; 2132def VST1LNq16Pseudo : VST1QLNPseudo<v8i16, truncstorei16, ARMvgetlaneu>; 2133def VST1LNq32Pseudo : VST1QLNPseudo<v4i32, store, extractelt>; 2134 2135let Predicates = [HasNEON] in { 2136def : Pat<(store (extractelt (v2f32 DPR:$src), imm:$lane), addrmode6:$addr), 2137 (VST1LNd32 addrmode6:$addr, DPR:$src, imm:$lane)>; 2138def : Pat<(store (extractelt (v4f32 QPR:$src), imm:$lane), addrmode6:$addr), 2139 (VST1LNq32Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>; 2140 2141def : Pat<(store (extractelt (v4f16 DPR:$src), imm:$lane), addrmode6:$addr), 2142 (VST1LNd16 addrmode6:$addr, DPR:$src, imm:$lane)>; 2143def : Pat<(store (extractelt (v8f16 QPR:$src), imm:$lane), addrmode6:$addr), 2144 (VST1LNq16Pseudo addrmode6:$addr, QPR:$src, imm:$lane)>; 2145} 2146 2147// ...with address register writeback: 2148class VST1LNWB<bits<4> op11_8, bits<4> op7_4, string Dt, ValueType Ty, 2149 PatFrag StoreOp, SDNode ExtractOp, Operand AdrMode> 2150 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2151 (ins AdrMode:$Rn, am6offset:$Rm, 2152 DPR:$Vd, nohash_imm:$lane), IIC_VST1lnu, "vst1", Dt, 2153 "\\{$Vd[$lane]\\}, $Rn$Rm", 2154 "$Rn.addr = $wb", 2155 [(set GPR:$wb, (StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), 2156 AdrMode:$Rn, am6offset:$Rm))]>, 2157 Sched<[WriteVST1]> { 2158 let DecoderMethod = "DecodeVST1LN"; 2159} 2160class VST1QLNWBPseudo<ValueType Ty, PatFrag StoreOp, SDNode ExtractOp> 2161 : VSTQLNWBPseudo<IIC_VST1lnu>, Sched<[WriteVST1]> { 2162 let Pattern = [(set GPR:$wb, (StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), 2163 addrmode6:$addr, am6offset:$offset))]; 2164} 2165 2166def VST1LNd8_UPD : VST1LNWB<0b0000, {?,?,?,0}, "8", v8i8, post_truncsti8, 2167 ARMvgetlaneu, addrmode6> { 2168 let Inst{7-5} = lane{2-0}; 2169} 2170def VST1LNd16_UPD : VST1LNWB<0b0100, {?,?,0,?}, "16", v4i16, post_truncsti16, 2171 ARMvgetlaneu, addrmode6> { 2172 let Inst{7-6} = lane{1-0}; 2173 let Inst{4} = Rn{4}; 2174} 2175def VST1LNd32_UPD : VST1LNWB<0b1000, {?,0,?,?}, "32", v2i32, post_store, 2176 extractelt, addrmode6oneL32> { 2177 let Inst{7} = lane{0}; 2178 let Inst{5-4} = Rn{5-4}; 2179} 2180 2181def VST1LNq8Pseudo_UPD : VST1QLNWBPseudo<v16i8, post_truncsti8, ARMvgetlaneu>; 2182def VST1LNq16Pseudo_UPD : VST1QLNWBPseudo<v8i16, post_truncsti16,ARMvgetlaneu>; 2183def VST1LNq32Pseudo_UPD : VST1QLNWBPseudo<v4i32, post_store, extractelt>; 2184 2185let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in { 2186 2187// VST2LN : Vector Store (single 2-element structure from one lane) 2188class VST2LN<bits<4> op11_8, bits<4> op7_4, string Dt> 2189 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2190 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, nohash_imm:$lane), 2191 IIC_VST2ln, "vst2", Dt, "\\{$Vd[$lane], $src2[$lane]\\}, $Rn", 2192 "", []>, Sched<[WriteVST1]> { 2193 let Rm = 0b1111; 2194 let Inst{4} = Rn{4}; 2195 let DecoderMethod = "DecodeVST2LN"; 2196} 2197 2198def VST2LNd8 : VST2LN<0b0001, {?,?,?,?}, "8"> { 2199 let Inst{7-5} = lane{2-0}; 2200} 2201def VST2LNd16 : VST2LN<0b0101, {?,?,0,?}, "16"> { 2202 let Inst{7-6} = lane{1-0}; 2203} 2204def VST2LNd32 : VST2LN<0b1001, {?,0,0,?}, "32"> { 2205 let Inst{7} = lane{0}; 2206} 2207 2208def VST2LNd8Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>; 2209def VST2LNd16Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>; 2210def VST2LNd32Pseudo : VSTQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>; 2211 2212// ...with double-spaced registers: 2213def VST2LNq16 : VST2LN<0b0101, {?,?,1,?}, "16"> { 2214 let Inst{7-6} = lane{1-0}; 2215 let Inst{4} = Rn{4}; 2216} 2217def VST2LNq32 : VST2LN<0b1001, {?,1,0,?}, "32"> { 2218 let Inst{7} = lane{0}; 2219 let Inst{4} = Rn{4}; 2220} 2221 2222def VST2LNq16Pseudo : VSTQQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>; 2223def VST2LNq32Pseudo : VSTQQLNPseudo<IIC_VST2ln>, Sched<[WriteVST1]>; 2224 2225// ...with address register writeback: 2226class VST2LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2227 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2228 (ins addrmode6:$Rn, am6offset:$Rm, 2229 DPR:$Vd, DPR:$src2, nohash_imm:$lane), IIC_VST2lnu, "vst2", Dt, 2230 "\\{$Vd[$lane], $src2[$lane]\\}, $Rn$Rm", 2231 "$Rn.addr = $wb", []> { 2232 let Inst{4} = Rn{4}; 2233 let DecoderMethod = "DecodeVST2LN"; 2234} 2235 2236def VST2LNd8_UPD : VST2LNWB<0b0001, {?,?,?,?}, "8"> { 2237 let Inst{7-5} = lane{2-0}; 2238} 2239def VST2LNd16_UPD : VST2LNWB<0b0101, {?,?,0,?}, "16"> { 2240 let Inst{7-6} = lane{1-0}; 2241} 2242def VST2LNd32_UPD : VST2LNWB<0b1001, {?,0,0,?}, "32"> { 2243 let Inst{7} = lane{0}; 2244} 2245 2246def VST2LNd8Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>; 2247def VST2LNd16Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>; 2248def VST2LNd32Pseudo_UPD : VSTQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>; 2249 2250def VST2LNq16_UPD : VST2LNWB<0b0101, {?,?,1,?}, "16"> { 2251 let Inst{7-6} = lane{1-0}; 2252} 2253def VST2LNq32_UPD : VST2LNWB<0b1001, {?,1,0,?}, "32"> { 2254 let Inst{7} = lane{0}; 2255} 2256 2257def VST2LNq16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>; 2258def VST2LNq32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST2lnu>, Sched<[WriteVST1]>; 2259 2260// VST3LN : Vector Store (single 3-element structure from one lane) 2261class VST3LN<bits<4> op11_8, bits<4> op7_4, string Dt> 2262 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2263 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, 2264 nohash_imm:$lane), IIC_VST3ln, "vst3", Dt, 2265 "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn", "", []>, 2266 Sched<[WriteVST2]> { 2267 let Rm = 0b1111; 2268 let DecoderMethod = "DecodeVST3LN"; 2269} 2270 2271def VST3LNd8 : VST3LN<0b0010, {?,?,?,0}, "8"> { 2272 let Inst{7-5} = lane{2-0}; 2273} 2274def VST3LNd16 : VST3LN<0b0110, {?,?,0,0}, "16"> { 2275 let Inst{7-6} = lane{1-0}; 2276} 2277def VST3LNd32 : VST3LN<0b1010, {?,0,0,0}, "32"> { 2278 let Inst{7} = lane{0}; 2279} 2280 2281def VST3LNd8Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>; 2282def VST3LNd16Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>; 2283def VST3LNd32Pseudo : VSTQQLNPseudo<IIC_VST3ln>, Sched<[WriteVST2]>; 2284 2285// ...with double-spaced registers: 2286def VST3LNq16 : VST3LN<0b0110, {?,?,1,0}, "16"> { 2287 let Inst{7-6} = lane{1-0}; 2288} 2289def VST3LNq32 : VST3LN<0b1010, {?,1,0,0}, "32"> { 2290 let Inst{7} = lane{0}; 2291} 2292 2293def VST3LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>; 2294def VST3LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST3ln>; 2295 2296// ...with address register writeback: 2297class VST3LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2298 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2299 (ins addrmode6:$Rn, am6offset:$Rm, 2300 DPR:$Vd, DPR:$src2, DPR:$src3, nohash_imm:$lane), 2301 IIC_VST3lnu, "vst3", Dt, 2302 "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn$Rm", 2303 "$Rn.addr = $wb", []> { 2304 let DecoderMethod = "DecodeVST3LN"; 2305} 2306 2307def VST3LNd8_UPD : VST3LNWB<0b0010, {?,?,?,0}, "8"> { 2308 let Inst{7-5} = lane{2-0}; 2309} 2310def VST3LNd16_UPD : VST3LNWB<0b0110, {?,?,0,0}, "16"> { 2311 let Inst{7-6} = lane{1-0}; 2312} 2313def VST3LNd32_UPD : VST3LNWB<0b1010, {?,0,0,0}, "32"> { 2314 let Inst{7} = lane{0}; 2315} 2316 2317def VST3LNd8Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>; 2318def VST3LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>; 2319def VST3LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>; 2320 2321def VST3LNq16_UPD : VST3LNWB<0b0110, {?,?,1,0}, "16"> { 2322 let Inst{7-6} = lane{1-0}; 2323} 2324def VST3LNq32_UPD : VST3LNWB<0b1010, {?,1,0,0}, "32"> { 2325 let Inst{7} = lane{0}; 2326} 2327 2328def VST3LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>; 2329def VST3LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST3lnu>, Sched<[WriteVST2]>; 2330 2331// VST4LN : Vector Store (single 4-element structure from one lane) 2332class VST4LN<bits<4> op11_8, bits<4> op7_4, string Dt> 2333 : NLdStLn<1, 0b00, op11_8, op7_4, (outs), 2334 (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, 2335 nohash_imm:$lane), IIC_VST4ln, "vst4", Dt, 2336 "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn", 2337 "", []>, Sched<[WriteVST2]> { 2338 let Rm = 0b1111; 2339 let Inst{4} = Rn{4}; 2340 let DecoderMethod = "DecodeVST4LN"; 2341} 2342 2343def VST4LNd8 : VST4LN<0b0011, {?,?,?,?}, "8"> { 2344 let Inst{7-5} = lane{2-0}; 2345} 2346def VST4LNd16 : VST4LN<0b0111, {?,?,0,?}, "16"> { 2347 let Inst{7-6} = lane{1-0}; 2348} 2349def VST4LNd32 : VST4LN<0b1011, {?,0,?,?}, "32"> { 2350 let Inst{7} = lane{0}; 2351 let Inst{5} = Rn{5}; 2352} 2353 2354def VST4LNd8Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>; 2355def VST4LNd16Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>; 2356def VST4LNd32Pseudo : VSTQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>; 2357 2358// ...with double-spaced registers: 2359def VST4LNq16 : VST4LN<0b0111, {?,?,1,?}, "16"> { 2360 let Inst{7-6} = lane{1-0}; 2361} 2362def VST4LNq32 : VST4LN<0b1011, {?,1,?,?}, "32"> { 2363 let Inst{7} = lane{0}; 2364 let Inst{5} = Rn{5}; 2365} 2366 2367def VST4LNq16Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>; 2368def VST4LNq32Pseudo : VSTQQQQLNPseudo<IIC_VST4ln>, Sched<[WriteVST2]>; 2369 2370// ...with address register writeback: 2371class VST4LNWB<bits<4> op11_8, bits<4> op7_4, string Dt> 2372 : NLdStLn<1, 0b00, op11_8, op7_4, (outs GPR:$wb), 2373 (ins addrmode6:$Rn, am6offset:$Rm, 2374 DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane), 2375 IIC_VST4lnu, "vst4", Dt, 2376 "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn$Rm", 2377 "$Rn.addr = $wb", []> { 2378 let Inst{4} = Rn{4}; 2379 let DecoderMethod = "DecodeVST4LN"; 2380} 2381 2382def VST4LNd8_UPD : VST4LNWB<0b0011, {?,?,?,?}, "8"> { 2383 let Inst{7-5} = lane{2-0}; 2384} 2385def VST4LNd16_UPD : VST4LNWB<0b0111, {?,?,0,?}, "16"> { 2386 let Inst{7-6} = lane{1-0}; 2387} 2388def VST4LNd32_UPD : VST4LNWB<0b1011, {?,0,?,?}, "32"> { 2389 let Inst{7} = lane{0}; 2390 let Inst{5} = Rn{5}; 2391} 2392 2393def VST4LNd8Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>; 2394def VST4LNd16Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>; 2395def VST4LNd32Pseudo_UPD : VSTQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>; 2396 2397def VST4LNq16_UPD : VST4LNWB<0b0111, {?,?,1,?}, "16"> { 2398 let Inst{7-6} = lane{1-0}; 2399} 2400def VST4LNq32_UPD : VST4LNWB<0b1011, {?,1,?,?}, "32"> { 2401 let Inst{7} = lane{0}; 2402 let Inst{5} = Rn{5}; 2403} 2404 2405def VST4LNq16Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>; 2406def VST4LNq32Pseudo_UPD : VSTQQQQLNWBPseudo<IIC_VST4lnu>, Sched<[WriteVST2]>; 2407 2408} // mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 2409 2410// Use vld1/vst1 for unaligned f64 load / store 2411let Predicates = [IsLE,HasNEON] in { 2412def : Pat<(f64 (hword_alignedload addrmode6:$addr)), 2413 (VLD1d16 addrmode6:$addr)>; 2414def : Pat<(hword_alignedstore (f64 DPR:$value), addrmode6:$addr), 2415 (VST1d16 addrmode6:$addr, DPR:$value)>; 2416def : Pat<(f64 (byte_alignedload addrmode6:$addr)), 2417 (VLD1d8 addrmode6:$addr)>; 2418def : Pat<(byte_alignedstore (f64 DPR:$value), addrmode6:$addr), 2419 (VST1d8 addrmode6:$addr, DPR:$value)>; 2420} 2421let Predicates = [IsBE,HasNEON] in { 2422def : Pat<(f64 (non_word_alignedload addrmode6:$addr)), 2423 (VLD1d64 addrmode6:$addr)>; 2424def : Pat<(non_word_alignedstore (f64 DPR:$value), addrmode6:$addr), 2425 (VST1d64 addrmode6:$addr, DPR:$value)>; 2426} 2427 2428// Use vld1/vst1 for Q and QQ. Also use them for unaligned v2f64 2429// load / store if it's legal. 2430let Predicates = [HasNEON] in { 2431def : Pat<(v2f64 (dword_alignedload addrmode6:$addr)), 2432 (VLD1q64 addrmode6:$addr)>; 2433def : Pat<(dword_alignedstore (v2f64 QPR:$value), addrmode6:$addr), 2434 (VST1q64 addrmode6:$addr, QPR:$value)>; 2435} 2436let Predicates = [IsLE,HasNEON] in { 2437def : Pat<(v2f64 (word_alignedload addrmode6:$addr)), 2438 (VLD1q32 addrmode6:$addr)>; 2439def : Pat<(word_alignedstore (v2f64 QPR:$value), addrmode6:$addr), 2440 (VST1q32 addrmode6:$addr, QPR:$value)>; 2441def : Pat<(v2f64 (hword_alignedload addrmode6:$addr)), 2442 (VLD1q16 addrmode6:$addr)>; 2443def : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr), 2444 (VST1q16 addrmode6:$addr, QPR:$value)>; 2445def : Pat<(v2f64 (byte_alignedload addrmode6:$addr)), 2446 (VLD1q8 addrmode6:$addr)>; 2447def : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr), 2448 (VST1q8 addrmode6:$addr, QPR:$value)>; 2449} 2450 2451//===----------------------------------------------------------------------===// 2452// NEON pattern fragments 2453//===----------------------------------------------------------------------===// 2454 2455// Extract D sub-registers of Q registers. 2456def DSubReg_i8_reg : SDNodeXForm<imm, [{ 2457 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2458 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/8, SDLoc(N), 2459 MVT::i32); 2460}]>; 2461def DSubReg_i16_reg : SDNodeXForm<imm, [{ 2462 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2463 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/4, SDLoc(N), 2464 MVT::i32); 2465}]>; 2466def DSubReg_i32_reg : SDNodeXForm<imm, [{ 2467 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2468 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue()/2, SDLoc(N), 2469 MVT::i32); 2470}]>; 2471def DSubReg_f64_reg : SDNodeXForm<imm, [{ 2472 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2473 return CurDAG->getTargetConstant(ARM::dsub_0 + N->getZExtValue(), SDLoc(N), 2474 MVT::i32); 2475}]>; 2476 2477// Extract S sub-registers of Q/D registers. 2478def SSubReg_f32_reg : SDNodeXForm<imm, [{ 2479 assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering"); 2480 return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue(), SDLoc(N), 2481 MVT::i32); 2482}]>; 2483 2484// Extract S sub-registers of Q/D registers containing a given f16 lane. 2485def SSubReg_f16_reg : SDNodeXForm<imm, [{ 2486 assert(ARM::ssub_3 == ARM::ssub_0+3 && "Unexpected subreg numbering"); 2487 return CurDAG->getTargetConstant(ARM::ssub_0 + N->getZExtValue()/2, SDLoc(N), 2488 MVT::i32); 2489}]>; 2490 2491// Translate lane numbers from Q registers to D subregs. 2492def SubReg_i8_lane : SDNodeXForm<imm, [{ 2493 return CurDAG->getTargetConstant(N->getZExtValue() & 7, SDLoc(N), MVT::i32); 2494}]>; 2495def SubReg_i16_lane : SDNodeXForm<imm, [{ 2496 return CurDAG->getTargetConstant(N->getZExtValue() & 3, SDLoc(N), MVT::i32); 2497}]>; 2498def SubReg_i32_lane : SDNodeXForm<imm, [{ 2499 return CurDAG->getTargetConstant(N->getZExtValue() & 1, SDLoc(N), MVT::i32); 2500}]>; 2501 2502//===----------------------------------------------------------------------===// 2503// Instruction Classes 2504//===----------------------------------------------------------------------===// 2505 2506// Basic 2-register operations: double- and quad-register. 2507class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2508 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, 2509 string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> 2510 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd), 2511 (ins DPR:$Vm), IIC_VUNAD, OpcodeStr, Dt,"$Vd, $Vm", "", 2512 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm))))]>; 2513class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2514 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, 2515 string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode> 2516 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd), 2517 (ins QPR:$Vm), IIC_VUNAQ, OpcodeStr, Dt,"$Vd, $Vm", "", 2518 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm))))]>; 2519 2520// Basic 2-register intrinsics, both double- and quad-register. 2521class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2522 bits<2> op17_16, bits<5> op11_7, bit op4, 2523 InstrItinClass itin, string OpcodeStr, string Dt, 2524 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2525 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd), 2526 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2527 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>; 2528class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2529 bits<2> op17_16, bits<5> op11_7, bit op4, 2530 InstrItinClass itin, string OpcodeStr, string Dt, 2531 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2532 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd), 2533 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2534 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>; 2535 2536// Same as above, but not predicated. 2537class N2VDIntnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, 2538 InstrItinClass itin, string OpcodeStr, string Dt, 2539 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2540 : N2Vnp<op19_18, op17_16, op10_8, op7, 0, (outs DPR:$Vd), (ins DPR:$Vm), 2541 itin, OpcodeStr, Dt, 2542 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>; 2543 2544class N2VQIntnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op7, 2545 InstrItinClass itin, string OpcodeStr, string Dt, 2546 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2547 : N2Vnp<op19_18, op17_16, op10_8, op7, 1, (outs QPR:$Vd), (ins QPR:$Vm), 2548 itin, OpcodeStr, Dt, 2549 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>; 2550 2551// Similar to NV2VQIntnp with some more encoding bits exposed (crypto). 2552class N2VQIntXnp<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6, 2553 bit op7, InstrItinClass itin, string OpcodeStr, string Dt, 2554 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2555 : N2Vnp<op19_18, op17_16, op10_8, op7, op6, (outs QPR:$Vd), (ins QPR:$Vm), 2556 itin, OpcodeStr, Dt, 2557 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>; 2558 2559// Same as N2VQIntXnp but with Vd as a src register. 2560class N2VQIntX2np<bits<2> op19_18, bits<2> op17_16, bits<3> op10_8, bit op6, 2561 bit op7, InstrItinClass itin, string OpcodeStr, string Dt, 2562 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2563 : N2Vnp<op19_18, op17_16, op10_8, op7, op6, 2564 (outs QPR:$Vd), (ins QPR:$src, QPR:$Vm), 2565 itin, OpcodeStr, Dt, 2566 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vm))))]> { 2567 let Constraints = "$src = $Vd"; 2568} 2569 2570// Narrow 2-register operations. 2571class N2VN<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2572 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2573 InstrItinClass itin, string OpcodeStr, string Dt, 2574 ValueType TyD, ValueType TyQ, SDNode OpNode> 2575 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd), 2576 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2577 [(set DPR:$Vd, (TyD (OpNode (TyQ QPR:$Vm))))]>; 2578 2579// Narrow 2-register intrinsics. 2580class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2581 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2582 InstrItinClass itin, string OpcodeStr, string Dt, 2583 ValueType TyD, ValueType TyQ, SDPatternOperator IntOp> 2584 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$Vd), 2585 (ins QPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2586 [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vm))))]>; 2587 2588// Long 2-register operations (currently only used for VMOVL). 2589class N2VL<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2590 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2591 InstrItinClass itin, string OpcodeStr, string Dt, 2592 ValueType TyQ, ValueType TyD, SDNode OpNode> 2593 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd), 2594 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2595 [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vm))))]>; 2596 2597// Long 2-register intrinsics. 2598class N2VLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 2599 bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, 2600 InstrItinClass itin, string OpcodeStr, string Dt, 2601 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp> 2602 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs QPR:$Vd), 2603 (ins DPR:$Vm), itin, OpcodeStr, Dt, "$Vd, $Vm", "", 2604 [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vm))))]>; 2605 2606// 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register. 2607class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr, string Dt> 2608 : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$Vd, DPR:$Vm), 2609 (ins DPR:$src1, DPR:$src2), IIC_VPERMD, 2610 OpcodeStr, Dt, "$Vd, $Vm", 2611 "$src1 = $Vd, $src2 = $Vm", []>; 2612class N2VQShuffle<bits<2> op19_18, bits<5> op11_7, 2613 InstrItinClass itin, string OpcodeStr, string Dt> 2614 : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$Vd, QPR:$Vm), 2615 (ins QPR:$src1, QPR:$src2), itin, OpcodeStr, Dt, "$Vd, $Vm", 2616 "$src1 = $Vd, $src2 = $Vm", []>; 2617 2618// Basic 3-register operations: double- and quad-register. 2619class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2620 InstrItinClass itin, string OpcodeStr, string Dt, 2621 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> 2622 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2623 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2624 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2625 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> { 2626 // All of these have a two-operand InstAlias. 2627 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2628 let isCommutable = Commutable; 2629} 2630// Same as N3VD but no data type. 2631class N3VDX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2632 InstrItinClass itin, string OpcodeStr, 2633 ValueType ResTy, ValueType OpTy, 2634 SDNode OpNode, bit Commutable> 2635 : N3VX<op24, op23, op21_20, op11_8, 0, op4, 2636 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2637 OpcodeStr, "$Vd, $Vn, $Vm", "", 2638 [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>{ 2639 // All of these have a two-operand InstAlias. 2640 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2641 let isCommutable = Commutable; 2642} 2643 2644class N3VDSL<bits<2> op21_20, bits<4> op11_8, 2645 InstrItinClass itin, string OpcodeStr, string Dt, 2646 ValueType Ty, SDNode ShOp> 2647 : N3VLane32<0, 1, op21_20, op11_8, 1, 0, 2648 (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2649 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2650 [(set (Ty DPR:$Vd), 2651 (Ty (ShOp (Ty DPR:$Vn), 2652 (Ty (ARMvduplane (Ty DPR_VFP2:$Vm),imm:$lane)))))]> { 2653 // All of these have a two-operand InstAlias. 2654 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2655 let isCommutable = 0; 2656} 2657class N3VDSL16<bits<2> op21_20, bits<4> op11_8, 2658 string OpcodeStr, string Dt, ValueType Ty, SDNode ShOp> 2659 : N3VLane16<0, 1, op21_20, op11_8, 1, 0, 2660 (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2661 NVMulSLFrm, IIC_VMULi16D, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane","", 2662 [(set (Ty DPR:$Vd), 2663 (Ty (ShOp (Ty DPR:$Vn), 2664 (Ty (ARMvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> { 2665 // All of these have a two-operand InstAlias. 2666 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2667 let isCommutable = 0; 2668} 2669 2670class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2671 InstrItinClass itin, string OpcodeStr, string Dt, 2672 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> 2673 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2674 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2675 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2676 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> { 2677 // All of these have a two-operand InstAlias. 2678 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2679 let isCommutable = Commutable; 2680} 2681class N3VQX<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2682 InstrItinClass itin, string OpcodeStr, 2683 ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> 2684 : N3VX<op24, op23, op21_20, op11_8, 1, op4, 2685 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2686 OpcodeStr, "$Vd, $Vn, $Vm", "", 2687 [(set QPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>{ 2688 // All of these have a two-operand InstAlias. 2689 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2690 let isCommutable = Commutable; 2691} 2692class N3VQSL<bits<2> op21_20, bits<4> op11_8, 2693 InstrItinClass itin, string OpcodeStr, string Dt, 2694 ValueType ResTy, ValueType OpTy, SDNode ShOp> 2695 : N3VLane32<1, 1, op21_20, op11_8, 1, 0, 2696 (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2697 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2698 [(set (ResTy QPR:$Vd), 2699 (ResTy (ShOp (ResTy QPR:$Vn), 2700 (ResTy (ARMvduplane (OpTy DPR_VFP2:$Vm), 2701 imm:$lane)))))]> { 2702 // All of these have a two-operand InstAlias. 2703 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2704 let isCommutable = 0; 2705} 2706class N3VQSL16<bits<2> op21_20, bits<4> op11_8, string OpcodeStr, string Dt, 2707 ValueType ResTy, ValueType OpTy, SDNode ShOp> 2708 : N3VLane16<1, 1, op21_20, op11_8, 1, 0, 2709 (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2710 NVMulSLFrm, IIC_VMULi16Q, OpcodeStr, Dt,"$Vd, $Vn, $Vm$lane", "", 2711 [(set (ResTy QPR:$Vd), 2712 (ResTy (ShOp (ResTy QPR:$Vn), 2713 (ResTy (ARMvduplane (OpTy DPR_8:$Vm), 2714 imm:$lane)))))]> { 2715 // All of these have a two-operand InstAlias. 2716 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2717 let isCommutable = 0; 2718} 2719 2720// Basic 3-register intrinsics, both double- and quad-register. 2721class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2722 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2723 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable> 2724 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2725 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin, 2726 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2727 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> { 2728 // All of these have a two-operand InstAlias. 2729 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2730 let isCommutable = Commutable; 2731} 2732 2733class N3VDIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2734 bit op4, Format f, InstrItinClass itin, string OpcodeStr, 2735 string Dt, ValueType ResTy, ValueType OpTy, 2736 SDPatternOperator IntOp, bit Commutable> 2737 : N3Vnp<op27_23, op21_20, op11_8, op6, op4, 2738 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt, 2739 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>; 2740 2741class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2742 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp> 2743 : N3VLane32<0, 1, op21_20, op11_8, 1, 0, 2744 (outs DPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2745 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2746 [(set (Ty DPR:$Vd), 2747 (Ty (IntOp (Ty DPR:$Vn), 2748 (Ty (ARMvduplane (Ty DPR_VFP2:$Vm), 2749 imm:$lane)))))]> { 2750 let isCommutable = 0; 2751} 2752 2753class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2754 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp> 2755 : N3VLane16<0, 1, op21_20, op11_8, 1, 0, 2756 (outs DPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2757 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2758 [(set (Ty DPR:$Vd), 2759 (Ty (IntOp (Ty DPR:$Vn), 2760 (Ty (ARMvduplane (Ty DPR_8:$Vm), imm:$lane)))))]> { 2761 let isCommutable = 0; 2762} 2763class N3VDIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2764 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2765 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2766 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2767 (outs DPR:$Vd), (ins DPR:$Vm, DPR:$Vn), f, itin, 2768 OpcodeStr, Dt, "$Vd, $Vm, $Vn", "", 2769 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (OpTy DPR:$Vn))))]> { 2770 let TwoOperandAliasConstraint = "$Vm = $Vd"; 2771 let isCommutable = 0; 2772} 2773 2774class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2775 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2776 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp, bit Commutable> 2777 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2778 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, 2779 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 2780 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> { 2781 // All of these have a two-operand InstAlias. 2782 let TwoOperandAliasConstraint = "$Vn = $Vd"; 2783 let isCommutable = Commutable; 2784} 2785 2786class N3VQIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2787 bit op4, Format f, InstrItinClass itin, string OpcodeStr, 2788 string Dt, ValueType ResTy, ValueType OpTy, 2789 SDPatternOperator IntOp, bit Commutable> 2790 : N3Vnp<op27_23, op21_20, op11_8, op6, op4, 2791 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr, Dt, 2792 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>; 2793 2794// Same as N3VQIntnp but with Vd as a src register. 2795class N3VQInt3np<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 2796 bit op4, Format f, InstrItinClass itin, string OpcodeStr, 2797 string Dt, ValueType ResTy, ValueType OpTy, 2798 SDPatternOperator IntOp, bit Commutable> 2799 : N3Vnp<op27_23, op21_20, op11_8, op6, op4, 2800 (outs QPR:$Vd), (ins QPR:$src, QPR:$Vn, QPR:$Vm), 2801 f, itin, OpcodeStr, Dt, 2802 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src), (OpTy QPR:$Vn), 2803 (OpTy QPR:$Vm))))]> { 2804 let Constraints = "$src = $Vd"; 2805} 2806 2807class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2808 string OpcodeStr, string Dt, 2809 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2810 : N3VLane32<1, 1, op21_20, op11_8, 1, 0, 2811 (outs QPR:$Vd), (ins QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2812 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2813 [(set (ResTy QPR:$Vd), 2814 (ResTy (IntOp (ResTy QPR:$Vn), 2815 (ResTy (ARMvduplane (OpTy DPR_VFP2:$Vm), 2816 imm:$lane)))))]> { 2817 let isCommutable = 0; 2818} 2819class N3VQIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2820 string OpcodeStr, string Dt, 2821 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2822 : N3VLane16<1, 1, op21_20, op11_8, 1, 0, 2823 (outs QPR:$Vd), (ins QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2824 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 2825 [(set (ResTy QPR:$Vd), 2826 (ResTy (IntOp (ResTy QPR:$Vn), 2827 (ResTy (ARMvduplane (OpTy DPR_8:$Vm), 2828 imm:$lane)))))]> { 2829 let isCommutable = 0; 2830} 2831class N3VQIntSh<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2832 Format f, InstrItinClass itin, string OpcodeStr, string Dt, 2833 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2834 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2835 (outs QPR:$Vd), (ins QPR:$Vm, QPR:$Vn), f, itin, 2836 OpcodeStr, Dt, "$Vd, $Vm, $Vn", "", 2837 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (OpTy QPR:$Vn))))]> { 2838 let TwoOperandAliasConstraint = "$Vm = $Vd"; 2839 let isCommutable = 0; 2840} 2841 2842// Multiply-Add/Sub operations: double- and quad-register. 2843class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2844 InstrItinClass itin, string OpcodeStr, string Dt, 2845 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator OpNode> 2846 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2847 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2848 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2849 [(set DPR:$Vd, (Ty (OpNode DPR:$src1, 2850 (Ty (MulOp DPR:$Vn, DPR:$Vm)))))]>; 2851 2852class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2853 string OpcodeStr, string Dt, 2854 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp> 2855 : N3VLane32<0, 1, op21_20, op11_8, 1, 0, 2856 (outs DPR:$Vd), 2857 (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2858 NVMulSLFrm, itin, 2859 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2860 [(set (Ty DPR:$Vd), 2861 (Ty (ShOp (Ty DPR:$src1), 2862 (Ty (MulOp DPR:$Vn, 2863 (Ty (ARMvduplane (Ty DPR_VFP2:$Vm), 2864 imm:$lane)))))))]>; 2865class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2866 string OpcodeStr, string Dt, 2867 ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp> 2868 : N3VLane16<0, 1, op21_20, op11_8, 1, 0, 2869 (outs DPR:$Vd), 2870 (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2871 NVMulSLFrm, itin, 2872 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2873 [(set (Ty DPR:$Vd), 2874 (Ty (ShOp (Ty DPR:$src1), 2875 (Ty (MulOp DPR:$Vn, 2876 (Ty (ARMvduplane (Ty DPR_8:$Vm), 2877 imm:$lane)))))))]>; 2878 2879class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2880 InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, 2881 SDPatternOperator MulOp, SDPatternOperator OpNode> 2882 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2883 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2884 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2885 [(set QPR:$Vd, (Ty (OpNode QPR:$src1, 2886 (Ty (MulOp QPR:$Vn, QPR:$Vm)))))]>; 2887class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2888 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 2889 SDPatternOperator MulOp, SDPatternOperator ShOp> 2890 : N3VLane32<1, 1, op21_20, op11_8, 1, 0, 2891 (outs QPR:$Vd), 2892 (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2893 NVMulSLFrm, itin, 2894 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2895 [(set (ResTy QPR:$Vd), 2896 (ResTy (ShOp (ResTy QPR:$src1), 2897 (ResTy (MulOp QPR:$Vn, 2898 (ResTy (ARMvduplane (OpTy DPR_VFP2:$Vm), 2899 imm:$lane)))))))]>; 2900class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 2901 string OpcodeStr, string Dt, 2902 ValueType ResTy, ValueType OpTy, 2903 SDPatternOperator MulOp, SDPatternOperator ShOp> 2904 : N3VLane16<1, 1, op21_20, op11_8, 1, 0, 2905 (outs QPR:$Vd), 2906 (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2907 NVMulSLFrm, itin, 2908 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2909 [(set (ResTy QPR:$Vd), 2910 (ResTy (ShOp (ResTy QPR:$src1), 2911 (ResTy (MulOp QPR:$Vn, 2912 (ResTy (ARMvduplane (OpTy DPR_8:$Vm), 2913 imm:$lane)))))))]>; 2914 2915// Neon Intrinsic-Op instructions (VABA): double- and quad-register. 2916class N3VDIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2917 InstrItinClass itin, string OpcodeStr, string Dt, 2918 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode> 2919 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2920 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2921 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2922 [(set DPR:$Vd, (Ty (OpNode DPR:$src1, 2923 (Ty (IntOp (Ty DPR:$Vn), (Ty DPR:$Vm))))))]>; 2924class N3VQIntOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2925 InstrItinClass itin, string OpcodeStr, string Dt, 2926 ValueType Ty, SDPatternOperator IntOp, SDNode OpNode> 2927 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2928 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2929 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2930 [(set QPR:$Vd, (Ty (OpNode QPR:$src1, 2931 (Ty (IntOp (Ty QPR:$Vn), (Ty QPR:$Vm))))))]>; 2932 2933// Neon 3-argument intrinsics, both double- and quad-register. 2934// The destination register is also used as the first source operand register. 2935class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2936 InstrItinClass itin, string OpcodeStr, string Dt, 2937 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2938 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2939 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2940 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2941 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$src1), 2942 (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>; 2943class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2944 InstrItinClass itin, string OpcodeStr, string Dt, 2945 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 2946 : N3V<op24, op23, op21_20, op11_8, 1, op4, 2947 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 2948 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2949 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$src1), 2950 (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>; 2951 2952// Long Multiply-Add/Sub operations. 2953class N3VLMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2954 InstrItinClass itin, string OpcodeStr, string Dt, 2955 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> 2956 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2957 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2958 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2959 [(set QPR:$Vd, (OpNode (TyQ QPR:$src1), 2960 (TyQ (MulOp (TyD DPR:$Vn), 2961 (TyD DPR:$Vm)))))]>; 2962class N3VLMulOpSL<bit op24, bits<2> op21_20, bits<4> op11_8, 2963 InstrItinClass itin, string OpcodeStr, string Dt, 2964 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> 2965 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), 2966 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 2967 NVMulSLFrm, itin, 2968 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2969 [(set QPR:$Vd, 2970 (OpNode (TyQ QPR:$src1), 2971 (TyQ (MulOp (TyD DPR:$Vn), 2972 (TyD (ARMvduplane (TyD DPR_VFP2:$Vm), 2973 imm:$lane))))))]>; 2974class N3VLMulOpSL16<bit op24, bits<2> op21_20, bits<4> op11_8, 2975 InstrItinClass itin, string OpcodeStr, string Dt, 2976 ValueType TyQ, ValueType TyD, SDNode MulOp, SDNode OpNode> 2977 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, (outs QPR:$Vd), 2978 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 2979 NVMulSLFrm, itin, 2980 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 2981 [(set QPR:$Vd, 2982 (OpNode (TyQ QPR:$src1), 2983 (TyQ (MulOp (TyD DPR:$Vn), 2984 (TyD (ARMvduplane (TyD DPR_8:$Vm), 2985 imm:$lane))))))]>; 2986 2987// Long Intrinsic-Op vector operations with explicit extend (VABAL). 2988class N3VLIntExtOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 2989 InstrItinClass itin, string OpcodeStr, string Dt, 2990 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp, 2991 SDNode OpNode> 2992 : N3V<op24, op23, op21_20, op11_8, 0, op4, 2993 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 2994 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 2995 [(set QPR:$Vd, (OpNode (TyQ QPR:$src1), 2996 (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn), 2997 (TyD DPR:$Vm)))))))]>; 2998 2999// Neon Long 3-argument intrinsic. The destination register is 3000// a quad-register and is also used as the first source operand register. 3001class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3002 InstrItinClass itin, string OpcodeStr, string Dt, 3003 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp> 3004 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3005 (outs QPR:$Vd), (ins QPR:$src1, DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 3006 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "$src1 = $Vd", 3007 [(set QPR:$Vd, 3008 (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$Vn), (TyD DPR:$Vm))))]>; 3009class N3VLInt3SL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 3010 string OpcodeStr, string Dt, 3011 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3012 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, 3013 (outs QPR:$Vd), 3014 (ins QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 3015 NVMulSLFrm, itin, 3016 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 3017 [(set (ResTy QPR:$Vd), 3018 (ResTy (IntOp (ResTy QPR:$src1), 3019 (OpTy DPR:$Vn), 3020 (OpTy (ARMvduplane (OpTy DPR_VFP2:$Vm), 3021 imm:$lane)))))]>; 3022class N3VLInt3SL16<bit op24, bits<2> op21_20, bits<4> op11_8, 3023 InstrItinClass itin, string OpcodeStr, string Dt, 3024 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3025 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, 3026 (outs QPR:$Vd), 3027 (ins QPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 3028 NVMulSLFrm, itin, 3029 OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "$src1 = $Vd", 3030 [(set (ResTy QPR:$Vd), 3031 (ResTy (IntOp (ResTy QPR:$src1), 3032 (OpTy DPR:$Vn), 3033 (OpTy (ARMvduplane (OpTy DPR_8:$Vm), 3034 imm:$lane)))))]>; 3035 3036// Narrowing 3-register intrinsics. 3037class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3038 string OpcodeStr, string Dt, ValueType TyD, ValueType TyQ, 3039 SDPatternOperator IntOp, bit Commutable> 3040 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3041 (outs DPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINi4D, 3042 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3043 [(set DPR:$Vd, (TyD (IntOp (TyQ QPR:$Vn), (TyQ QPR:$Vm))))]> { 3044 let isCommutable = Commutable; 3045} 3046 3047// Long 3-register operations. 3048class N3VL<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3049 InstrItinClass itin, string OpcodeStr, string Dt, 3050 ValueType TyQ, ValueType TyD, SDNode OpNode, bit Commutable> 3051 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3052 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 3053 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3054 [(set QPR:$Vd, (TyQ (OpNode (TyD DPR:$Vn), (TyD DPR:$Vm))))]> { 3055 let isCommutable = Commutable; 3056} 3057 3058class N3VLSL<bit op24, bits<2> op21_20, bits<4> op11_8, 3059 InstrItinClass itin, string OpcodeStr, string Dt, 3060 ValueType TyQ, ValueType TyD, SDNode OpNode> 3061 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, 3062 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 3063 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 3064 [(set QPR:$Vd, 3065 (TyQ (OpNode (TyD DPR:$Vn), 3066 (TyD (ARMvduplane (TyD DPR_VFP2:$Vm),imm:$lane)))))]>; 3067class N3VLSL16<bit op24, bits<2> op21_20, bits<4> op11_8, 3068 InstrItinClass itin, string OpcodeStr, string Dt, 3069 ValueType TyQ, ValueType TyD, SDNode OpNode> 3070 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, 3071 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 3072 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 3073 [(set QPR:$Vd, 3074 (TyQ (OpNode (TyD DPR:$Vn), 3075 (TyD (ARMvduplane (TyD DPR_8:$Vm), imm:$lane)))))]>; 3076 3077// Long 3-register operations with explicitly extended operands. 3078class N3VLExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3079 InstrItinClass itin, string OpcodeStr, string Dt, 3080 ValueType TyQ, ValueType TyD, SDNode OpNode, SDNode ExtOp, 3081 bit Commutable> 3082 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3083 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 3084 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3085 [(set QPR:$Vd, (OpNode (TyQ (ExtOp (TyD DPR:$Vn))), 3086 (TyQ (ExtOp (TyD DPR:$Vm)))))]> { 3087 let isCommutable = Commutable; 3088} 3089 3090// Long 3-register intrinsics with explicit extend (VABDL). 3091class N3VLIntExt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3092 InstrItinClass itin, string OpcodeStr, string Dt, 3093 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, SDNode ExtOp, 3094 bit Commutable> 3095 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3096 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 3097 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3098 [(set QPR:$Vd, (TyQ (ExtOp (TyD (IntOp (TyD DPR:$Vn), 3099 (TyD DPR:$Vm))))))]> { 3100 let isCommutable = Commutable; 3101} 3102 3103// Long 3-register intrinsics. 3104class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3105 InstrItinClass itin, string OpcodeStr, string Dt, 3106 ValueType TyQ, ValueType TyD, SDPatternOperator IntOp, bit Commutable> 3107 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3108 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 3109 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3110 [(set QPR:$Vd, (TyQ (IntOp (TyD DPR:$Vn), (TyD DPR:$Vm))))]> { 3111 let isCommutable = Commutable; 3112} 3113 3114// Same as above, but not predicated. 3115class N3VLIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6, 3116 bit op4, InstrItinClass itin, string OpcodeStr, 3117 string Dt, ValueType ResTy, ValueType OpTy, 3118 SDPatternOperator IntOp, bit Commutable> 3119 : N3Vnp<op27_23, op21_20, op11_8, op6, op4, 3120 (outs QPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, OpcodeStr, Dt, 3121 [(set QPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>; 3122 3123class N3VLIntSL<bit op24, bits<2> op21_20, bits<4> op11_8, InstrItinClass itin, 3124 string OpcodeStr, string Dt, 3125 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3126 : N3VLane32<op24, 1, op21_20, op11_8, 1, 0, 3127 (outs QPR:$Vd), (ins DPR:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 3128 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 3129 [(set (ResTy QPR:$Vd), 3130 (ResTy (IntOp (OpTy DPR:$Vn), 3131 (OpTy (ARMvduplane (OpTy DPR_VFP2:$Vm), 3132 imm:$lane)))))]>; 3133class N3VLIntSL16<bit op24, bits<2> op21_20, bits<4> op11_8, 3134 InstrItinClass itin, string OpcodeStr, string Dt, 3135 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3136 : N3VLane16<op24, 1, op21_20, op11_8, 1, 0, 3137 (outs QPR:$Vd), (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane), 3138 NVMulSLFrm, itin, OpcodeStr, Dt, "$Vd, $Vn, $Vm$lane", "", 3139 [(set (ResTy QPR:$Vd), 3140 (ResTy (IntOp (OpTy DPR:$Vn), 3141 (OpTy (ARMvduplane (OpTy DPR_8:$Vm), 3142 imm:$lane)))))]>; 3143 3144// Wide 3-register operations. 3145class N3VW<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3146 string OpcodeStr, string Dt, ValueType TyQ, ValueType TyD, 3147 SDNode OpNode, SDNode ExtOp, bit Commutable> 3148 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3149 (outs QPR:$Vd), (ins QPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VSUBiD, 3150 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3151 [(set QPR:$Vd, (OpNode (TyQ QPR:$Vn), 3152 (TyQ (ExtOp (TyD DPR:$Vm)))))]> { 3153 // All of these have a two-operand InstAlias. 3154 let TwoOperandAliasConstraint = "$Vn = $Vd"; 3155 let isCommutable = Commutable; 3156} 3157 3158// Pairwise long 2-register intrinsics, both double- and quad-register. 3159class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 3160 bits<2> op17_16, bits<5> op11_7, bit op4, 3161 string OpcodeStr, string Dt, 3162 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3163 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$Vd), 3164 (ins DPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "", 3165 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm))))]>; 3166class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 3167 bits<2> op17_16, bits<5> op11_7, bit op4, 3168 string OpcodeStr, string Dt, 3169 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3170 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$Vd), 3171 (ins QPR:$Vm), IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "", 3172 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm))))]>; 3173 3174// Pairwise long 2-register accumulate intrinsics, 3175// both double- and quad-register. 3176// The destination register is also used as the first source operand register. 3177class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 3178 bits<2> op17_16, bits<5> op11_7, bit op4, 3179 string OpcodeStr, string Dt, 3180 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3181 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, 3182 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vm), IIC_VPALiD, 3183 OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd", 3184 [(set DPR:$Vd, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$Vm))))]>; 3185class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, 3186 bits<2> op17_16, bits<5> op11_7, bit op4, 3187 string OpcodeStr, string Dt, 3188 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp> 3189 : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, 3190 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vm), IIC_VPALiQ, 3191 OpcodeStr, Dt, "$Vd, $Vm", "$src1 = $Vd", 3192 [(set QPR:$Vd, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$Vm))))]>; 3193 3194// Shift by immediate, 3195// both double- and quad-register. 3196let TwoOperandAliasConstraint = "$Vm = $Vd" in { 3197class N2VDSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3198 Format f, InstrItinClass itin, Operand ImmTy, 3199 string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode> 3200 : N2VImm<op24, op23, op11_8, op7, 0, op4, 3201 (outs DPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), f, itin, 3202 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3203 [(set DPR:$Vd, (Ty (OpNode (Ty DPR:$Vm), (i32 imm:$SIMM))))]>; 3204class N2VQSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3205 Format f, InstrItinClass itin, Operand ImmTy, 3206 string OpcodeStr, string Dt, ValueType Ty, SDNode OpNode> 3207 : N2VImm<op24, op23, op11_8, op7, 1, op4, 3208 (outs QPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), f, itin, 3209 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3210 [(set QPR:$Vd, (Ty (OpNode (Ty QPR:$Vm), (i32 imm:$SIMM))))]>; 3211} 3212 3213// Long shift by immediate. 3214class N2VLSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 3215 string OpcodeStr, string Dt, 3216 ValueType ResTy, ValueType OpTy, Operand ImmTy, 3217 SDPatternOperator OpNode> 3218 : N2VImm<op24, op23, op11_8, op7, op6, op4, 3219 (outs QPR:$Vd), (ins DPR:$Vm, ImmTy:$SIMM), N2RegVShLFrm, 3220 IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3221 [(set QPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vm), ImmTy:$SIMM)))]>; 3222 3223// Narrow shift by immediate. 3224class N2VNSh<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, 3225 InstrItinClass itin, string OpcodeStr, string Dt, 3226 ValueType ResTy, ValueType OpTy, Operand ImmTy, 3227 SDPatternOperator OpNode> 3228 : N2VImm<op24, op23, op11_8, op7, op6, op4, 3229 (outs DPR:$Vd), (ins QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, itin, 3230 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3231 [(set DPR:$Vd, (ResTy (OpNode (OpTy QPR:$Vm), 3232 (i32 ImmTy:$SIMM))))]>; 3233 3234// Shift right by immediate and accumulate, 3235// both double- and quad-register. 3236let TwoOperandAliasConstraint = "$Vm = $Vd" in { 3237class N2VDShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3238 Operand ImmTy, string OpcodeStr, string Dt, 3239 ValueType Ty, SDNode ShOp> 3240 : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd), 3241 (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD, 3242 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 3243 [(set DPR:$Vd, (Ty (add DPR:$src1, 3244 (Ty (ShOp DPR:$Vm, (i32 imm:$SIMM))))))]>; 3245class N2VQShAdd<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3246 Operand ImmTy, string OpcodeStr, string Dt, 3247 ValueType Ty, SDNode ShOp> 3248 : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd), 3249 (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), N2RegVShRFrm, IIC_VPALiD, 3250 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 3251 [(set QPR:$Vd, (Ty (add QPR:$src1, 3252 (Ty (ShOp QPR:$Vm, (i32 imm:$SIMM))))))]>; 3253} 3254 3255// Shift by immediate and insert, 3256// both double- and quad-register. 3257let TwoOperandAliasConstraint = "$Vm = $Vd" in { 3258class N2VDShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3259 Operand ImmTy, Format f, string OpcodeStr, string Dt, 3260 ValueType Ty,SDNode ShOp> 3261 : N2VImm<op24, op23, op11_8, op7, 0, op4, (outs DPR:$Vd), 3262 (ins DPR:$src1, DPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiD, 3263 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 3264 [(set DPR:$Vd, (Ty (ShOp DPR:$src1, DPR:$Vm, (i32 imm:$SIMM))))]>; 3265class N2VQShIns<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3266 Operand ImmTy, Format f, string OpcodeStr, string Dt, 3267 ValueType Ty,SDNode ShOp> 3268 : N2VImm<op24, op23, op11_8, op7, 1, op4, (outs QPR:$Vd), 3269 (ins QPR:$src1, QPR:$Vm, ImmTy:$SIMM), f, IIC_VSHLiQ, 3270 OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "$src1 = $Vd", 3271 [(set QPR:$Vd, (Ty (ShOp QPR:$src1, QPR:$Vm, (i32 imm:$SIMM))))]>; 3272} 3273 3274// Convert, with fractional bits immediate, 3275// both double- and quad-register. 3276class N2VCvtD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3277 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 3278 SDPatternOperator IntOp> 3279 : N2VImm<op24, op23, op11_8, op7, 0, op4, 3280 (outs DPR:$Vd), (ins DPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm, 3281 IIC_VUNAD, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3282 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vm), (i32 imm:$SIMM))))]>; 3283class N2VCvtQ<bit op24, bit op23, bits<4> op11_8, bit op7, bit op4, 3284 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, 3285 SDPatternOperator IntOp> 3286 : N2VImm<op24, op23, op11_8, op7, 1, op4, 3287 (outs QPR:$Vd), (ins QPR:$Vm, neon_vcvt_imm32:$SIMM), NVCVTFrm, 3288 IIC_VUNAQ, OpcodeStr, Dt, "$Vd, $Vm, $SIMM", "", 3289 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vm), (i32 imm:$SIMM))))]>; 3290 3291//===----------------------------------------------------------------------===// 3292// Multiclasses 3293//===----------------------------------------------------------------------===// 3294 3295// Abbreviations used in multiclass suffixes: 3296// Q = quarter int (8 bit) elements 3297// H = half int (16 bit) elements 3298// S = single int (32 bit) elements 3299// D = double int (64 bit) elements 3300 3301// Neon 2-register vector operations and intrinsics. 3302 3303// Neon 2-register comparisons. 3304// source operand element sizes of 8, 16 and 32 bits: 3305multiclass N2V_QHS_cmp<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3306 bits<5> op11_7, bit op4, string opc, string Dt, 3307 string asm, PatFrag fc> { 3308 // 64-bit vector types. 3309 def v8i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 0, op4, 3310 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3311 opc, !strconcat(Dt, "8"), asm, "", 3312 [(set DPR:$Vd, (v8i8 (ARMvcmpz (v8i8 DPR:$Vm), fc)))]>; 3313 def v4i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4, 3314 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3315 opc, !strconcat(Dt, "16"), asm, "", 3316 [(set DPR:$Vd, (v4i16 (ARMvcmpz (v4i16 DPR:$Vm), fc)))]>; 3317 def v2i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4, 3318 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3319 opc, !strconcat(Dt, "32"), asm, "", 3320 [(set DPR:$Vd, (v2i32 (ARMvcmpz (v2i32 DPR:$Vm), fc)))]>; 3321 def v2f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 0, op4, 3322 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3323 opc, "f32", asm, "", 3324 [(set DPR:$Vd, (v2i32 (ARMvcmpz (v2f32 DPR:$Vm), fc)))]> { 3325 let Inst{10} = 1; // overwrite F = 1 3326 } 3327 def v4f16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 0, op4, 3328 (outs DPR:$Vd), (ins DPR:$Vm), NoItinerary, 3329 opc, "f16", asm, "", 3330 [(set DPR:$Vd, (v4i16 (ARMvcmpz (v4f16 DPR:$Vm), fc)))]>, 3331 Requires<[HasNEON,HasFullFP16]> { 3332 let Inst{10} = 1; // overwrite F = 1 3333 } 3334 3335 // 128-bit vector types. 3336 def v16i8 : N2V<op24_23, op21_20, 0b00, op17_16, op11_7, 1, op4, 3337 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3338 opc, !strconcat(Dt, "8"), asm, "", 3339 [(set QPR:$Vd, (v16i8 (ARMvcmpz (v16i8 QPR:$Vm), fc)))]>; 3340 def v8i16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4, 3341 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3342 opc, !strconcat(Dt, "16"), asm, "", 3343 [(set QPR:$Vd, (v8i16 (ARMvcmpz (v8i16 QPR:$Vm), fc)))]>; 3344 def v4i32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4, 3345 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3346 opc, !strconcat(Dt, "32"), asm, "", 3347 [(set QPR:$Vd, (v4i32 (ARMvcmpz (v4i32 QPR:$Vm), fc)))]>; 3348 def v4f32 : N2V<op24_23, op21_20, 0b10, op17_16, op11_7, 1, op4, 3349 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3350 opc, "f32", asm, "", 3351 [(set QPR:$Vd, (v4i32 (ARMvcmpz (v4f32 QPR:$Vm), fc)))]> { 3352 let Inst{10} = 1; // overwrite F = 1 3353 } 3354 def v8f16 : N2V<op24_23, op21_20, 0b01, op17_16, op11_7, 1, op4, 3355 (outs QPR:$Vd), (ins QPR:$Vm), NoItinerary, 3356 opc, "f16", asm, "", 3357 [(set QPR:$Vd, (v8i16 (ARMvcmpz (v8f16 QPR:$Vm), fc)))]>, 3358 Requires<[HasNEON,HasFullFP16]> { 3359 let Inst{10} = 1; // overwrite F = 1 3360 } 3361} 3362 3363// Neon 3-register comparisons. 3364class N3VQ_cmp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3365 InstrItinClass itin, string OpcodeStr, string Dt, 3366 ValueType ResTy, ValueType OpTy, PatFrag fc, bit Commutable> 3367 : N3V<op24, op23, op21_20, op11_8, 1, op4, 3368 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), N3RegFrm, itin, 3369 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3370 [(set QPR:$Vd, (ResTy (ARMvcmp (OpTy QPR:$Vn), (OpTy QPR:$Vm), fc)))]> { 3371 // All of these have a two-operand InstAlias. 3372 let TwoOperandAliasConstraint = "$Vn = $Vd"; 3373 let isCommutable = Commutable; 3374} 3375 3376class N3VD_cmp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4, 3377 InstrItinClass itin, string OpcodeStr, string Dt, 3378 ValueType ResTy, ValueType OpTy, PatFrag fc, bit Commutable> 3379 : N3V<op24, op23, op21_20, op11_8, 0, op4, 3380 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, 3381 OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", 3382 [(set DPR:$Vd, (ResTy (ARMvcmp (OpTy DPR:$Vn), (OpTy DPR:$Vm), fc)))]> { 3383 // All of these have a two-operand InstAlias. 3384 let TwoOperandAliasConstraint = "$Vn = $Vd"; 3385 let isCommutable = Commutable; 3386} 3387 3388multiclass N3V_QHS_cmp<bit op24, bit op23, bits<4> op11_8, bit op4, 3389 InstrItinClass itinD16, InstrItinClass itinD32, 3390 InstrItinClass itinQ16, InstrItinClass itinQ32, 3391 string OpcodeStr, string Dt, 3392 PatFrag fc, bit Commutable = 0> { 3393 // 64-bit vector types. 3394 def v8i8 : N3VD_cmp<op24, op23, 0b00, op11_8, op4, itinD16, 3395 OpcodeStr, !strconcat(Dt, "8"), 3396 v8i8, v8i8, fc, Commutable>; 3397 def v4i16 : N3VD_cmp<op24, op23, 0b01, op11_8, op4, itinD16, 3398 OpcodeStr, !strconcat(Dt, "16"), 3399 v4i16, v4i16, fc, Commutable>; 3400 def v2i32 : N3VD_cmp<op24, op23, 0b10, op11_8, op4, itinD32, 3401 OpcodeStr, !strconcat(Dt, "32"), 3402 v2i32, v2i32, fc, Commutable>; 3403 3404 // 128-bit vector types. 3405 def v16i8 : N3VQ_cmp<op24, op23, 0b00, op11_8, op4, itinQ16, 3406 OpcodeStr, !strconcat(Dt, "8"), 3407 v16i8, v16i8, fc, Commutable>; 3408 def v8i16 : N3VQ_cmp<op24, op23, 0b01, op11_8, op4, itinQ16, 3409 OpcodeStr, !strconcat(Dt, "16"), 3410 v8i16, v8i16, fc, Commutable>; 3411 def v4i32 : N3VQ_cmp<op24, op23, 0b10, op11_8, op4, itinQ32, 3412 OpcodeStr, !strconcat(Dt, "32"), 3413 v4i32, v4i32, fc, Commutable>; 3414} 3415 3416 3417// Neon 2-register vector intrinsics, 3418// element sizes of 8, 16 and 32 bits: 3419multiclass N2VInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3420 bits<5> op11_7, bit op4, 3421 InstrItinClass itinD, InstrItinClass itinQ, 3422 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3423 // 64-bit vector types. 3424 def v8i8 : N2VDInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3425 itinD, OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>; 3426 def v4i16 : N2VDInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3427 itinD, OpcodeStr, !strconcat(Dt, "16"),v4i16,v4i16,IntOp>; 3428 def v2i32 : N2VDInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3429 itinD, OpcodeStr, !strconcat(Dt, "32"),v2i32,v2i32,IntOp>; 3430 3431 // 128-bit vector types. 3432 def v16i8 : N2VQInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3433 itinQ, OpcodeStr, !strconcat(Dt, "8"), v16i8,v16i8,IntOp>; 3434 def v8i16 : N2VQInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3435 itinQ, OpcodeStr, !strconcat(Dt, "16"),v8i16,v8i16,IntOp>; 3436 def v4i32 : N2VQInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3437 itinQ, OpcodeStr, !strconcat(Dt, "32"),v4i32,v4i32,IntOp>; 3438} 3439 3440 3441// Neon Narrowing 2-register vector operations, 3442// source operand element sizes of 16, 32 and 64 bits: 3443multiclass N2VN_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3444 bits<5> op11_7, bit op6, bit op4, 3445 InstrItinClass itin, string OpcodeStr, string Dt, 3446 SDNode OpNode> { 3447 def v8i8 : N2VN<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4, 3448 itin, OpcodeStr, !strconcat(Dt, "16"), 3449 v8i8, v8i16, OpNode>; 3450 def v4i16 : N2VN<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4, 3451 itin, OpcodeStr, !strconcat(Dt, "32"), 3452 v4i16, v4i32, OpNode>; 3453 def v2i32 : N2VN<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4, 3454 itin, OpcodeStr, !strconcat(Dt, "64"), 3455 v2i32, v2i64, OpNode>; 3456} 3457 3458// Neon Narrowing 2-register vector intrinsics, 3459// source operand element sizes of 16, 32 and 64 bits: 3460multiclass N2VNInt_HSD<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3461 bits<5> op11_7, bit op6, bit op4, 3462 InstrItinClass itin, string OpcodeStr, string Dt, 3463 SDPatternOperator IntOp> { 3464 def v8i8 : N2VNInt<op24_23, op21_20, 0b00, op17_16, op11_7, op6, op4, 3465 itin, OpcodeStr, !strconcat(Dt, "16"), 3466 v8i8, v8i16, IntOp>; 3467 def v4i16 : N2VNInt<op24_23, op21_20, 0b01, op17_16, op11_7, op6, op4, 3468 itin, OpcodeStr, !strconcat(Dt, "32"), 3469 v4i16, v4i32, IntOp>; 3470 def v2i32 : N2VNInt<op24_23, op21_20, 0b10, op17_16, op11_7, op6, op4, 3471 itin, OpcodeStr, !strconcat(Dt, "64"), 3472 v2i32, v2i64, IntOp>; 3473} 3474 3475 3476// Neon Lengthening 2-register vector intrinsic (currently specific to VMOVL). 3477// source operand element sizes of 16, 32 and 64 bits: 3478multiclass N2VL_QHS<bits<2> op24_23, bits<5> op11_7, bit op6, bit op4, 3479 string OpcodeStr, string Dt, SDNode OpNode> { 3480 def v8i16 : N2VL<op24_23, 0b00, 0b10, 0b00, op11_7, op6, op4, IIC_VQUNAiD, 3481 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, OpNode>; 3482 def v4i32 : N2VL<op24_23, 0b01, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD, 3483 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, OpNode>; 3484 def v2i64 : N2VL<op24_23, 0b10, 0b00, 0b00, op11_7, op6, op4, IIC_VQUNAiD, 3485 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, OpNode>; 3486} 3487 3488 3489// Neon 3-register vector operations. 3490 3491// First with only element sizes of 8, 16 and 32 bits: 3492multiclass N3V_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3493 InstrItinClass itinD16, InstrItinClass itinD32, 3494 InstrItinClass itinQ16, InstrItinClass itinQ32, 3495 string OpcodeStr, string Dt, 3496 SDNode OpNode, bit Commutable = 0> { 3497 // 64-bit vector types. 3498 def v8i8 : N3VD<op24, op23, 0b00, op11_8, op4, itinD16, 3499 OpcodeStr, !strconcat(Dt, "8"), 3500 v8i8, v8i8, OpNode, Commutable>; 3501 def v4i16 : N3VD<op24, op23, 0b01, op11_8, op4, itinD16, 3502 OpcodeStr, !strconcat(Dt, "16"), 3503 v4i16, v4i16, OpNode, Commutable>; 3504 def v2i32 : N3VD<op24, op23, 0b10, op11_8, op4, itinD32, 3505 OpcodeStr, !strconcat(Dt, "32"), 3506 v2i32, v2i32, OpNode, Commutable>; 3507 3508 // 128-bit vector types. 3509 def v16i8 : N3VQ<op24, op23, 0b00, op11_8, op4, itinQ16, 3510 OpcodeStr, !strconcat(Dt, "8"), 3511 v16i8, v16i8, OpNode, Commutable>; 3512 def v8i16 : N3VQ<op24, op23, 0b01, op11_8, op4, itinQ16, 3513 OpcodeStr, !strconcat(Dt, "16"), 3514 v8i16, v8i16, OpNode, Commutable>; 3515 def v4i32 : N3VQ<op24, op23, 0b10, op11_8, op4, itinQ32, 3516 OpcodeStr, !strconcat(Dt, "32"), 3517 v4i32, v4i32, OpNode, Commutable>; 3518} 3519 3520multiclass N3VSL_HS<bits<4> op11_8, string OpcodeStr, SDNode ShOp> { 3521 def v4i16 : N3VDSL16<0b01, op11_8, OpcodeStr, "i16", v4i16, ShOp>; 3522 def v2i32 : N3VDSL<0b10, op11_8, IIC_VMULi32D, OpcodeStr, "i32", v2i32, ShOp>; 3523 def v8i16 : N3VQSL16<0b01, op11_8, OpcodeStr, "i16", v8i16, v4i16, ShOp>; 3524 def v4i32 : N3VQSL<0b10, op11_8, IIC_VMULi32Q, OpcodeStr, "i32", 3525 v4i32, v2i32, ShOp>; 3526} 3527 3528// ....then also with element size 64 bits: 3529multiclass N3V_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3530 InstrItinClass itinD, InstrItinClass itinQ, 3531 string OpcodeStr, string Dt, 3532 SDNode OpNode, bit Commutable = 0> 3533 : N3V_QHS<op24, op23, op11_8, op4, itinD, itinD, itinQ, itinQ, 3534 OpcodeStr, Dt, OpNode, Commutable> { 3535 def v1i64 : N3VD<op24, op23, 0b11, op11_8, op4, itinD, 3536 OpcodeStr, !strconcat(Dt, "64"), 3537 v1i64, v1i64, OpNode, Commutable>; 3538 def v2i64 : N3VQ<op24, op23, 0b11, op11_8, op4, itinQ, 3539 OpcodeStr, !strconcat(Dt, "64"), 3540 v2i64, v2i64, OpNode, Commutable>; 3541} 3542 3543 3544// Neon 3-register vector intrinsics. 3545 3546// First with only element sizes of 16 and 32 bits: 3547multiclass N3VInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3548 InstrItinClass itinD16, InstrItinClass itinD32, 3549 InstrItinClass itinQ16, InstrItinClass itinQ32, 3550 string OpcodeStr, string Dt, 3551 SDPatternOperator IntOp, bit Commutable = 0> { 3552 // 64-bit vector types. 3553 def v4i16 : N3VDInt<op24, op23, 0b01, op11_8, op4, f, itinD16, 3554 OpcodeStr, !strconcat(Dt, "16"), 3555 v4i16, v4i16, IntOp, Commutable>; 3556 def v2i32 : N3VDInt<op24, op23, 0b10, op11_8, op4, f, itinD32, 3557 OpcodeStr, !strconcat(Dt, "32"), 3558 v2i32, v2i32, IntOp, Commutable>; 3559 3560 // 128-bit vector types. 3561 def v8i16 : N3VQInt<op24, op23, 0b01, op11_8, op4, f, itinQ16, 3562 OpcodeStr, !strconcat(Dt, "16"), 3563 v8i16, v8i16, IntOp, Commutable>; 3564 def v4i32 : N3VQInt<op24, op23, 0b10, op11_8, op4, f, itinQ32, 3565 OpcodeStr, !strconcat(Dt, "32"), 3566 v4i32, v4i32, IntOp, Commutable>; 3567} 3568multiclass N3VInt_HSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3569 InstrItinClass itinD16, InstrItinClass itinD32, 3570 InstrItinClass itinQ16, InstrItinClass itinQ32, 3571 string OpcodeStr, string Dt, 3572 SDPatternOperator IntOp> { 3573 // 64-bit vector types. 3574 def v4i16 : N3VDIntSh<op24, op23, 0b01, op11_8, op4, f, itinD16, 3575 OpcodeStr, !strconcat(Dt, "16"), 3576 v4i16, v4i16, IntOp>; 3577 def v2i32 : N3VDIntSh<op24, op23, 0b10, op11_8, op4, f, itinD32, 3578 OpcodeStr, !strconcat(Dt, "32"), 3579 v2i32, v2i32, IntOp>; 3580 3581 // 128-bit vector types. 3582 def v8i16 : N3VQIntSh<op24, op23, 0b01, op11_8, op4, f, itinQ16, 3583 OpcodeStr, !strconcat(Dt, "16"), 3584 v8i16, v8i16, IntOp>; 3585 def v4i32 : N3VQIntSh<op24, op23, 0b10, op11_8, op4, f, itinQ32, 3586 OpcodeStr, !strconcat(Dt, "32"), 3587 v4i32, v4i32, IntOp>; 3588} 3589 3590multiclass N3VIntSL_HS<bits<4> op11_8, 3591 InstrItinClass itinD16, InstrItinClass itinD32, 3592 InstrItinClass itinQ16, InstrItinClass itinQ32, 3593 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3594 def v4i16 : N3VDIntSL16<0b01, op11_8, itinD16, 3595 OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp>; 3596 def v2i32 : N3VDIntSL<0b10, op11_8, itinD32, 3597 OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp>; 3598 def v8i16 : N3VQIntSL16<0b01, op11_8, itinQ16, 3599 OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, IntOp>; 3600 def v4i32 : N3VQIntSL<0b10, op11_8, itinQ32, 3601 OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, IntOp>; 3602} 3603 3604// ....then also with element size of 8 bits: 3605multiclass N3VInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3606 InstrItinClass itinD16, InstrItinClass itinD32, 3607 InstrItinClass itinQ16, InstrItinClass itinQ32, 3608 string OpcodeStr, string Dt, 3609 SDPatternOperator IntOp, bit Commutable = 0> 3610 : N3VInt_HS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3611 OpcodeStr, Dt, IntOp, Commutable> { 3612 def v8i8 : N3VDInt<op24, op23, 0b00, op11_8, op4, f, itinD16, 3613 OpcodeStr, !strconcat(Dt, "8"), 3614 v8i8, v8i8, IntOp, Commutable>; 3615 def v16i8 : N3VQInt<op24, op23, 0b00, op11_8, op4, f, itinQ16, 3616 OpcodeStr, !strconcat(Dt, "8"), 3617 v16i8, v16i8, IntOp, Commutable>; 3618} 3619multiclass N3VInt_QHSSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3620 InstrItinClass itinD16, InstrItinClass itinD32, 3621 InstrItinClass itinQ16, InstrItinClass itinQ32, 3622 string OpcodeStr, string Dt, 3623 SDPatternOperator IntOp> 3624 : N3VInt_HSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3625 OpcodeStr, Dt, IntOp> { 3626 def v8i8 : N3VDIntSh<op24, op23, 0b00, op11_8, op4, f, itinD16, 3627 OpcodeStr, !strconcat(Dt, "8"), 3628 v8i8, v8i8, IntOp>; 3629 def v16i8 : N3VQIntSh<op24, op23, 0b00, op11_8, op4, f, itinQ16, 3630 OpcodeStr, !strconcat(Dt, "8"), 3631 v16i8, v16i8, IntOp>; 3632} 3633 3634 3635// ....then also with element size of 64 bits: 3636multiclass N3VInt_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3637 InstrItinClass itinD16, InstrItinClass itinD32, 3638 InstrItinClass itinQ16, InstrItinClass itinQ32, 3639 string OpcodeStr, string Dt, 3640 SDPatternOperator IntOp, bit Commutable = 0> 3641 : N3VInt_QHS<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3642 OpcodeStr, Dt, IntOp, Commutable> { 3643 def v1i64 : N3VDInt<op24, op23, 0b11, op11_8, op4, f, itinD32, 3644 OpcodeStr, !strconcat(Dt, "64"), 3645 v1i64, v1i64, IntOp, Commutable>; 3646 def v2i64 : N3VQInt<op24, op23, 0b11, op11_8, op4, f, itinQ32, 3647 OpcodeStr, !strconcat(Dt, "64"), 3648 v2i64, v2i64, IntOp, Commutable>; 3649} 3650multiclass N3VInt_QHSDSh<bit op24, bit op23, bits<4> op11_8, bit op4, Format f, 3651 InstrItinClass itinD16, InstrItinClass itinD32, 3652 InstrItinClass itinQ16, InstrItinClass itinQ32, 3653 string OpcodeStr, string Dt, 3654 SDPatternOperator IntOp> 3655 : N3VInt_QHSSh<op24, op23, op11_8, op4, f, itinD16, itinD32, itinQ16, itinQ32, 3656 OpcodeStr, Dt, IntOp> { 3657 def v1i64 : N3VDIntSh<op24, op23, 0b11, op11_8, op4, f, itinD32, 3658 OpcodeStr, !strconcat(Dt, "64"), 3659 v1i64, v1i64, IntOp>; 3660 def v2i64 : N3VQIntSh<op24, op23, 0b11, op11_8, op4, f, itinQ32, 3661 OpcodeStr, !strconcat(Dt, "64"), 3662 v2i64, v2i64, IntOp>; 3663} 3664 3665// Neon Narrowing 3-register vector intrinsics, 3666// source operand element sizes of 16, 32 and 64 bits: 3667multiclass N3VNInt_HSD<bit op24, bit op23, bits<4> op11_8, bit op4, 3668 string OpcodeStr, string Dt, 3669 SDPatternOperator IntOp, bit Commutable = 0> { 3670 def v8i8 : N3VNInt<op24, op23, 0b00, op11_8, op4, 3671 OpcodeStr, !strconcat(Dt, "16"), 3672 v8i8, v8i16, IntOp, Commutable>; 3673 def v4i16 : N3VNInt<op24, op23, 0b01, op11_8, op4, 3674 OpcodeStr, !strconcat(Dt, "32"), 3675 v4i16, v4i32, IntOp, Commutable>; 3676 def v2i32 : N3VNInt<op24, op23, 0b10, op11_8, op4, 3677 OpcodeStr, !strconcat(Dt, "64"), 3678 v2i32, v2i64, IntOp, Commutable>; 3679} 3680 3681 3682// Neon Long 3-register vector operations. 3683 3684multiclass N3VL_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3685 InstrItinClass itin16, InstrItinClass itin32, 3686 string OpcodeStr, string Dt, 3687 SDNode OpNode, bit Commutable = 0> { 3688 def v8i16 : N3VL<op24, op23, 0b00, op11_8, op4, itin16, 3689 OpcodeStr, !strconcat(Dt, "8"), 3690 v8i16, v8i8, OpNode, Commutable>; 3691 def v4i32 : N3VL<op24, op23, 0b01, op11_8, op4, itin16, 3692 OpcodeStr, !strconcat(Dt, "16"), 3693 v4i32, v4i16, OpNode, Commutable>; 3694 def v2i64 : N3VL<op24, op23, 0b10, op11_8, op4, itin32, 3695 OpcodeStr, !strconcat(Dt, "32"), 3696 v2i64, v2i32, OpNode, Commutable>; 3697} 3698 3699multiclass N3VLSL_HS<bit op24, bits<4> op11_8, 3700 InstrItinClass itin, string OpcodeStr, string Dt, 3701 SDNode OpNode> { 3702 def v4i16 : N3VLSL16<op24, 0b01, op11_8, itin, OpcodeStr, 3703 !strconcat(Dt, "16"), v4i32, v4i16, OpNode>; 3704 def v2i32 : N3VLSL<op24, 0b10, op11_8, itin, OpcodeStr, 3705 !strconcat(Dt, "32"), v2i64, v2i32, OpNode>; 3706} 3707 3708multiclass N3VLExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3709 InstrItinClass itin16, InstrItinClass itin32, 3710 string OpcodeStr, string Dt, 3711 SDNode OpNode, SDNode ExtOp, bit Commutable = 0> { 3712 def v8i16 : N3VLExt<op24, op23, 0b00, op11_8, op4, itin16, 3713 OpcodeStr, !strconcat(Dt, "8"), 3714 v8i16, v8i8, OpNode, ExtOp, Commutable>; 3715 def v4i32 : N3VLExt<op24, op23, 0b01, op11_8, op4, itin16, 3716 OpcodeStr, !strconcat(Dt, "16"), 3717 v4i32, v4i16, OpNode, ExtOp, Commutable>; 3718 def v2i64 : N3VLExt<op24, op23, 0b10, op11_8, op4, itin32, 3719 OpcodeStr, !strconcat(Dt, "32"), 3720 v2i64, v2i32, OpNode, ExtOp, Commutable>; 3721} 3722 3723// Neon Long 3-register vector intrinsics. 3724 3725// First with only element sizes of 16 and 32 bits: 3726multiclass N3VLInt_HS<bit op24, bit op23, bits<4> op11_8, bit op4, 3727 InstrItinClass itin16, InstrItinClass itin32, 3728 string OpcodeStr, string Dt, 3729 SDPatternOperator IntOp, bit Commutable = 0> { 3730 def v4i32 : N3VLInt<op24, op23, 0b01, op11_8, op4, itin16, 3731 OpcodeStr, !strconcat(Dt, "16"), 3732 v4i32, v4i16, IntOp, Commutable>; 3733 def v2i64 : N3VLInt<op24, op23, 0b10, op11_8, op4, itin32, 3734 OpcodeStr, !strconcat(Dt, "32"), 3735 v2i64, v2i32, IntOp, Commutable>; 3736} 3737 3738multiclass N3VLIntSL_HS<bit op24, bits<4> op11_8, 3739 InstrItinClass itin, string OpcodeStr, string Dt, 3740 SDPatternOperator IntOp> { 3741 def v4i16 : N3VLIntSL16<op24, 0b01, op11_8, itin, 3742 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>; 3743 def v2i32 : N3VLIntSL<op24, 0b10, op11_8, itin, 3744 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>; 3745} 3746 3747// ....then also with element size of 8 bits: 3748multiclass N3VLInt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3749 InstrItinClass itin16, InstrItinClass itin32, 3750 string OpcodeStr, string Dt, 3751 SDPatternOperator IntOp, bit Commutable = 0> 3752 : N3VLInt_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, 3753 IntOp, Commutable> { 3754 def v8i16 : N3VLInt<op24, op23, 0b00, op11_8, op4, itin16, 3755 OpcodeStr, !strconcat(Dt, "8"), 3756 v8i16, v8i8, IntOp, Commutable>; 3757} 3758 3759// ....with explicit extend (VABDL). 3760multiclass N3VLIntExt_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3761 InstrItinClass itin, string OpcodeStr, string Dt, 3762 SDPatternOperator IntOp, SDNode ExtOp, bit Commutable = 0> { 3763 def v8i16 : N3VLIntExt<op24, op23, 0b00, op11_8, op4, itin, 3764 OpcodeStr, !strconcat(Dt, "8"), 3765 v8i16, v8i8, IntOp, ExtOp, Commutable>; 3766 def v4i32 : N3VLIntExt<op24, op23, 0b01, op11_8, op4, itin, 3767 OpcodeStr, !strconcat(Dt, "16"), 3768 v4i32, v4i16, IntOp, ExtOp, Commutable>; 3769 def v2i64 : N3VLIntExt<op24, op23, 0b10, op11_8, op4, itin, 3770 OpcodeStr, !strconcat(Dt, "32"), 3771 v2i64, v2i32, IntOp, ExtOp, Commutable>; 3772} 3773 3774 3775// Neon Wide 3-register vector intrinsics, 3776// source operand element sizes of 8, 16 and 32 bits: 3777multiclass N3VW_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3778 string OpcodeStr, string Dt, 3779 SDNode OpNode, SDNode ExtOp, bit Commutable = 0> { 3780 def v8i16 : N3VW<op24, op23, 0b00, op11_8, op4, 3781 OpcodeStr, !strconcat(Dt, "8"), 3782 v8i16, v8i8, OpNode, ExtOp, Commutable>; 3783 def v4i32 : N3VW<op24, op23, 0b01, op11_8, op4, 3784 OpcodeStr, !strconcat(Dt, "16"), 3785 v4i32, v4i16, OpNode, ExtOp, Commutable>; 3786 def v2i64 : N3VW<op24, op23, 0b10, op11_8, op4, 3787 OpcodeStr, !strconcat(Dt, "32"), 3788 v2i64, v2i32, OpNode, ExtOp, Commutable>; 3789} 3790 3791 3792// Neon Multiply-Op vector operations, 3793// element sizes of 8, 16 and 32 bits: 3794multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3795 InstrItinClass itinD16, InstrItinClass itinD32, 3796 InstrItinClass itinQ16, InstrItinClass itinQ32, 3797 string OpcodeStr, string Dt, SDNode OpNode> { 3798 // 64-bit vector types. 3799 def v8i8 : N3VDMulOp<op24, op23, 0b00, op11_8, op4, itinD16, 3800 OpcodeStr, !strconcat(Dt, "8"), v8i8, mul, OpNode>; 3801 def v4i16 : N3VDMulOp<op24, op23, 0b01, op11_8, op4, itinD16, 3802 OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, OpNode>; 3803 def v2i32 : N3VDMulOp<op24, op23, 0b10, op11_8, op4, itinD32, 3804 OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, OpNode>; 3805 3806 // 128-bit vector types. 3807 def v16i8 : N3VQMulOp<op24, op23, 0b00, op11_8, op4, itinQ16, 3808 OpcodeStr, !strconcat(Dt, "8"), v16i8, mul, OpNode>; 3809 def v8i16 : N3VQMulOp<op24, op23, 0b01, op11_8, op4, itinQ16, 3810 OpcodeStr, !strconcat(Dt, "16"), v8i16, mul, OpNode>; 3811 def v4i32 : N3VQMulOp<op24, op23, 0b10, op11_8, op4, itinQ32, 3812 OpcodeStr, !strconcat(Dt, "32"), v4i32, mul, OpNode>; 3813} 3814 3815multiclass N3VMulOpSL_HS<bits<4> op11_8, 3816 InstrItinClass itinD16, InstrItinClass itinD32, 3817 InstrItinClass itinQ16, InstrItinClass itinQ32, 3818 string OpcodeStr, string Dt, SDPatternOperator ShOp> { 3819 def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16, 3820 OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>; 3821 def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32, 3822 OpcodeStr, !strconcat(Dt, "32"), v2i32, mul, ShOp>; 3823 def v8i16 : N3VQMulOpSL16<0b01, op11_8, itinQ16, 3824 OpcodeStr, !strconcat(Dt, "16"), v8i16, v4i16, 3825 mul, ShOp>; 3826 def v4i32 : N3VQMulOpSL<0b10, op11_8, itinQ32, 3827 OpcodeStr, !strconcat(Dt, "32"), v4i32, v2i32, 3828 mul, ShOp>; 3829} 3830 3831// Neon Intrinsic-Op vector operations, 3832// element sizes of 8, 16 and 32 bits: 3833multiclass N3VIntOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3834 InstrItinClass itinD, InstrItinClass itinQ, 3835 string OpcodeStr, string Dt, SDPatternOperator IntOp, 3836 SDNode OpNode> { 3837 // 64-bit vector types. 3838 def v8i8 : N3VDIntOp<op24, op23, 0b00, op11_8, op4, itinD, 3839 OpcodeStr, !strconcat(Dt, "8"), v8i8, IntOp, OpNode>; 3840 def v4i16 : N3VDIntOp<op24, op23, 0b01, op11_8, op4, itinD, 3841 OpcodeStr, !strconcat(Dt, "16"), v4i16, IntOp, OpNode>; 3842 def v2i32 : N3VDIntOp<op24, op23, 0b10, op11_8, op4, itinD, 3843 OpcodeStr, !strconcat(Dt, "32"), v2i32, IntOp, OpNode>; 3844 3845 // 128-bit vector types. 3846 def v16i8 : N3VQIntOp<op24, op23, 0b00, op11_8, op4, itinQ, 3847 OpcodeStr, !strconcat(Dt, "8"), v16i8, IntOp, OpNode>; 3848 def v8i16 : N3VQIntOp<op24, op23, 0b01, op11_8, op4, itinQ, 3849 OpcodeStr, !strconcat(Dt, "16"), v8i16, IntOp, OpNode>; 3850 def v4i32 : N3VQIntOp<op24, op23, 0b10, op11_8, op4, itinQ, 3851 OpcodeStr, !strconcat(Dt, "32"), v4i32, IntOp, OpNode>; 3852} 3853 3854// Neon 3-argument intrinsics, 3855// element sizes of 16 and 32 bits: 3856multiclass N3VInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4, 3857 InstrItinClass itinD16, InstrItinClass itinD32, 3858 InstrItinClass itinQ16, InstrItinClass itinQ32, 3859 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3860 // 64-bit vector types. 3861 def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD16, 3862 OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>; 3863 def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD32, 3864 OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>; 3865 3866 // 128-bit vector types. 3867 def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ16, 3868 OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>; 3869 def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ32, 3870 OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>; 3871} 3872 3873// element sizes of 8, 16 and 32 bits: 3874multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3875 InstrItinClass itinD16, InstrItinClass itinD32, 3876 InstrItinClass itinQ16, InstrItinClass itinQ32, 3877 string OpcodeStr, string Dt, SDPatternOperator IntOp> 3878 :N3VInt3_HS <op24, op23, op11_8, op4, itinD16, itinD32, 3879 itinQ16, itinQ32, OpcodeStr, Dt, IntOp>{ 3880 // 64-bit vector types. 3881 def v8i8 : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD16, 3882 OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>; 3883 // 128-bit vector types. 3884 def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ16, 3885 OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>; 3886} 3887 3888// Neon Long Multiply-Op vector operations, 3889// element sizes of 8, 16 and 32 bits: 3890multiclass N3VLMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3891 InstrItinClass itin16, InstrItinClass itin32, 3892 string OpcodeStr, string Dt, SDNode MulOp, 3893 SDNode OpNode> { 3894 def v8i16 : N3VLMulOp<op24, op23, 0b00, op11_8, op4, itin16, OpcodeStr, 3895 !strconcat(Dt, "8"), v8i16, v8i8, MulOp, OpNode>; 3896 def v4i32 : N3VLMulOp<op24, op23, 0b01, op11_8, op4, itin16, OpcodeStr, 3897 !strconcat(Dt, "16"), v4i32, v4i16, MulOp, OpNode>; 3898 def v2i64 : N3VLMulOp<op24, op23, 0b10, op11_8, op4, itin32, OpcodeStr, 3899 !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>; 3900} 3901 3902multiclass N3VLMulOpSL_HS<bit op24, bits<4> op11_8, string OpcodeStr, 3903 string Dt, SDNode MulOp, SDNode OpNode> { 3904 def v4i16 : N3VLMulOpSL16<op24, 0b01, op11_8, IIC_VMACi16D, OpcodeStr, 3905 !strconcat(Dt,"16"), v4i32, v4i16, MulOp, OpNode>; 3906 def v2i32 : N3VLMulOpSL<op24, 0b10, op11_8, IIC_VMACi32D, OpcodeStr, 3907 !strconcat(Dt, "32"), v2i64, v2i32, MulOp, OpNode>; 3908} 3909 3910 3911// Neon Long 3-argument intrinsics. 3912 3913// First with only element sizes of 16 and 32 bits: 3914multiclass N3VLInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4, 3915 InstrItinClass itin16, InstrItinClass itin32, 3916 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3917 def v4i32 : N3VLInt3<op24, op23, 0b01, op11_8, op4, itin16, 3918 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, IntOp>; 3919 def v2i64 : N3VLInt3<op24, op23, 0b10, op11_8, op4, itin32, 3920 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>; 3921} 3922 3923multiclass N3VLInt3SL_HS<bit op24, bits<4> op11_8, 3924 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3925 def v4i16 : N3VLInt3SL16<op24, 0b01, op11_8, IIC_VMACi16D, 3926 OpcodeStr, !strconcat(Dt,"16"), v4i32, v4i16, IntOp>; 3927 def v2i32 : N3VLInt3SL<op24, 0b10, op11_8, IIC_VMACi32D, 3928 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, IntOp>; 3929} 3930 3931// ....then also with element size of 8 bits: 3932multiclass N3VLInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3933 InstrItinClass itin16, InstrItinClass itin32, 3934 string OpcodeStr, string Dt, SDPatternOperator IntOp> 3935 : N3VLInt3_HS<op24, op23, op11_8, op4, itin16, itin32, OpcodeStr, Dt, IntOp> { 3936 def v8i16 : N3VLInt3<op24, op23, 0b00, op11_8, op4, itin16, 3937 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, IntOp>; 3938} 3939 3940// ....with explicit extend (VABAL). 3941multiclass N3VLIntExtOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4, 3942 InstrItinClass itin, string OpcodeStr, string Dt, 3943 SDPatternOperator IntOp, SDNode ExtOp, SDNode OpNode> { 3944 def v8i16 : N3VLIntExtOp<op24, op23, 0b00, op11_8, op4, itin, 3945 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, 3946 IntOp, ExtOp, OpNode>; 3947 def v4i32 : N3VLIntExtOp<op24, op23, 0b01, op11_8, op4, itin, 3948 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, 3949 IntOp, ExtOp, OpNode>; 3950 def v2i64 : N3VLIntExtOp<op24, op23, 0b10, op11_8, op4, itin, 3951 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, 3952 IntOp, ExtOp, OpNode>; 3953} 3954 3955 3956// Neon Pairwise long 2-register intrinsics, 3957// element sizes of 8, 16 and 32 bits: 3958multiclass N2VPLInt_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3959 bits<5> op11_7, bit op4, 3960 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3961 // 64-bit vector types. 3962 def v8i8 : N2VDPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3963 OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>; 3964 def v4i16 : N2VDPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3965 OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>; 3966 def v2i32 : N2VDPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3967 OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>; 3968 3969 // 128-bit vector types. 3970 def v16i8 : N2VQPLInt<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3971 OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>; 3972 def v8i16 : N2VQPLInt<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3973 OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>; 3974 def v4i32 : N2VQPLInt<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3975 OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>; 3976} 3977 3978 3979// Neon Pairwise long 2-register accumulate intrinsics, 3980// element sizes of 8, 16 and 32 bits: 3981multiclass N2VPLInt2_QHS<bits<2> op24_23, bits<2> op21_20, bits<2> op17_16, 3982 bits<5> op11_7, bit op4, 3983 string OpcodeStr, string Dt, SDPatternOperator IntOp> { 3984 // 64-bit vector types. 3985 def v8i8 : N2VDPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3986 OpcodeStr, !strconcat(Dt, "8"), v4i16, v8i8, IntOp>; 3987 def v4i16 : N2VDPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3988 OpcodeStr, !strconcat(Dt, "16"), v2i32, v4i16, IntOp>; 3989 def v2i32 : N2VDPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3990 OpcodeStr, !strconcat(Dt, "32"), v1i64, v2i32, IntOp>; 3991 3992 // 128-bit vector types. 3993 def v16i8 : N2VQPLInt2<op24_23, op21_20, 0b00, op17_16, op11_7, op4, 3994 OpcodeStr, !strconcat(Dt, "8"), v8i16, v16i8, IntOp>; 3995 def v8i16 : N2VQPLInt2<op24_23, op21_20, 0b01, op17_16, op11_7, op4, 3996 OpcodeStr, !strconcat(Dt, "16"), v4i32, v8i16, IntOp>; 3997 def v4i32 : N2VQPLInt2<op24_23, op21_20, 0b10, op17_16, op11_7, op4, 3998 OpcodeStr, !strconcat(Dt, "32"), v2i64, v4i32, IntOp>; 3999} 4000 4001 4002// Neon 2-register vector shift by immediate, 4003// with f of either N2RegVShLFrm or N2RegVShRFrm 4004// element sizes of 8, 16, 32 and 64 bits: 4005multiclass N2VShL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 4006 InstrItinClass itin, string OpcodeStr, string Dt, 4007 SDNode OpNode> { 4008 // 64-bit vector types. 4009 def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 4010 OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> { 4011 let Inst{21-19} = 0b001; // imm6 = 001xxx 4012 } 4013 def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 4014 OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> { 4015 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4016 } 4017 def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 4018 OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> { 4019 let Inst{21} = 0b1; // imm6 = 1xxxxx 4020 } 4021 def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm, 4022 OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>; 4023 // imm6 = xxxxxx 4024 4025 // 128-bit vector types. 4026 def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 4027 OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> { 4028 let Inst{21-19} = 0b001; // imm6 = 001xxx 4029 } 4030 def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 4031 OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> { 4032 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4033 } 4034 def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShLFrm, itin, i32imm, 4035 OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> { 4036 let Inst{21} = 0b1; // imm6 = 1xxxxx 4037 } 4038 def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShLFrm, itin, i32imm, 4039 OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>; 4040 // imm6 = xxxxxx 4041} 4042multiclass N2VShR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 4043 InstrItinClass itin, string OpcodeStr, string Dt, 4044 string baseOpc, SDNode OpNode> { 4045 // 64-bit vector types. 4046 def v8i8 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8, 4047 OpcodeStr, !strconcat(Dt, "8"), v8i8, OpNode> { 4048 let Inst{21-19} = 0b001; // imm6 = 001xxx 4049 } 4050 def v4i16 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16, 4051 OpcodeStr, !strconcat(Dt, "16"), v4i16, OpNode> { 4052 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4053 } 4054 def v2i32 : N2VDSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32, 4055 OpcodeStr, !strconcat(Dt, "32"), v2i32, OpNode> { 4056 let Inst{21} = 0b1; // imm6 = 1xxxxx 4057 } 4058 def v1i64 : N2VDSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64, 4059 OpcodeStr, !strconcat(Dt, "64"), v1i64, OpNode>; 4060 // imm6 = xxxxxx 4061 4062 // 128-bit vector types. 4063 def v16i8 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm8, 4064 OpcodeStr, !strconcat(Dt, "8"), v16i8, OpNode> { 4065 let Inst{21-19} = 0b001; // imm6 = 001xxx 4066 } 4067 def v8i16 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm16, 4068 OpcodeStr, !strconcat(Dt, "16"), v8i16, OpNode> { 4069 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4070 } 4071 def v4i32 : N2VQSh<op24, op23, op11_8, 0, op4, N2RegVShRFrm, itin, shr_imm32, 4072 OpcodeStr, !strconcat(Dt, "32"), v4i32, OpNode> { 4073 let Inst{21} = 0b1; // imm6 = 1xxxxx 4074 } 4075 def v2i64 : N2VQSh<op24, op23, op11_8, 1, op4, N2RegVShRFrm, itin, shr_imm64, 4076 OpcodeStr, !strconcat(Dt, "64"), v2i64, OpNode>; 4077 // imm6 = xxxxxx 4078} 4079 4080// Neon Shift-Accumulate vector operations, 4081// element sizes of 8, 16, 32 and 64 bits: 4082multiclass N2VShAdd_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 4083 string OpcodeStr, string Dt, SDNode ShOp> { 4084 // 64-bit vector types. 4085 def v8i8 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm8, 4086 OpcodeStr, !strconcat(Dt, "8"), v8i8, ShOp> { 4087 let Inst{21-19} = 0b001; // imm6 = 001xxx 4088 } 4089 def v4i16 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm16, 4090 OpcodeStr, !strconcat(Dt, "16"), v4i16, ShOp> { 4091 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4092 } 4093 def v2i32 : N2VDShAdd<op24, op23, op11_8, 0, op4, shr_imm32, 4094 OpcodeStr, !strconcat(Dt, "32"), v2i32, ShOp> { 4095 let Inst{21} = 0b1; // imm6 = 1xxxxx 4096 } 4097 def v1i64 : N2VDShAdd<op24, op23, op11_8, 1, op4, shr_imm64, 4098 OpcodeStr, !strconcat(Dt, "64"), v1i64, ShOp>; 4099 // imm6 = xxxxxx 4100 4101 // 128-bit vector types. 4102 def v16i8 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm8, 4103 OpcodeStr, !strconcat(Dt, "8"), v16i8, ShOp> { 4104 let Inst{21-19} = 0b001; // imm6 = 001xxx 4105 } 4106 def v8i16 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm16, 4107 OpcodeStr, !strconcat(Dt, "16"), v8i16, ShOp> { 4108 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4109 } 4110 def v4i32 : N2VQShAdd<op24, op23, op11_8, 0, op4, shr_imm32, 4111 OpcodeStr, !strconcat(Dt, "32"), v4i32, ShOp> { 4112 let Inst{21} = 0b1; // imm6 = 1xxxxx 4113 } 4114 def v2i64 : N2VQShAdd<op24, op23, op11_8, 1, op4, shr_imm64, 4115 OpcodeStr, !strconcat(Dt, "64"), v2i64, ShOp>; 4116 // imm6 = xxxxxx 4117} 4118 4119// Neon Shift-Insert vector operations, 4120// with f of either N2RegVShLFrm or N2RegVShRFrm 4121// element sizes of 8, 16, 32 and 64 bits: 4122multiclass N2VShInsL_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 4123 string OpcodeStr> { 4124 // 64-bit vector types. 4125 def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm, 4126 N2RegVShLFrm, OpcodeStr, "8", v8i8, NEONvsliImm> { 4127 let Inst{21-19} = 0b001; // imm6 = 001xxx 4128 } 4129 def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm, 4130 N2RegVShLFrm, OpcodeStr, "16", v4i16, NEONvsliImm> { 4131 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4132 } 4133 def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, i32imm, 4134 N2RegVShLFrm, OpcodeStr, "32", v2i32, NEONvsliImm> { 4135 let Inst{21} = 0b1; // imm6 = 1xxxxx 4136 } 4137 def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, i32imm, 4138 N2RegVShLFrm, OpcodeStr, "64", v1i64, NEONvsliImm>; 4139 // imm6 = xxxxxx 4140 4141 // 128-bit vector types. 4142 def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm, 4143 N2RegVShLFrm, OpcodeStr, "8", v16i8, NEONvsliImm> { 4144 let Inst{21-19} = 0b001; // imm6 = 001xxx 4145 } 4146 def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm, 4147 N2RegVShLFrm, OpcodeStr, "16", v8i16, NEONvsliImm> { 4148 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4149 } 4150 def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, i32imm, 4151 N2RegVShLFrm, OpcodeStr, "32", v4i32, NEONvsliImm> { 4152 let Inst{21} = 0b1; // imm6 = 1xxxxx 4153 } 4154 def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, i32imm, 4155 N2RegVShLFrm, OpcodeStr, "64", v2i64, NEONvsliImm>; 4156 // imm6 = xxxxxx 4157} 4158multiclass N2VShInsR_QHSD<bit op24, bit op23, bits<4> op11_8, bit op4, 4159 string OpcodeStr> { 4160 // 64-bit vector types. 4161 def v8i8 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm8, 4162 N2RegVShRFrm, OpcodeStr, "8", v8i8, NEONvsriImm> { 4163 let Inst{21-19} = 0b001; // imm6 = 001xxx 4164 } 4165 def v4i16 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm16, 4166 N2RegVShRFrm, OpcodeStr, "16", v4i16, NEONvsriImm> { 4167 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4168 } 4169 def v2i32 : N2VDShIns<op24, op23, op11_8, 0, op4, shr_imm32, 4170 N2RegVShRFrm, OpcodeStr, "32", v2i32, NEONvsriImm> { 4171 let Inst{21} = 0b1; // imm6 = 1xxxxx 4172 } 4173 def v1i64 : N2VDShIns<op24, op23, op11_8, 1, op4, shr_imm64, 4174 N2RegVShRFrm, OpcodeStr, "64", v1i64, NEONvsriImm>; 4175 // imm6 = xxxxxx 4176 4177 // 128-bit vector types. 4178 def v16i8 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm8, 4179 N2RegVShRFrm, OpcodeStr, "8", v16i8, NEONvsriImm> { 4180 let Inst{21-19} = 0b001; // imm6 = 001xxx 4181 } 4182 def v8i16 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm16, 4183 N2RegVShRFrm, OpcodeStr, "16", v8i16, NEONvsriImm> { 4184 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4185 } 4186 def v4i32 : N2VQShIns<op24, op23, op11_8, 0, op4, shr_imm32, 4187 N2RegVShRFrm, OpcodeStr, "32", v4i32, NEONvsriImm> { 4188 let Inst{21} = 0b1; // imm6 = 1xxxxx 4189 } 4190 def v2i64 : N2VQShIns<op24, op23, op11_8, 1, op4, shr_imm64, 4191 N2RegVShRFrm, OpcodeStr, "64", v2i64, NEONvsriImm>; 4192 // imm6 = xxxxxx 4193} 4194 4195// Neon Shift Long operations, 4196// element sizes of 8, 16, 32 bits: 4197multiclass N2VLSh_QHS<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, 4198 bit op4, string OpcodeStr, string Dt, 4199 SDPatternOperator OpNode> { 4200 def v8i16 : N2VLSh<op24, op23, op11_8, op7, op6, op4, 4201 OpcodeStr, !strconcat(Dt, "8"), v8i16, v8i8, imm1_7, OpNode> { 4202 let Inst{21-19} = 0b001; // imm6 = 001xxx 4203 } 4204 def v4i32 : N2VLSh<op24, op23, op11_8, op7, op6, op4, 4205 OpcodeStr, !strconcat(Dt, "16"), v4i32, v4i16, imm1_15, OpNode> { 4206 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4207 } 4208 def v2i64 : N2VLSh<op24, op23, op11_8, op7, op6, op4, 4209 OpcodeStr, !strconcat(Dt, "32"), v2i64, v2i32, imm1_31, OpNode> { 4210 let Inst{21} = 0b1; // imm6 = 1xxxxx 4211 } 4212} 4213 4214// Neon Shift Narrow operations, 4215// element sizes of 16, 32, 64 bits: 4216multiclass N2VNSh_HSD<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, 4217 bit op4, InstrItinClass itin, string OpcodeStr, string Dt, 4218 SDPatternOperator OpNode> { 4219 def v8i8 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin, 4220 OpcodeStr, !strconcat(Dt, "16"), 4221 v8i8, v8i16, shr_imm8, OpNode> { 4222 let Inst{21-19} = 0b001; // imm6 = 001xxx 4223 } 4224 def v4i16 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin, 4225 OpcodeStr, !strconcat(Dt, "32"), 4226 v4i16, v4i32, shr_imm16, OpNode> { 4227 let Inst{21-20} = 0b01; // imm6 = 01xxxx 4228 } 4229 def v2i32 : N2VNSh<op24, op23, op11_8, op7, op6, op4, itin, 4230 OpcodeStr, !strconcat(Dt, "64"), 4231 v2i32, v2i64, shr_imm32, OpNode> { 4232 let Inst{21} = 0b1; // imm6 = 1xxxxx 4233 } 4234} 4235 4236//===----------------------------------------------------------------------===// 4237// Instruction Definitions. 4238//===----------------------------------------------------------------------===// 4239 4240// Vector Add Operations. 4241 4242// VADD : Vector Add (integer and floating-point) 4243defm VADD : N3V_QHSD<0, 0, 0b1000, 0, IIC_VBINiD, IIC_VBINiQ, "vadd", "i", 4244 add, 1>; 4245def VADDfd : N3VD<0, 0, 0b00, 0b1101, 0, IIC_VBIND, "vadd", "f32", 4246 v2f32, v2f32, fadd, 1>; 4247def VADDfq : N3VQ<0, 0, 0b00, 0b1101, 0, IIC_VBINQ, "vadd", "f32", 4248 v4f32, v4f32, fadd, 1>; 4249def VADDhd : N3VD<0, 0, 0b01, 0b1101, 0, IIC_VBIND, "vadd", "f16", 4250 v4f16, v4f16, fadd, 1>, 4251 Requires<[HasNEON,HasFullFP16]>; 4252def VADDhq : N3VQ<0, 0, 0b01, 0b1101, 0, IIC_VBINQ, "vadd", "f16", 4253 v8f16, v8f16, fadd, 1>, 4254 Requires<[HasNEON,HasFullFP16]>; 4255// VADDL : Vector Add Long (Q = D + D) 4256defm VADDLs : N3VLExt_QHS<0,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD, 4257 "vaddl", "s", add, sext, 1>; 4258defm VADDLu : N3VLExt_QHS<1,1,0b0000,0, IIC_VSHLiD, IIC_VSHLiD, 4259 "vaddl", "u", add, zext, 1>; 4260// VADDW : Vector Add Wide (Q = Q + D) 4261defm VADDWs : N3VW_QHS<0,1,0b0001,0, "vaddw", "s", add, sext, 0>; 4262defm VADDWu : N3VW_QHS<1,1,0b0001,0, "vaddw", "u", add, zext, 0>; 4263// VHADD : Vector Halving Add 4264defm VHADDs : N3VInt_QHS<0, 0, 0b0000, 0, N3RegFrm, 4265 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 4266 "vhadd", "s", int_arm_neon_vhadds, 1>; 4267defm VHADDu : N3VInt_QHS<1, 0, 0b0000, 0, N3RegFrm, 4268 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 4269 "vhadd", "u", int_arm_neon_vhaddu, 1>; 4270// VRHADD : Vector Rounding Halving Add 4271defm VRHADDs : N3VInt_QHS<0, 0, 0b0001, 0, N3RegFrm, 4272 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 4273 "vrhadd", "s", int_arm_neon_vrhadds, 1>; 4274defm VRHADDu : N3VInt_QHS<1, 0, 0b0001, 0, N3RegFrm, 4275 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 4276 "vrhadd", "u", int_arm_neon_vrhaddu, 1>; 4277// VQADD : Vector Saturating Add 4278defm VQADDs : N3VInt_QHSD<0, 0, 0b0000, 1, N3RegFrm, 4279 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 4280 "vqadd", "s", saddsat, 1>; 4281defm VQADDu : N3VInt_QHSD<1, 0, 0b0000, 1, N3RegFrm, 4282 IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, IIC_VBINi4Q, 4283 "vqadd", "u", uaddsat, 1>; 4284// VADDHN : Vector Add and Narrow Returning High Half (D = Q + Q) 4285defm VADDHN : N3VNInt_HSD<0,1,0b0100,0, "vaddhn", "i", null_frag, 1>; 4286// VRADDHN : Vector Rounding Add and Narrow Returning High Half (D = Q + Q) 4287defm VRADDHN : N3VNInt_HSD<1,1,0b0100,0, "vraddhn", "i", 4288 int_arm_neon_vraddhn, 1>; 4289 4290let Predicates = [HasNEON] in { 4291def : Pat<(v8i8 (trunc (ARMvshruImm (add (v8i16 QPR:$Vn), QPR:$Vm), 8))), 4292 (VADDHNv8i8 QPR:$Vn, QPR:$Vm)>; 4293def : Pat<(v4i16 (trunc (ARMvshruImm (add (v4i32 QPR:$Vn), QPR:$Vm), 16))), 4294 (VADDHNv4i16 QPR:$Vn, QPR:$Vm)>; 4295def : Pat<(v2i32 (trunc (ARMvshruImm (add (v2i64 QPR:$Vn), QPR:$Vm), 32))), 4296 (VADDHNv2i32 QPR:$Vn, QPR:$Vm)>; 4297} 4298 4299// Vector Multiply Operations. 4300 4301// VMUL : Vector Multiply (integer, polynomial and floating-point) 4302defm VMUL : N3V_QHS<0, 0, 0b1001, 1, IIC_VMULi16D, IIC_VMULi32D, 4303 IIC_VMULi16Q, IIC_VMULi32Q, "vmul", "i", mul, 1>; 4304def VMULpd : N3VDInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16D, "vmul", 4305 "p8", v8i8, v8i8, int_arm_neon_vmulp, 1>; 4306def VMULpq : N3VQInt<1, 0, 0b00, 0b1001, 1, N3RegFrm, IIC_VMULi16Q, "vmul", 4307 "p8", v16i8, v16i8, int_arm_neon_vmulp, 1>; 4308def VMULfd : N3VD<1, 0, 0b00, 0b1101, 1, IIC_VFMULD, "vmul", "f32", 4309 v2f32, v2f32, fmul, 1>; 4310def VMULfq : N3VQ<1, 0, 0b00, 0b1101, 1, IIC_VFMULQ, "vmul", "f32", 4311 v4f32, v4f32, fmul, 1>; 4312def VMULhd : N3VD<1, 0, 0b01, 0b1101, 1, IIC_VFMULD, "vmul", "f16", 4313 v4f16, v4f16, fmul, 1>, 4314 Requires<[HasNEON,HasFullFP16]>; 4315def VMULhq : N3VQ<1, 0, 0b01, 0b1101, 1, IIC_VFMULQ, "vmul", "f16", 4316 v8f16, v8f16, fmul, 1>, 4317 Requires<[HasNEON,HasFullFP16]>; 4318defm VMULsl : N3VSL_HS<0b1000, "vmul", mul>; 4319def VMULslfd : N3VDSL<0b10, 0b1001, IIC_VBIND, "vmul", "f32", v2f32, fmul>; 4320def VMULslfq : N3VQSL<0b10, 0b1001, IIC_VBINQ, "vmul", "f32", v4f32, 4321 v2f32, fmul>; 4322def VMULslhd : N3VDSL16<0b01, 0b1001, "vmul", "f16", v4f16, fmul>, 4323 Requires<[HasNEON,HasFullFP16]>; 4324def VMULslhq : N3VQSL16<0b01, 0b1001, "vmul", "f16", v8f16, 4325 v4f16, fmul>, 4326 Requires<[HasNEON,HasFullFP16]>; 4327 4328let Predicates = [HasNEON] in { 4329def : Pat<(v8i16 (mul (v8i16 QPR:$src1), 4330 (v8i16 (ARMvduplane (v8i16 QPR:$src2), imm:$lane)))), 4331 (v8i16 (VMULslv8i16 (v8i16 QPR:$src1), 4332 (v4i16 (EXTRACT_SUBREG QPR:$src2, 4333 (DSubReg_i16_reg imm:$lane))), 4334 (SubReg_i16_lane imm:$lane)))>; 4335def : Pat<(v4i32 (mul (v4i32 QPR:$src1), 4336 (v4i32 (ARMvduplane (v4i32 QPR:$src2), imm:$lane)))), 4337 (v4i32 (VMULslv4i32 (v4i32 QPR:$src1), 4338 (v2i32 (EXTRACT_SUBREG QPR:$src2, 4339 (DSubReg_i32_reg imm:$lane))), 4340 (SubReg_i32_lane imm:$lane)))>; 4341def : Pat<(v4f32 (fmul (v4f32 QPR:$src1), 4342 (v4f32 (ARMvduplane (v4f32 QPR:$src2), imm:$lane)))), 4343 (v4f32 (VMULslfq (v4f32 QPR:$src1), 4344 (v2f32 (EXTRACT_SUBREG QPR:$src2, 4345 (DSubReg_i32_reg imm:$lane))), 4346 (SubReg_i32_lane imm:$lane)))>; 4347def : Pat<(v8f16 (fmul (v8f16 QPR:$src1), 4348 (v8f16 (ARMvduplane (v8f16 QPR:$src2), imm:$lane)))), 4349 (v8f16 (VMULslhq(v8f16 QPR:$src1), 4350 (v4f16 (EXTRACT_SUBREG QPR:$src2, 4351 (DSubReg_i16_reg imm:$lane))), 4352 (SubReg_i16_lane imm:$lane)))>; 4353 4354def : Pat<(v2f32 (fmul DPR:$Rn, (ARMvdup (f32 SPR:$Rm)))), 4355 (VMULslfd DPR:$Rn, 4356 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0), 4357 (i32 0))>; 4358def : Pat<(v4f16 (fmul DPR:$Rn, (ARMvdup (f16 HPR:$Rm)))), 4359 (VMULslhd DPR:$Rn, 4360 (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), HPR:$Rm, ssub_0), 4361 (i32 0))>; 4362def : Pat<(v4f32 (fmul QPR:$Rn, (ARMvdup (f32 SPR:$Rm)))), 4363 (VMULslfq QPR:$Rn, 4364 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$Rm, ssub_0), 4365 (i32 0))>; 4366def : Pat<(v8f16 (fmul QPR:$Rn, (ARMvdup (f16 HPR:$Rm)))), 4367 (VMULslhq QPR:$Rn, 4368 (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), HPR:$Rm, ssub_0), 4369 (i32 0))>; 4370} 4371 4372// VQDMULH : Vector Saturating Doubling Multiply Returning High Half 4373defm VQDMULH : N3VInt_HS<0, 0, 0b1011, 0, N3RegFrm, IIC_VMULi16D, IIC_VMULi32D, 4374 IIC_VMULi16Q, IIC_VMULi32Q, 4375 "vqdmulh", "s", int_arm_neon_vqdmulh, 1>; 4376defm VQDMULHsl: N3VIntSL_HS<0b1100, IIC_VMULi16D, IIC_VMULi32D, 4377 IIC_VMULi16Q, IIC_VMULi32Q, 4378 "vqdmulh", "s", int_arm_neon_vqdmulh>; 4379 4380let Predicates = [HasNEON] in { 4381def : Pat<(v8i16 (int_arm_neon_vqdmulh (v8i16 QPR:$src1), 4382 (v8i16 (ARMvduplane (v8i16 QPR:$src2), 4383 imm:$lane)))), 4384 (v8i16 (VQDMULHslv8i16 (v8i16 QPR:$src1), 4385 (v4i16 (EXTRACT_SUBREG QPR:$src2, 4386 (DSubReg_i16_reg imm:$lane))), 4387 (SubReg_i16_lane imm:$lane)))>; 4388def : Pat<(v4i32 (int_arm_neon_vqdmulh (v4i32 QPR:$src1), 4389 (v4i32 (ARMvduplane (v4i32 QPR:$src2), 4390 imm:$lane)))), 4391 (v4i32 (VQDMULHslv4i32 (v4i32 QPR:$src1), 4392 (v2i32 (EXTRACT_SUBREG QPR:$src2, 4393 (DSubReg_i32_reg imm:$lane))), 4394 (SubReg_i32_lane imm:$lane)))>; 4395} 4396 4397// VQRDMULH : Vector Rounding Saturating Doubling Multiply Returning High Half 4398defm VQRDMULH : N3VInt_HS<1, 0, 0b1011, 0, N3RegFrm, 4399 IIC_VMULi16D,IIC_VMULi32D,IIC_VMULi16Q,IIC_VMULi32Q, 4400 "vqrdmulh", "s", int_arm_neon_vqrdmulh, 1>; 4401defm VQRDMULHsl : N3VIntSL_HS<0b1101, IIC_VMULi16D, IIC_VMULi32D, 4402 IIC_VMULi16Q, IIC_VMULi32Q, 4403 "vqrdmulh", "s", int_arm_neon_vqrdmulh>; 4404 4405let Predicates = [HasNEON] in { 4406def : Pat<(v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$src1), 4407 (v8i16 (ARMvduplane (v8i16 QPR:$src2), 4408 imm:$lane)))), 4409 (v8i16 (VQRDMULHslv8i16 (v8i16 QPR:$src1), 4410 (v4i16 (EXTRACT_SUBREG QPR:$src2, 4411 (DSubReg_i16_reg imm:$lane))), 4412 (SubReg_i16_lane imm:$lane)))>; 4413def : Pat<(v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$src1), 4414 (v4i32 (ARMvduplane (v4i32 QPR:$src2), 4415 imm:$lane)))), 4416 (v4i32 (VQRDMULHslv4i32 (v4i32 QPR:$src1), 4417 (v2i32 (EXTRACT_SUBREG QPR:$src2, 4418 (DSubReg_i32_reg imm:$lane))), 4419 (SubReg_i32_lane imm:$lane)))>; 4420} 4421 4422// VMULL : Vector Multiply Long (integer and polynomial) (Q = D * D) 4423let PostEncoderMethod = "NEONThumb2DataIPostEncoder", 4424 DecoderNamespace = "NEONData" in { 4425 defm VMULLs : N3VL_QHS<0,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D, 4426 "vmull", "s", ARMvmulls, 1>; 4427 defm VMULLu : N3VL_QHS<1,1,0b1100,0, IIC_VMULi16D, IIC_VMULi32D, 4428 "vmull", "u", ARMvmullu, 1>; 4429 def VMULLp8 : N3VLInt<0, 1, 0b00, 0b1110, 0, IIC_VMULi16D, "vmull", "p8", 4430 v8i16, v8i8, int_arm_neon_vmullp, 1>; 4431 def VMULLp64 : N3VLIntnp<0b00101, 0b10, 0b1110, 0, 0, NoItinerary, 4432 "vmull", "p64", v2i64, v1i64, int_arm_neon_vmullp, 1>, 4433 Requires<[HasV8, HasCrypto]>; 4434} 4435defm VMULLsls : N3VLSL_HS<0, 0b1010, IIC_VMULi16D, "vmull", "s", ARMvmulls>; 4436defm VMULLslu : N3VLSL_HS<1, 0b1010, IIC_VMULi16D, "vmull", "u", ARMvmullu>; 4437 4438// VQDMULL : Vector Saturating Doubling Multiply Long (Q = D * D) 4439defm VQDMULL : N3VLInt_HS<0,1,0b1101,0, IIC_VMULi16D, IIC_VMULi32D, 4440 "vqdmull", "s", int_arm_neon_vqdmull, 1>; 4441defm VQDMULLsl: N3VLIntSL_HS<0, 0b1011, IIC_VMULi16D, 4442 "vqdmull", "s", int_arm_neon_vqdmull>; 4443 4444// Vector Multiply-Accumulate and Multiply-Subtract Operations. 4445 4446// VMLA : Vector Multiply Accumulate (integer and floating-point) 4447defm VMLA : N3VMulOp_QHS<0, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D, 4448 IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>; 4449def VMLAfd : N3VDMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACD, "vmla", "f32", 4450 v2f32, fmul_su, fadd_mlx>, 4451 Requires<[HasNEON, UseFPVMLx]>; 4452def VMLAfq : N3VQMulOp<0, 0, 0b00, 0b1101, 1, IIC_VMACQ, "vmla", "f32", 4453 v4f32, fmul_su, fadd_mlx>, 4454 Requires<[HasNEON, UseFPVMLx]>; 4455def VMLAhd : N3VDMulOp<0, 0, 0b01, 0b1101, 1, IIC_VMACD, "vmla", "f16", 4456 v4f16, fmul_su, fadd_mlx>, 4457 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4458def VMLAhq : N3VQMulOp<0, 0, 0b01, 0b1101, 1, IIC_VMACQ, "vmla", "f16", 4459 v8f16, fmul_su, fadd_mlx>, 4460 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4461defm VMLAsl : N3VMulOpSL_HS<0b0000, IIC_VMACi16D, IIC_VMACi32D, 4462 IIC_VMACi16Q, IIC_VMACi32Q, "vmla", "i", add>; 4463def VMLAslfd : N3VDMulOpSL<0b10, 0b0001, IIC_VMACD, "vmla", "f32", 4464 v2f32, fmul_su, fadd_mlx>, 4465 Requires<[HasNEON, UseFPVMLx]>; 4466def VMLAslfq : N3VQMulOpSL<0b10, 0b0001, IIC_VMACQ, "vmla", "f32", 4467 v4f32, v2f32, fmul_su, fadd_mlx>, 4468 Requires<[HasNEON, UseFPVMLx]>; 4469def VMLAslhd : N3VDMulOpSL16<0b01, 0b0001, IIC_VMACD, "vmla", "f16", 4470 v4f16, fmul, fadd>, 4471 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4472def VMLAslhq : N3VQMulOpSL16<0b01, 0b0001, IIC_VMACQ, "vmla", "f16", 4473 v8f16, v4f16, fmul, fadd>, 4474 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4475 4476let Predicates = [HasNEON] in { 4477def : Pat<(v8i16 (add (v8i16 QPR:$src1), 4478 (mul (v8i16 QPR:$src2), 4479 (v8i16 (ARMvduplane (v8i16 QPR:$src3), imm:$lane))))), 4480 (v8i16 (VMLAslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2), 4481 (v4i16 (EXTRACT_SUBREG QPR:$src3, 4482 (DSubReg_i16_reg imm:$lane))), 4483 (SubReg_i16_lane imm:$lane)))>; 4484 4485def : Pat<(v4i32 (add (v4i32 QPR:$src1), 4486 (mul (v4i32 QPR:$src2), 4487 (v4i32 (ARMvduplane (v4i32 QPR:$src3), imm:$lane))))), 4488 (v4i32 (VMLAslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2), 4489 (v2i32 (EXTRACT_SUBREG QPR:$src3, 4490 (DSubReg_i32_reg imm:$lane))), 4491 (SubReg_i32_lane imm:$lane)))>; 4492} 4493 4494def : Pat<(v4f32 (fadd_mlx (v4f32 QPR:$src1), 4495 (fmul_su (v4f32 QPR:$src2), 4496 (v4f32 (ARMvduplane (v4f32 QPR:$src3), imm:$lane))))), 4497 (v4f32 (VMLAslfq (v4f32 QPR:$src1), 4498 (v4f32 QPR:$src2), 4499 (v2f32 (EXTRACT_SUBREG QPR:$src3, 4500 (DSubReg_i32_reg imm:$lane))), 4501 (SubReg_i32_lane imm:$lane)))>, 4502 Requires<[HasNEON, UseFPVMLx]>; 4503 4504// VMLAL : Vector Multiply Accumulate Long (Q += D * D) 4505defm VMLALs : N3VLMulOp_QHS<0,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D, 4506 "vmlal", "s", ARMvmulls, add>; 4507defm VMLALu : N3VLMulOp_QHS<1,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D, 4508 "vmlal", "u", ARMvmullu, add>; 4509 4510defm VMLALsls : N3VLMulOpSL_HS<0, 0b0010, "vmlal", "s", ARMvmulls, add>; 4511defm VMLALslu : N3VLMulOpSL_HS<1, 0b0010, "vmlal", "u", ARMvmullu, add>; 4512 4513let Predicates = [HasNEON, HasV8_1a] in { 4514 // v8.1a Neon Rounding Double Multiply-Op vector operations, 4515 // VQRDMLAH : Vector Saturating Rounding Doubling Multiply Accumulate Long 4516 // (Q += D * D) 4517 defm VQRDMLAH : N3VInt3_HS<1, 0, 0b1011, 1, IIC_VMACi16D, IIC_VMACi32D, 4518 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s", 4519 null_frag>; 4520 def : Pat<(v4i16 (saddsat 4521 (v4i16 DPR:$src1), 4522 (v4i16 (int_arm_neon_vqrdmulh (v4i16 DPR:$Vn), 4523 (v4i16 DPR:$Vm))))), 4524 (v4i16 (VQRDMLAHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>; 4525 def : Pat<(v2i32 (saddsat 4526 (v2i32 DPR:$src1), 4527 (v2i32 (int_arm_neon_vqrdmulh (v2i32 DPR:$Vn), 4528 (v2i32 DPR:$Vm))))), 4529 (v2i32 (VQRDMLAHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>; 4530 def : Pat<(v8i16 (saddsat 4531 (v8i16 QPR:$src1), 4532 (v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$Vn), 4533 (v8i16 QPR:$Vm))))), 4534 (v8i16 (VQRDMLAHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>; 4535 def : Pat<(v4i32 (saddsat 4536 (v4i32 QPR:$src1), 4537 (v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$Vn), 4538 (v4i32 QPR:$Vm))))), 4539 (v4i32 (VQRDMLAHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>; 4540 4541 defm VQRDMLAHsl : N3VMulOpSL_HS<0b1110, IIC_VMACi16D, IIC_VMACi32D, 4542 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s", 4543 null_frag>; 4544 def : Pat<(v4i16 (saddsat 4545 (v4i16 DPR:$src1), 4546 (v4i16 (int_arm_neon_vqrdmulh 4547 (v4i16 DPR:$Vn), 4548 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm), 4549 imm:$lane)))))), 4550 (v4i16 (VQRDMLAHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm, 4551 imm:$lane))>; 4552 def : Pat<(v2i32 (saddsat 4553 (v2i32 DPR:$src1), 4554 (v2i32 (int_arm_neon_vqrdmulh 4555 (v2i32 DPR:$Vn), 4556 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm), 4557 imm:$lane)))))), 4558 (v2i32 (VQRDMLAHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, 4559 imm:$lane))>; 4560 def : Pat<(v8i16 (saddsat 4561 (v8i16 QPR:$src1), 4562 (v8i16 (int_arm_neon_vqrdmulh 4563 (v8i16 QPR:$src2), 4564 (v8i16 (ARMvduplane (v8i16 QPR:$src3), 4565 imm:$lane)))))), 4566 (v8i16 (VQRDMLAHslv8i16 (v8i16 QPR:$src1), 4567 (v8i16 QPR:$src2), 4568 (v4i16 (EXTRACT_SUBREG 4569 QPR:$src3, 4570 (DSubReg_i16_reg imm:$lane))), 4571 (SubReg_i16_lane imm:$lane)))>; 4572 def : Pat<(v4i32 (saddsat 4573 (v4i32 QPR:$src1), 4574 (v4i32 (int_arm_neon_vqrdmulh 4575 (v4i32 QPR:$src2), 4576 (v4i32 (ARMvduplane (v4i32 QPR:$src3), 4577 imm:$lane)))))), 4578 (v4i32 (VQRDMLAHslv4i32 (v4i32 QPR:$src1), 4579 (v4i32 QPR:$src2), 4580 (v2i32 (EXTRACT_SUBREG 4581 QPR:$src3, 4582 (DSubReg_i32_reg imm:$lane))), 4583 (SubReg_i32_lane imm:$lane)))>; 4584 4585 // VQRDMLSH : Vector Saturating Rounding Doubling Multiply Subtract Long 4586 // (Q -= D * D) 4587 defm VQRDMLSH : N3VInt3_HS<1, 0, 0b1100, 1, IIC_VMACi16D, IIC_VMACi32D, 4588 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s", 4589 null_frag>; 4590 def : Pat<(v4i16 (ssubsat 4591 (v4i16 DPR:$src1), 4592 (v4i16 (int_arm_neon_vqrdmulh (v4i16 DPR:$Vn), 4593 (v4i16 DPR:$Vm))))), 4594 (v4i16 (VQRDMLSHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>; 4595 def : Pat<(v2i32 (ssubsat 4596 (v2i32 DPR:$src1), 4597 (v2i32 (int_arm_neon_vqrdmulh (v2i32 DPR:$Vn), 4598 (v2i32 DPR:$Vm))))), 4599 (v2i32 (VQRDMLSHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>; 4600 def : Pat<(v8i16 (ssubsat 4601 (v8i16 QPR:$src1), 4602 (v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$Vn), 4603 (v8i16 QPR:$Vm))))), 4604 (v8i16 (VQRDMLSHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>; 4605 def : Pat<(v4i32 (ssubsat 4606 (v4i32 QPR:$src1), 4607 (v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$Vn), 4608 (v4i32 QPR:$Vm))))), 4609 (v4i32 (VQRDMLSHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>; 4610 4611 defm VQRDMLSHsl : N3VMulOpSL_HS<0b1111, IIC_VMACi16D, IIC_VMACi32D, 4612 IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s", 4613 null_frag>; 4614 def : Pat<(v4i16 (ssubsat 4615 (v4i16 DPR:$src1), 4616 (v4i16 (int_arm_neon_vqrdmulh 4617 (v4i16 DPR:$Vn), 4618 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm), 4619 imm:$lane)))))), 4620 (v4i16 (VQRDMLSHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane))>; 4621 def : Pat<(v2i32 (ssubsat 4622 (v2i32 DPR:$src1), 4623 (v2i32 (int_arm_neon_vqrdmulh 4624 (v2i32 DPR:$Vn), 4625 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm), 4626 imm:$lane)))))), 4627 (v2i32 (VQRDMLSHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, 4628 imm:$lane))>; 4629 def : Pat<(v8i16 (ssubsat 4630 (v8i16 QPR:$src1), 4631 (v8i16 (int_arm_neon_vqrdmulh 4632 (v8i16 QPR:$src2), 4633 (v8i16 (ARMvduplane (v8i16 QPR:$src3), 4634 imm:$lane)))))), 4635 (v8i16 (VQRDMLSHslv8i16 (v8i16 QPR:$src1), 4636 (v8i16 QPR:$src2), 4637 (v4i16 (EXTRACT_SUBREG 4638 QPR:$src3, 4639 (DSubReg_i16_reg imm:$lane))), 4640 (SubReg_i16_lane imm:$lane)))>; 4641 def : Pat<(v4i32 (ssubsat 4642 (v4i32 QPR:$src1), 4643 (v4i32 (int_arm_neon_vqrdmulh 4644 (v4i32 QPR:$src2), 4645 (v4i32 (ARMvduplane (v4i32 QPR:$src3), 4646 imm:$lane)))))), 4647 (v4i32 (VQRDMLSHslv4i32 (v4i32 QPR:$src1), 4648 (v4i32 QPR:$src2), 4649 (v2i32 (EXTRACT_SUBREG 4650 QPR:$src3, 4651 (DSubReg_i32_reg imm:$lane))), 4652 (SubReg_i32_lane imm:$lane)))>; 4653} 4654// VQDMLAL : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D) 4655defm VQDMLAL : N3VLInt3_HS<0, 1, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D, 4656 "vqdmlal", "s", null_frag>; 4657defm VQDMLALsl: N3VLInt3SL_HS<0, 0b0011, "vqdmlal", "s", null_frag>; 4658 4659let Predicates = [HasNEON] in { 4660def : Pat<(v4i32 (saddsat (v4i32 QPR:$src1), 4661 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn), 4662 (v4i16 DPR:$Vm))))), 4663 (VQDMLALv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>; 4664def : Pat<(v2i64 (saddsat (v2i64 QPR:$src1), 4665 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn), 4666 (v2i32 DPR:$Vm))))), 4667 (VQDMLALv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>; 4668def : Pat<(v4i32 (saddsat (v4i32 QPR:$src1), 4669 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn), 4670 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm), 4671 imm:$lane)))))), 4672 (VQDMLALslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>; 4673def : Pat<(v2i64 (saddsat (v2i64 QPR:$src1), 4674 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn), 4675 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm), 4676 imm:$lane)))))), 4677 (VQDMLALslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>; 4678} 4679 4680// VMLS : Vector Multiply Subtract (integer and floating-point) 4681defm VMLS : N3VMulOp_QHS<1, 0, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D, 4682 IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>; 4683def VMLSfd : N3VDMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACD, "vmls", "f32", 4684 v2f32, fmul_su, fsub_mlx>, 4685 Requires<[HasNEON, UseFPVMLx]>; 4686def VMLSfq : N3VQMulOp<0, 0, 0b10, 0b1101, 1, IIC_VMACQ, "vmls", "f32", 4687 v4f32, fmul_su, fsub_mlx>, 4688 Requires<[HasNEON, UseFPVMLx]>; 4689def VMLShd : N3VDMulOp<0, 0, 0b11, 0b1101, 1, IIC_VMACD, "vmls", "f16", 4690 v4f16, fmul, fsub>, 4691 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4692def VMLShq : N3VQMulOp<0, 0, 0b11, 0b1101, 1, IIC_VMACQ, "vmls", "f16", 4693 v8f16, fmul, fsub>, 4694 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4695defm VMLSsl : N3VMulOpSL_HS<0b0100, IIC_VMACi16D, IIC_VMACi32D, 4696 IIC_VMACi16Q, IIC_VMACi32Q, "vmls", "i", sub>; 4697def VMLSslfd : N3VDMulOpSL<0b10, 0b0101, IIC_VMACD, "vmls", "f32", 4698 v2f32, fmul_su, fsub_mlx>, 4699 Requires<[HasNEON, UseFPVMLx]>; 4700def VMLSslfq : N3VQMulOpSL<0b10, 0b0101, IIC_VMACQ, "vmls", "f32", 4701 v4f32, v2f32, fmul_su, fsub_mlx>, 4702 Requires<[HasNEON, UseFPVMLx]>; 4703def VMLSslhd : N3VDMulOpSL16<0b01, 0b0101, IIC_VMACD, "vmls", "f16", 4704 v4f16, fmul, fsub>, 4705 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4706def VMLSslhq : N3VQMulOpSL16<0b01, 0b0101, IIC_VMACQ, "vmls", "f16", 4707 v8f16, v4f16, fmul, fsub>, 4708 Requires<[HasNEON, HasFullFP16, UseFPVMLx]>; 4709 4710let Predicates = [HasNEON] in { 4711def : Pat<(v8i16 (sub (v8i16 QPR:$src1), 4712 (mul (v8i16 QPR:$src2), 4713 (v8i16 (ARMvduplane (v8i16 QPR:$src3), imm:$lane))))), 4714 (v8i16 (VMLSslv8i16 (v8i16 QPR:$src1), (v8i16 QPR:$src2), 4715 (v4i16 (EXTRACT_SUBREG QPR:$src3, 4716 (DSubReg_i16_reg imm:$lane))), 4717 (SubReg_i16_lane imm:$lane)))>; 4718 4719def : Pat<(v4i32 (sub (v4i32 QPR:$src1), 4720 (mul (v4i32 QPR:$src2), 4721 (v4i32 (ARMvduplane (v4i32 QPR:$src3), imm:$lane))))), 4722 (v4i32 (VMLSslv4i32 (v4i32 QPR:$src1), (v4i32 QPR:$src2), 4723 (v2i32 (EXTRACT_SUBREG QPR:$src3, 4724 (DSubReg_i32_reg imm:$lane))), 4725 (SubReg_i32_lane imm:$lane)))>; 4726} 4727 4728def : Pat<(v4f32 (fsub_mlx (v4f32 QPR:$src1), 4729 (fmul_su (v4f32 QPR:$src2), 4730 (v4f32 (ARMvduplane (v4f32 QPR:$src3), imm:$lane))))), 4731 (v4f32 (VMLSslfq (v4f32 QPR:$src1), (v4f32 QPR:$src2), 4732 (v2f32 (EXTRACT_SUBREG QPR:$src3, 4733 (DSubReg_i32_reg imm:$lane))), 4734 (SubReg_i32_lane imm:$lane)))>, 4735 Requires<[HasNEON, UseFPVMLx]>; 4736 4737// VMLSL : Vector Multiply Subtract Long (Q -= D * D) 4738defm VMLSLs : N3VLMulOp_QHS<0,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D, 4739 "vmlsl", "s", ARMvmulls, sub>; 4740defm VMLSLu : N3VLMulOp_QHS<1,1,0b1010,0, IIC_VMACi16D, IIC_VMACi32D, 4741 "vmlsl", "u", ARMvmullu, sub>; 4742 4743defm VMLSLsls : N3VLMulOpSL_HS<0, 0b0110, "vmlsl", "s", ARMvmulls, sub>; 4744defm VMLSLslu : N3VLMulOpSL_HS<1, 0b0110, "vmlsl", "u", ARMvmullu, sub>; 4745 4746// VQDMLSL : Vector Saturating Doubling Multiply Subtract Long (Q -= D * D) 4747defm VQDMLSL : N3VLInt3_HS<0, 1, 0b1011, 0, IIC_VMACi16D, IIC_VMACi32D, 4748 "vqdmlsl", "s", null_frag>; 4749defm VQDMLSLsl: N3VLInt3SL_HS<0, 0b0111, "vqdmlsl", "s", null_frag>; 4750 4751let Predicates = [HasNEON] in { 4752def : Pat<(v4i32 (ssubsat (v4i32 QPR:$src1), 4753 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn), 4754 (v4i16 DPR:$Vm))))), 4755 (VQDMLSLv4i32 QPR:$src1, DPR:$Vn, DPR:$Vm)>; 4756def : Pat<(v2i64 (ssubsat (v2i64 QPR:$src1), 4757 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn), 4758 (v2i32 DPR:$Vm))))), 4759 (VQDMLSLv2i64 QPR:$src1, DPR:$Vn, DPR:$Vm)>; 4760def : Pat<(v4i32 (ssubsat (v4i32 QPR:$src1), 4761 (v4i32 (int_arm_neon_vqdmull (v4i16 DPR:$Vn), 4762 (v4i16 (ARMvduplane (v4i16 DPR_8:$Vm), 4763 imm:$lane)))))), 4764 (VQDMLSLslv4i16 QPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane)>; 4765def : Pat<(v2i64 (ssubsat (v2i64 QPR:$src1), 4766 (v2i64 (int_arm_neon_vqdmull (v2i32 DPR:$Vn), 4767 (v2i32 (ARMvduplane (v2i32 DPR_VFP2:$Vm), 4768 imm:$lane)))))), 4769 (VQDMLSLslv2i32 QPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, imm:$lane)>; 4770} 4771 4772// Fused Vector Multiply-Accumulate and Fused Multiply-Subtract Operations. 4773def VFMAfd : N3VDMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACD, "vfma", "f32", 4774 v2f32, fmul_su, fadd_mlx>, 4775 Requires<[HasNEON,HasVFP4,UseFusedMAC]>; 4776 4777def VFMAfq : N3VQMulOp<0, 0, 0b00, 0b1100, 1, IIC_VFMACQ, "vfma", "f32", 4778 v4f32, fmul_su, fadd_mlx>, 4779 Requires<[HasNEON,HasVFP4,UseFusedMAC]>; 4780def VFMAhd : N3VDMulOp<0, 0, 0b01, 0b1100, 1, IIC_VFMACD, "vfma", "f16", 4781 v4f16, fmul, fadd>, 4782 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>; 4783 4784def VFMAhq : N3VQMulOp<0, 0, 0b01, 0b1100, 1, IIC_VFMACQ, "vfma", "f16", 4785 v8f16, fmul, fadd>, 4786 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>; 4787 4788// Fused Vector Multiply Subtract (floating-point) 4789def VFMSfd : N3VDMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACD, "vfms", "f32", 4790 v2f32, fmul_su, fsub_mlx>, 4791 Requires<[HasNEON,HasVFP4,UseFusedMAC]>; 4792def VFMSfq : N3VQMulOp<0, 0, 0b10, 0b1100, 1, IIC_VFMACQ, "vfms", "f32", 4793 v4f32, fmul_su, fsub_mlx>, 4794 Requires<[HasNEON,HasVFP4,UseFusedMAC]>; 4795def VFMShd : N3VDMulOp<0, 0, 0b11, 0b1100, 1, IIC_VFMACD, "vfms", "f16", 4796 v4f16, fmul, fsub>, 4797 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>; 4798def VFMShq : N3VQMulOp<0, 0, 0b11, 0b1100, 1, IIC_VFMACQ, "vfms", "f16", 4799 v8f16, fmul, fsub>, 4800 Requires<[HasNEON,HasFullFP16,UseFusedMAC]>; 4801 4802// Match @llvm.fma.* intrinsics 4803def : Pat<(v4f16 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)), 4804 (VFMAhd DPR:$src1, DPR:$Vn, DPR:$Vm)>, 4805 Requires<[HasNEON,HasFullFP16]>; 4806def : Pat<(v8f16 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)), 4807 (VFMAhq QPR:$src1, QPR:$Vn, QPR:$Vm)>, 4808 Requires<[HasNEON,HasFullFP16]>; 4809def : Pat<(v2f32 (fma DPR:$Vn, DPR:$Vm, DPR:$src1)), 4810 (VFMAfd DPR:$src1, DPR:$Vn, DPR:$Vm)>, 4811 Requires<[HasNEON,HasVFP4]>; 4812def : Pat<(v4f32 (fma QPR:$Vn, QPR:$Vm, QPR:$src1)), 4813 (VFMAfq QPR:$src1, QPR:$Vn, QPR:$Vm)>, 4814 Requires<[HasNEON,HasVFP4]>; 4815def : Pat<(v2f32 (fma (fneg DPR:$Vn), DPR:$Vm, DPR:$src1)), 4816 (VFMSfd DPR:$src1, DPR:$Vn, DPR:$Vm)>, 4817 Requires<[HasNEON,HasVFP4]>; 4818def : Pat<(v4f32 (fma (fneg QPR:$Vn), QPR:$Vm, QPR:$src1)), 4819 (VFMSfq QPR:$src1, QPR:$Vn, QPR:$Vm)>, 4820 Requires<[HasNEON,HasVFP4]>; 4821 4822// ARMv8.2a dot product instructions. 4823// We put them in the VFPV8 decoder namespace because the ARM and Thumb 4824// encodings are the same and thus no further bit twiddling is necessary 4825// in the disassembler. 4826class VDOT<bit op6, bit op4, RegisterClass RegTy, string Asm, string AsmTy, 4827 ValueType AccumTy, ValueType InputTy, 4828 SDPatternOperator OpNode> : 4829 N3Vnp<0b11000, 0b10, 0b1101, op6, op4, (outs RegTy:$dst), 4830 (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm), N3RegFrm, IIC_VDOTPROD, 4831 Asm, AsmTy, 4832 [(set (AccumTy RegTy:$dst), 4833 (OpNode (AccumTy RegTy:$Vd), 4834 (InputTy RegTy:$Vn), 4835 (InputTy RegTy:$Vm)))]> { 4836 let Predicates = [HasDotProd]; 4837 let DecoderNamespace = "VFPV8"; 4838 let Constraints = "$dst = $Vd"; 4839} 4840 4841def VUDOTD : VDOT<0, 1, DPR, "vudot", "u8", v2i32, v8i8, int_arm_neon_udot>; 4842def VSDOTD : VDOT<0, 0, DPR, "vsdot", "s8", v2i32, v8i8, int_arm_neon_sdot>; 4843def VUDOTQ : VDOT<1, 1, QPR, "vudot", "u8", v4i32, v16i8, int_arm_neon_udot>; 4844def VSDOTQ : VDOT<1, 0, QPR, "vsdot", "s8", v4i32, v16i8, int_arm_neon_sdot>; 4845 4846// Indexed dot product instructions: 4847multiclass DOTI<string opc, string dt, bit Q, bit U, RegisterClass Ty, 4848 ValueType AccumType, ValueType InputType, SDPatternOperator OpNode, 4849 dag RHS> { 4850 def "" : N3Vnp<0b11100, 0b10, 0b1101, Q, U, (outs Ty:$dst), 4851 (ins Ty:$Vd, Ty:$Vn, DPR_VFP2:$Vm, VectorIndex32:$lane), 4852 N3RegFrm, IIC_VDOTPROD, opc, dt, []> { 4853 bit lane; 4854 let Inst{5} = lane; 4855 let AsmString = !strconcat(opc, ".", dt, "\t$Vd, $Vn, $Vm$lane"); 4856 let Constraints = "$dst = $Vd"; 4857 let Predicates = [HasDotProd]; 4858 let DecoderNamespace = "VFPV8"; 4859 } 4860 4861 def : Pat< 4862 (AccumType (OpNode (AccumType Ty:$Vd), 4863 (InputType Ty:$Vn), 4864 (InputType (bitconvert (AccumType 4865 (ARMvduplane (AccumType Ty:$Vm), 4866 VectorIndex32:$lane)))))), 4867 (!cast<Instruction>(NAME) Ty:$Vd, Ty:$Vn, RHS, VectorIndex32:$lane)>; 4868} 4869 4870defm VUDOTDI : DOTI<"vudot", "u8", 0b0, 0b1, DPR, v2i32, v8i8, 4871 int_arm_neon_udot, (v2i32 DPR_VFP2:$Vm)>; 4872defm VSDOTDI : DOTI<"vsdot", "s8", 0b0, 0b0, DPR, v2i32, v8i8, 4873 int_arm_neon_sdot, (v2i32 DPR_VFP2:$Vm)>; 4874defm VUDOTQI : DOTI<"vudot", "u8", 0b1, 0b1, QPR, v4i32, v16i8, 4875 int_arm_neon_udot, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>; 4876defm VSDOTQI : DOTI<"vsdot", "s8", 0b1, 0b0, QPR, v4i32, v16i8, 4877 int_arm_neon_sdot, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>; 4878 4879 4880// ARMv8.3 complex operations 4881class BaseN3VCP8ComplexTied<bit op21, bit op4, bit s, bit q, 4882 InstrItinClass itin, dag oops, dag iops, 4883 string opc, string dt, list<dag> pattern> 4884 : N3VCP8<{?,?}, {op21,s}, q, op4, oops, 4885 iops, itin, opc, dt, "$Vd, $Vn, $Vm, $rot", "$src1 = $Vd", pattern>{ 4886 bits<2> rot; 4887 let Inst{24-23} = rot; 4888} 4889 4890class BaseN3VCP8ComplexOdd<bit op23, bit op21, bit op4, bit s, bit q, 4891 InstrItinClass itin, dag oops, dag iops, string opc, 4892 string dt, list<dag> pattern> 4893 : N3VCP8<{?,op23}, {op21,s}, q, op4, oops, 4894 iops, itin, opc, dt, "$Vd, $Vn, $Vm, $rot", "", pattern> { 4895 bits<1> rot; 4896 let Inst{24} = rot; 4897} 4898 4899class BaseN3VCP8ComplexTiedLane32<bit op4, bit s, bit q, InstrItinClass itin, 4900 dag oops, dag iops, string opc, string dt, 4901 list<dag> pattern> 4902 : N3VLaneCP8<s, {?,?}, q, op4, oops, iops, itin, opc, dt, 4903 "$Vd, $Vn, $Vm$lane, $rot", "$src1 = $Vd", pattern> { 4904 bits<2> rot; 4905 bit lane; 4906 4907 let Inst{21-20} = rot; 4908 let Inst{5} = lane; 4909} 4910 4911class BaseN3VCP8ComplexTiedLane64<bit op4, bit s, bit q, InstrItinClass itin, 4912 dag oops, dag iops, string opc, string dt, 4913 list<dag> pattern> 4914 : N3VLaneCP8<s, {?,?}, q, op4, oops, iops, itin, opc, dt, 4915 "$Vd, $Vn, $Vm$lane, $rot", "$src1 = $Vd", pattern> { 4916 bits<2> rot; 4917 bit lane; 4918 4919 let Inst{21-20} = rot; 4920 let Inst{5} = Vm{4}; 4921 // This is needed because the lane operand does not have any bits in the 4922 // encoding (it only has one possible value), so we need to manually set it 4923 // to it's default value. 4924 let DecoderMethod = "DecodeNEONComplexLane64Instruction"; 4925} 4926 4927multiclass N3VCP8ComplexTied<bit op21, bit op4, 4928 string OpcodeStr, SDPatternOperator Op> { 4929 let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in { 4930 def v4f16 : BaseN3VCP8ComplexTied<op21, op4, 0, 0, IIC_VMACD, (outs DPR:$Vd), 4931 (ins DPR:$src1, DPR:$Vn, DPR:$Vm, complexrotateop:$rot), 4932 OpcodeStr, "f16", []>; 4933 def v8f16 : BaseN3VCP8ComplexTied<op21, op4, 0, 1, IIC_VMACQ, (outs QPR:$Vd), 4934 (ins QPR:$src1, QPR:$Vn, QPR:$Vm, complexrotateop:$rot), 4935 OpcodeStr, "f16", []>; 4936 } 4937 let Predicates = [HasNEON,HasV8_3a] in { 4938 def v2f32 : BaseN3VCP8ComplexTied<op21, op4, 1, 0, IIC_VMACD, (outs DPR:$Vd), 4939 (ins DPR:$src1, DPR:$Vn, DPR:$Vm, complexrotateop:$rot), 4940 OpcodeStr, "f32", []>; 4941 def v4f32 : BaseN3VCP8ComplexTied<op21, op4, 1, 1, IIC_VMACQ, (outs QPR:$Vd), 4942 (ins QPR:$src1, QPR:$Vn, QPR:$Vm, complexrotateop:$rot), 4943 OpcodeStr, "f32", []>; 4944 } 4945} 4946 4947multiclass N3VCP8ComplexOdd<bit op23, bit op21, bit op4, 4948 string OpcodeStr, SDPatternOperator Op> { 4949 let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in { 4950 def v4f16 : BaseN3VCP8ComplexOdd<op23, op21, op4, 0, 0, IIC_VMACD, 4951 (outs DPR:$Vd), 4952 (ins DPR:$Vn, DPR:$Vm, complexrotateopodd:$rot), 4953 OpcodeStr, "f16", []>; 4954 def v8f16 : BaseN3VCP8ComplexOdd<op23, op21, op4, 0, 1, IIC_VMACQ, 4955 (outs QPR:$Vd), 4956 (ins QPR:$Vn, QPR:$Vm, complexrotateopodd:$rot), 4957 OpcodeStr, "f16", []>; 4958 } 4959 let Predicates = [HasNEON,HasV8_3a] in { 4960 def v2f32 : BaseN3VCP8ComplexOdd<op23, op21, op4, 1, 0, IIC_VMACD, 4961 (outs DPR:$Vd), 4962 (ins DPR:$Vn, DPR:$Vm, complexrotateopodd:$rot), 4963 OpcodeStr, "f32", []>; 4964 def v4f32 : BaseN3VCP8ComplexOdd<op23, op21, op4, 1, 1, IIC_VMACQ, 4965 (outs QPR:$Vd), 4966 (ins QPR:$Vn, QPR:$Vm, complexrotateopodd:$rot), 4967 OpcodeStr, "f32", []>; 4968 } 4969} 4970 4971// These instructions index by pairs of lanes, so the VectorIndexes are twice 4972// as wide as the data types. 4973multiclass N3VCP8ComplexTiedLane<bit op4, string OpcodeStr, 4974 SDPatternOperator Op> { 4975 let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in { 4976 def v4f16_indexed : BaseN3VCP8ComplexTiedLane32<op4, 0, 0, IIC_VMACD, 4977 (outs DPR:$Vd), 4978 (ins DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, 4979 VectorIndex32:$lane, complexrotateop:$rot), 4980 OpcodeStr, "f16", []>; 4981 def v8f16_indexed : BaseN3VCP8ComplexTiedLane32<op4, 0, 1, IIC_VMACQ, 4982 (outs QPR:$Vd), 4983 (ins QPR:$src1, QPR:$Vn, DPR_VFP2:$Vm, 4984 VectorIndex32:$lane, complexrotateop:$rot), 4985 OpcodeStr, "f16", []>; 4986 } 4987 let Predicates = [HasNEON,HasV8_3a] in { 4988 def v2f32_indexed : BaseN3VCP8ComplexTiedLane64<op4, 1, 0, IIC_VMACD, 4989 (outs DPR:$Vd), 4990 (ins DPR:$src1, DPR:$Vn, DPR:$Vm, VectorIndex64:$lane, 4991 complexrotateop:$rot), 4992 OpcodeStr, "f32", []>; 4993 def v4f32_indexed : BaseN3VCP8ComplexTiedLane64<op4, 1, 1, IIC_VMACQ, 4994 (outs QPR:$Vd), 4995 (ins QPR:$src1, QPR:$Vn, DPR:$Vm, VectorIndex64:$lane, 4996 complexrotateop:$rot), 4997 OpcodeStr, "f32", []>; 4998 } 4999} 5000 5001defm VCMLA : N3VCP8ComplexTied<1, 0, "vcmla", null_frag>; 5002defm VCADD : N3VCP8ComplexOdd<1, 0, 0, "vcadd", null_frag>; 5003defm VCMLA : N3VCP8ComplexTiedLane<0, "vcmla", null_frag>; 5004 5005let Predicates = [HasNEON,HasV8_3a,HasFullFP16] in { 5006 def : Pat<(v4f16 (int_arm_neon_vcadd_rot90 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm))), 5007 (VCADDv4f16 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm), (i32 0))>; 5008 def : Pat<(v4f16 (int_arm_neon_vcadd_rot270 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm))), 5009 (VCADDv4f16 (v4f16 DPR:$Rn), (v4f16 DPR:$Rm), (i32 1))>; 5010 def : Pat<(v8f16 (int_arm_neon_vcadd_rot90 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm))), 5011 (VCADDv8f16 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm), (i32 0))>; 5012 def : Pat<(v8f16 (int_arm_neon_vcadd_rot270 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm))), 5013 (VCADDv8f16 (v8f16 QPR:$Rn), (v8f16 QPR:$Rm), (i32 1))>; 5014} 5015let Predicates = [HasNEON,HasV8_3a] in { 5016 def : Pat<(v2f32 (int_arm_neon_vcadd_rot90 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm))), 5017 (VCADDv2f32 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm), (i32 0))>; 5018 def : Pat<(v2f32 (int_arm_neon_vcadd_rot270 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm))), 5019 (VCADDv2f32 (v2f32 DPR:$Rn), (v2f32 DPR:$Rm), (i32 1))>; 5020 def : Pat<(v4f32 (int_arm_neon_vcadd_rot90 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm))), 5021 (VCADDv4f32 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm), (i32 0))>; 5022 def : Pat<(v4f32 (int_arm_neon_vcadd_rot270 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm))), 5023 (VCADDv4f32 (v4f32 QPR:$Rn), (v4f32 QPR:$Rm), (i32 1))>; 5024} 5025 5026// Vector Subtract Operations. 5027 5028// VSUB : Vector Subtract (integer and floating-point) 5029defm VSUB : N3V_QHSD<1, 0, 0b1000, 0, IIC_VSUBiD, IIC_VSUBiQ, 5030 "vsub", "i", sub, 0>; 5031def VSUBfd : N3VD<0, 0, 0b10, 0b1101, 0, IIC_VBIND, "vsub", "f32", 5032 v2f32, v2f32, fsub, 0>; 5033def VSUBfq : N3VQ<0, 0, 0b10, 0b1101, 0, IIC_VBINQ, "vsub", "f32", 5034 v4f32, v4f32, fsub, 0>; 5035def VSUBhd : N3VD<0, 0, 0b11, 0b1101, 0, IIC_VBIND, "vsub", "f16", 5036 v4f16, v4f16, fsub, 0>, 5037 Requires<[HasNEON,HasFullFP16]>; 5038def VSUBhq : N3VQ<0, 0, 0b11, 0b1101, 0, IIC_VBINQ, "vsub", "f16", 5039 v8f16, v8f16, fsub, 0>, 5040 Requires<[HasNEON,HasFullFP16]>; 5041// VSUBL : Vector Subtract Long (Q = D - D) 5042defm VSUBLs : N3VLExt_QHS<0,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD, 5043 "vsubl", "s", sub, sext, 0>; 5044defm VSUBLu : N3VLExt_QHS<1,1,0b0010,0, IIC_VSHLiD, IIC_VSHLiD, 5045 "vsubl", "u", sub, zext, 0>; 5046// VSUBW : Vector Subtract Wide (Q = Q - D) 5047defm VSUBWs : N3VW_QHS<0,1,0b0011,0, "vsubw", "s", sub, sext, 0>; 5048defm VSUBWu : N3VW_QHS<1,1,0b0011,0, "vsubw", "u", sub, zext, 0>; 5049// VHSUB : Vector Halving Subtract 5050defm VHSUBs : N3VInt_QHS<0, 0, 0b0010, 0, N3RegFrm, 5051 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5052 "vhsub", "s", int_arm_neon_vhsubs, 0>; 5053defm VHSUBu : N3VInt_QHS<1, 0, 0b0010, 0, N3RegFrm, 5054 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5055 "vhsub", "u", int_arm_neon_vhsubu, 0>; 5056// VQSUB : Vector Saturing Subtract 5057defm VQSUBs : N3VInt_QHSD<0, 0, 0b0010, 1, N3RegFrm, 5058 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5059 "vqsub", "s", ssubsat, 0>; 5060defm VQSUBu : N3VInt_QHSD<1, 0, 0b0010, 1, N3RegFrm, 5061 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5062 "vqsub", "u", usubsat, 0>; 5063// VSUBHN : Vector Subtract and Narrow Returning High Half (D = Q - Q) 5064defm VSUBHN : N3VNInt_HSD<0,1,0b0110,0, "vsubhn", "i", null_frag, 0>; 5065// VRSUBHN : Vector Rounding Subtract and Narrow Returning High Half (D=Q-Q) 5066defm VRSUBHN : N3VNInt_HSD<1,1,0b0110,0, "vrsubhn", "i", 5067 int_arm_neon_vrsubhn, 0>; 5068 5069let Predicates = [HasNEON] in { 5070def : Pat<(v8i8 (trunc (ARMvshruImm (sub (v8i16 QPR:$Vn), QPR:$Vm), 8))), 5071 (VSUBHNv8i8 QPR:$Vn, QPR:$Vm)>; 5072def : Pat<(v4i16 (trunc (ARMvshruImm (sub (v4i32 QPR:$Vn), QPR:$Vm), 16))), 5073 (VSUBHNv4i16 QPR:$Vn, QPR:$Vm)>; 5074def : Pat<(v2i32 (trunc (ARMvshruImm (sub (v2i64 QPR:$Vn), QPR:$Vm), 32))), 5075 (VSUBHNv2i32 QPR:$Vn, QPR:$Vm)>; 5076} 5077 5078// Vector Comparisons. 5079 5080// VCEQ : Vector Compare Equal 5081defm VCEQ : N3V_QHS_cmp<1, 0, 0b1000, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 5082 IIC_VSUBi4Q, "vceq", "i", ARMCCeq, 1>; 5083def VCEQfd : N3VD_cmp<0,0,0b00,0b1110,0, IIC_VBIND, "vceq", "f32", v2i32, v2f32, 5084 ARMCCeq, 1>; 5085def VCEQfq : N3VQ_cmp<0,0,0b00,0b1110,0, IIC_VBINQ, "vceq", "f32", v4i32, v4f32, 5086 ARMCCeq, 1>; 5087def VCEQhd : N3VD_cmp<0,0,0b01,0b1110,0, IIC_VBIND, "vceq", "f16", v4i16, v4f16, 5088 ARMCCeq, 1>, 5089 Requires<[HasNEON, HasFullFP16]>; 5090def VCEQhq : N3VQ_cmp<0,0,0b01,0b1110,0, IIC_VBINQ, "vceq", "f16", v8i16, v8f16, 5091 ARMCCeq, 1>, 5092 Requires<[HasNEON, HasFullFP16]>; 5093 5094let TwoOperandAliasConstraint = "$Vm = $Vd" in 5095defm VCEQz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00010, 0, "vceq", "i", 5096 "$Vd, $Vm, #0", ARMCCeq>; 5097 5098// VCGE : Vector Compare Greater Than or Equal 5099defm VCGEs : N3V_QHS_cmp<0, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 5100 IIC_VSUBi4Q, "vcge", "s", ARMCCge, 0>; 5101defm VCGEu : N3V_QHS_cmp<1, 0, 0b0011, 1, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 5102 IIC_VSUBi4Q, "vcge", "u", ARMCChs, 0>; 5103def VCGEfd : N3VD_cmp<1,0,0b00,0b1110,0, IIC_VBIND, "vcge", "f32", v2i32, v2f32, 5104 ARMCCge, 0>; 5105def VCGEfq : N3VQ_cmp<1,0,0b00,0b1110,0, IIC_VBINQ, "vcge", "f32", v4i32, v4f32, 5106 ARMCCge, 0>; 5107def VCGEhd : N3VD_cmp<1,0,0b01,0b1110,0, IIC_VBIND, "vcge", "f16", v4i16, v4f16, 5108 ARMCCge, 0>, 5109 Requires<[HasNEON, HasFullFP16]>; 5110def VCGEhq : N3VQ_cmp<1,0,0b01,0b1110,0, IIC_VBINQ, "vcge", "f16", v8i16, v8f16, 5111 ARMCCge, 0>, 5112 Requires<[HasNEON, HasFullFP16]>; 5113 5114let TwoOperandAliasConstraint = "$Vm = $Vd" in { 5115defm VCGEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00001, 0, "vcge", "s", 5116 "$Vd, $Vm, #0", ARMCCge>; 5117defm VCLEz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00011, 0, "vcle", "s", 5118 "$Vd, $Vm, #0", ARMCCle>; 5119} 5120 5121// VCGT : Vector Compare Greater Than 5122defm VCGTs : N3V_QHS_cmp<0, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 5123 IIC_VSUBi4Q, "vcgt", "s", ARMCCgt, 0>; 5124defm VCGTu : N3V_QHS_cmp<1, 0, 0b0011, 0, IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, 5125 IIC_VSUBi4Q, "vcgt", "u", ARMCChi, 0>; 5126def VCGTfd : N3VD_cmp<1,0,0b10,0b1110,0, IIC_VBIND, "vcgt", "f32", v2i32, v2f32, 5127 ARMCCgt, 0>; 5128def VCGTfq : N3VQ_cmp<1,0,0b10,0b1110,0, IIC_VBINQ, "vcgt", "f32", v4i32, v4f32, 5129 ARMCCgt, 0>; 5130def VCGThd : N3VD_cmp<1,0,0b11,0b1110,0, IIC_VBIND, "vcgt", "f16", v4i16, v4f16, 5131 ARMCCgt, 0>, 5132 Requires<[HasNEON, HasFullFP16]>; 5133def VCGThq : N3VQ_cmp<1,0,0b11,0b1110,0, IIC_VBINQ, "vcgt", "f16", v8i16, v8f16, 5134 ARMCCgt, 0>, 5135 Requires<[HasNEON, HasFullFP16]>; 5136 5137let TwoOperandAliasConstraint = "$Vm = $Vd" in { 5138defm VCGTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00000, 0, "vcgt", "s", 5139 "$Vd, $Vm, #0", ARMCCgt>; 5140defm VCLTz : N2V_QHS_cmp<0b11, 0b11, 0b01, 0b00100, 0, "vclt", "s", 5141 "$Vd, $Vm, #0", ARMCClt>; 5142} 5143 5144// VACGE : Vector Absolute Compare Greater Than or Equal (aka VCAGE) 5145def VACGEfd : N3VDInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge", 5146 "f32", v2i32, v2f32, int_arm_neon_vacge, 0>; 5147def VACGEfq : N3VQInt<1, 0, 0b00, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge", 5148 "f32", v4i32, v4f32, int_arm_neon_vacge, 0>; 5149def VACGEhd : N3VDInt<1, 0, 0b01, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacge", 5150 "f16", v4i16, v4f16, int_arm_neon_vacge, 0>, 5151 Requires<[HasNEON, HasFullFP16]>; 5152def VACGEhq : N3VQInt<1, 0, 0b01, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacge", 5153 "f16", v8i16, v8f16, int_arm_neon_vacge, 0>, 5154 Requires<[HasNEON, HasFullFP16]>; 5155// VACGT : Vector Absolute Compare Greater Than (aka VCAGT) 5156def VACGTfd : N3VDInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt", 5157 "f32", v2i32, v2f32, int_arm_neon_vacgt, 0>; 5158def VACGTfq : N3VQInt<1, 0, 0b10, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt", 5159 "f32", v4i32, v4f32, int_arm_neon_vacgt, 0>; 5160def VACGThd : N3VDInt<1, 0, 0b11, 0b1110, 1, N3RegFrm, IIC_VBIND, "vacgt", 5161 "f16", v4i16, v4f16, int_arm_neon_vacgt, 0>, 5162 Requires<[HasNEON, HasFullFP16]>; 5163def VACGThq : N3VQInt<1, 0, 0b11, 0b1110, 1, N3RegFrm, IIC_VBINQ, "vacgt", 5164 "f16", v8i16, v8f16, int_arm_neon_vacgt, 0>, 5165 Requires<[HasNEON, HasFullFP16]>; 5166// VTST : Vector Test Bits 5167defm VTST : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q, 5168 IIC_VBINi4Q, "vtst", "", NEONvtst, 1>; 5169 5170def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm", 5171 (VACGTfd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>; 5172def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vn, $Vm", 5173 (VACGTfq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>; 5174def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm", 5175 (VACGEfd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>; 5176def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vn, $Vm", 5177 (VACGEfq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>; 5178let Predicates = [HasNEON, HasFullFP16] in { 5179def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vn, $Vm", 5180 (VACGThd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>; 5181def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vn, $Vm", 5182 (VACGThq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>; 5183def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vn, $Vm", 5184 (VACGEhd DPR:$Vd, DPR:$Vm, DPR:$Vn, pred:$p)>; 5185def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vn, $Vm", 5186 (VACGEhq QPR:$Vd, QPR:$Vm, QPR:$Vn, pred:$p)>; 5187} 5188 5189// +fp16fml Floating Point Multiplication Variants 5190let Predicates = [HasNEON, HasFP16FML], DecoderNamespace= "VFPV8" in { 5191 5192class N3VCP8F16Q1<string asm, RegisterClass Td, RegisterClass Tn, 5193 RegisterClass Tm, bits<2> op1, bits<2> op2, bit op3> 5194 : N3VCP8<op1, op2, 1, op3, (outs Td:$Vd), (ins Tn:$Vn, Tm:$Vm), NoItinerary, 5195 asm, "f16", "$Vd, $Vn, $Vm", "", []>; 5196 5197class N3VCP8F16Q0<string asm, RegisterClass Td, RegisterClass Tn, 5198 RegisterClass Tm, bits<2> op1, bits<2> op2, bit op3> 5199 : N3VCP8Q0<op1, op2, 0, op3, (outs Td:$Vd), (ins Tn:$Vn, Tm:$Vm), NoItinerary, 5200 asm, "f16", "$Vd, $Vn, $Vm", "", []>; 5201 5202// Vd, Vs, Vs[0-15], Idx[0-1] 5203class VFMD<string opc, string type, bits<2> S> 5204 : N3VLaneCP8<0, S, 0, 1, (outs DPR:$Vd), 5205 (ins SPR:$Vn, SPR_8:$Vm, VectorIndex32:$idx), 5206 IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> { 5207 bit idx; 5208 let Inst{3} = idx; 5209 let Inst{19-16} = Vn{4-1}; 5210 let Inst{7} = Vn{0}; 5211 let Inst{5} = Vm{0}; 5212 let Inst{2-0} = Vm{3-1}; 5213} 5214 5215// Vq, Vd, Vd[0-7], Idx[0-3] 5216class VFMQ<string opc, string type, bits<2> S> 5217 : N3VLaneCP8<0, S, 1, 1, (outs QPR:$Vd), 5218 (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx), 5219 IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> { 5220 bits<2> idx; 5221 let Inst{5} = idx{1}; 5222 let Inst{3} = idx{0}; 5223} 5224 5225let hasNoSchedulingInfo = 1 in { 5226// op1 op2 op3 5227def VFMALD : N3VCP8F16Q0<"vfmal", DPR, SPR, SPR, 0b00, 0b10, 1>; 5228def VFMSLD : N3VCP8F16Q0<"vfmsl", DPR, SPR, SPR, 0b01, 0b10, 1>; 5229def VFMALQ : N3VCP8F16Q1<"vfmal", QPR, DPR, DPR, 0b00, 0b10, 1>; 5230def VFMSLQ : N3VCP8F16Q1<"vfmsl", QPR, DPR, DPR, 0b01, 0b10, 1>; 5231def VFMALDI : VFMD<"vfmal", "f16", 0b00>; 5232def VFMSLDI : VFMD<"vfmsl", "f16", 0b01>; 5233def VFMALQI : VFMQ<"vfmal", "f16", 0b00>; 5234def VFMSLQI : VFMQ<"vfmsl", "f16", 0b01>; 5235} 5236} // HasNEON, HasFP16FML 5237 5238 5239def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm", 5240 (VACGTfd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>; 5241def: NEONInstAlias<"vaclt${p}.f32 $Vd, $Vm", 5242 (VACGTfq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>; 5243def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm", 5244 (VACGEfd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>; 5245def: NEONInstAlias<"vacle${p}.f32 $Vd, $Vm", 5246 (VACGEfq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>; 5247let Predicates = [HasNEON, HasFullFP16] in { 5248def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vm", 5249 (VACGThd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>; 5250def: NEONInstAlias<"vaclt${p}.f16 $Vd, $Vm", 5251 (VACGThq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>; 5252def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm", 5253 (VACGEhd DPR:$Vd, DPR:$Vm, DPR:$Vd, pred:$p)>; 5254def: NEONInstAlias<"vacle${p}.f16 $Vd, $Vm", 5255 (VACGEhq QPR:$Vd, QPR:$Vm, QPR:$Vd, pred:$p)>; 5256} 5257 5258// Vector Bitwise Operations. 5259 5260def vnotd : PatFrag<(ops node:$in), 5261 (xor node:$in, (bitconvert (v8i8 NEONimmAllOnesV)))>; 5262def vnotq : PatFrag<(ops node:$in), 5263 (xor node:$in, (bitconvert (v16i8 NEONimmAllOnesV)))>; 5264 5265 5266// VAND : Vector Bitwise AND 5267def VANDd : N3VDX<0, 0, 0b00, 0b0001, 1, IIC_VBINiD, "vand", 5268 v2i32, v2i32, and, 1>; 5269def VANDq : N3VQX<0, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "vand", 5270 v4i32, v4i32, and, 1>; 5271 5272// VEOR : Vector Bitwise Exclusive OR 5273def VEORd : N3VDX<1, 0, 0b00, 0b0001, 1, IIC_VBINiD, "veor", 5274 v2i32, v2i32, xor, 1>; 5275def VEORq : N3VQX<1, 0, 0b00, 0b0001, 1, IIC_VBINiQ, "veor", 5276 v4i32, v4i32, xor, 1>; 5277 5278// VORR : Vector Bitwise OR 5279def VORRd : N3VDX<0, 0, 0b10, 0b0001, 1, IIC_VBINiD, "vorr", 5280 v2i32, v2i32, or, 1>; 5281def VORRq : N3VQX<0, 0, 0b10, 0b0001, 1, IIC_VBINiQ, "vorr", 5282 v4i32, v4i32, or, 1>; 5283 5284def VORRiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 0, 1, 5285 (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src), 5286 IIC_VMOVImm, 5287 "vorr", "i16", "$Vd, $SIMM", "$src = $Vd", 5288 [(set DPR:$Vd, 5289 (v4i16 (ARMvorrImm DPR:$src, timm:$SIMM)))]> { 5290 let Inst{9} = SIMM{9}; 5291} 5292 5293def VORRiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 0, 1, 5294 (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src), 5295 IIC_VMOVImm, 5296 "vorr", "i32", "$Vd, $SIMM", "$src = $Vd", 5297 [(set DPR:$Vd, 5298 (v2i32 (ARMvorrImm DPR:$src, timm:$SIMM)))]> { 5299 let Inst{10-9} = SIMM{10-9}; 5300} 5301 5302def VORRiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 0, 1, 5303 (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src), 5304 IIC_VMOVImm, 5305 "vorr", "i16", "$Vd, $SIMM", "$src = $Vd", 5306 [(set QPR:$Vd, 5307 (v8i16 (ARMvorrImm QPR:$src, timm:$SIMM)))]> { 5308 let Inst{9} = SIMM{9}; 5309} 5310 5311def VORRiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 0, 1, 5312 (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src), 5313 IIC_VMOVImm, 5314 "vorr", "i32", "$Vd, $SIMM", "$src = $Vd", 5315 [(set QPR:$Vd, 5316 (v4i32 (ARMvorrImm QPR:$src, timm:$SIMM)))]> { 5317 let Inst{10-9} = SIMM{10-9}; 5318} 5319 5320 5321// VBIC : Vector Bitwise Bit Clear (AND NOT) 5322let TwoOperandAliasConstraint = "$Vn = $Vd" in { 5323def VBICd : N3VX<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd), 5324 (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD, 5325 "vbic", "$Vd, $Vn, $Vm", "", 5326 [(set DPR:$Vd, (v2i32 (and DPR:$Vn, 5327 (vnotd DPR:$Vm))))]>; 5328def VBICq : N3VX<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd), 5329 (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ, 5330 "vbic", "$Vd, $Vn, $Vm", "", 5331 [(set QPR:$Vd, (v4i32 (and QPR:$Vn, 5332 (vnotq QPR:$Vm))))]>; 5333} 5334 5335def VBICiv4i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 0, 1, 1, 5336 (outs DPR:$Vd), (ins nImmSplatI16:$SIMM, DPR:$src), 5337 IIC_VMOVImm, 5338 "vbic", "i16", "$Vd, $SIMM", "$src = $Vd", 5339 [(set DPR:$Vd, 5340 (v4i16 (ARMvbicImm DPR:$src, timm:$SIMM)))]> { 5341 let Inst{9} = SIMM{9}; 5342} 5343 5344def VBICiv2i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 0, 1, 1, 5345 (outs DPR:$Vd), (ins nImmSplatI32:$SIMM, DPR:$src), 5346 IIC_VMOVImm, 5347 "vbic", "i32", "$Vd, $SIMM", "$src = $Vd", 5348 [(set DPR:$Vd, 5349 (v2i32 (ARMvbicImm DPR:$src, timm:$SIMM)))]> { 5350 let Inst{10-9} = SIMM{10-9}; 5351} 5352 5353def VBICiv8i16 : N1ModImm<1, 0b000, {1,0,?,1}, 0, 1, 1, 1, 5354 (outs QPR:$Vd), (ins nImmSplatI16:$SIMM, QPR:$src), 5355 IIC_VMOVImm, 5356 "vbic", "i16", "$Vd, $SIMM", "$src = $Vd", 5357 [(set QPR:$Vd, 5358 (v8i16 (ARMvbicImm QPR:$src, timm:$SIMM)))]> { 5359 let Inst{9} = SIMM{9}; 5360} 5361 5362def VBICiv4i32 : N1ModImm<1, 0b000, {0,?,?,1}, 0, 1, 1, 1, 5363 (outs QPR:$Vd), (ins nImmSplatI32:$SIMM, QPR:$src), 5364 IIC_VMOVImm, 5365 "vbic", "i32", "$Vd, $SIMM", "$src = $Vd", 5366 [(set QPR:$Vd, 5367 (v4i32 (ARMvbicImm QPR:$src, timm:$SIMM)))]> { 5368 let Inst{10-9} = SIMM{10-9}; 5369} 5370 5371// VORN : Vector Bitwise OR NOT 5372def VORNd : N3VX<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$Vd), 5373 (ins DPR:$Vn, DPR:$Vm), N3RegFrm, IIC_VBINiD, 5374 "vorn", "$Vd, $Vn, $Vm", "", 5375 [(set DPR:$Vd, (v2i32 (or DPR:$Vn, 5376 (vnotd DPR:$Vm))))]>; 5377def VORNq : N3VX<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$Vd), 5378 (ins QPR:$Vn, QPR:$Vm), N3RegFrm, IIC_VBINiQ, 5379 "vorn", "$Vd, $Vn, $Vm", "", 5380 [(set QPR:$Vd, (v4i32 (or QPR:$Vn, 5381 (vnotq QPR:$Vm))))]>; 5382 5383// VMVN : Vector Bitwise NOT (Immediate) 5384 5385let isReMaterializable = 1 in { 5386 5387def VMVNv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 1, 1, (outs DPR:$Vd), 5388 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 5389 "vmvn", "i16", "$Vd, $SIMM", "", 5390 [(set DPR:$Vd, (v4i16 (ARMvmvnImm timm:$SIMM)))]> { 5391 let Inst{9} = SIMM{9}; 5392} 5393 5394def VMVNv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 1, 1, (outs QPR:$Vd), 5395 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 5396 "vmvn", "i16", "$Vd, $SIMM", "", 5397 [(set QPR:$Vd, (v8i16 (ARMvmvnImm timm:$SIMM)))]> { 5398 let Inst{9} = SIMM{9}; 5399} 5400 5401def VMVNv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 1, 1, (outs DPR:$Vd), 5402 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 5403 "vmvn", "i32", "$Vd, $SIMM", "", 5404 [(set DPR:$Vd, (v2i32 (ARMvmvnImm timm:$SIMM)))]> { 5405 let Inst{11-8} = SIMM{11-8}; 5406} 5407 5408def VMVNv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 1, 1, (outs QPR:$Vd), 5409 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 5410 "vmvn", "i32", "$Vd, $SIMM", "", 5411 [(set QPR:$Vd, (v4i32 (ARMvmvnImm timm:$SIMM)))]> { 5412 let Inst{11-8} = SIMM{11-8}; 5413} 5414} 5415 5416// VMVN : Vector Bitwise NOT 5417def VMVNd : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0, 5418 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VSUBiD, 5419 "vmvn", "$Vd, $Vm", "", 5420 [(set DPR:$Vd, (v2i32 (vnotd DPR:$Vm)))]>; 5421def VMVNq : N2VX<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0, 5422 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VSUBiD, 5423 "vmvn", "$Vd, $Vm", "", 5424 [(set QPR:$Vd, (v4i32 (vnotq QPR:$Vm)))]>; 5425let Predicates = [HasNEON] in { 5426def : Pat<(v2i32 (vnotd DPR:$src)), (VMVNd DPR:$src)>; 5427def : Pat<(v4i32 (vnotq QPR:$src)), (VMVNq QPR:$src)>; 5428} 5429 5430// VBSL : Vector Bitwise Select 5431def VBSLd : N3VX<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$Vd), 5432 (ins DPR:$src1, DPR:$Vn, DPR:$Vm), 5433 N3RegFrm, IIC_VCNTiD, 5434 "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd", 5435 [(set DPR:$Vd, 5436 (v2i32 (NEONvbsl DPR:$src1, DPR:$Vn, DPR:$Vm)))]>; 5437let Predicates = [HasNEON] in { 5438def : Pat<(v8i8 (int_arm_neon_vbsl (v8i8 DPR:$src1), 5439 (v8i8 DPR:$Vn), (v8i8 DPR:$Vm))), 5440 (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>; 5441def : Pat<(v4i16 (int_arm_neon_vbsl (v4i16 DPR:$src1), 5442 (v4i16 DPR:$Vn), (v4i16 DPR:$Vm))), 5443 (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>; 5444def : Pat<(v2i32 (int_arm_neon_vbsl (v2i32 DPR:$src1), 5445 (v2i32 DPR:$Vn), (v2i32 DPR:$Vm))), 5446 (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>; 5447def : Pat<(v2f32 (int_arm_neon_vbsl (v2f32 DPR:$src1), 5448 (v2f32 DPR:$Vn), (v2f32 DPR:$Vm))), 5449 (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>; 5450def : Pat<(v1i64 (int_arm_neon_vbsl (v1i64 DPR:$src1), 5451 (v1i64 DPR:$Vn), (v1i64 DPR:$Vm))), 5452 (VBSLd DPR:$src1, DPR:$Vn, DPR:$Vm)>; 5453 5454def : Pat<(v2i32 (or (and DPR:$Vn, DPR:$Vd), 5455 (and DPR:$Vm, (vnotd DPR:$Vd)))), 5456 (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>; 5457 5458def : Pat<(v1i64 (or (and DPR:$Vn, DPR:$Vd), 5459 (and DPR:$Vm, (vnotd DPR:$Vd)))), 5460 (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm)>; 5461} 5462 5463def VBSLq : N3VX<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$Vd), 5464 (ins QPR:$src1, QPR:$Vn, QPR:$Vm), 5465 N3RegFrm, IIC_VCNTiQ, 5466 "vbsl", "$Vd, $Vn, $Vm", "$src1 = $Vd", 5467 [(set QPR:$Vd, 5468 (v4i32 (NEONvbsl QPR:$src1, QPR:$Vn, QPR:$Vm)))]>; 5469 5470let Predicates = [HasNEON] in { 5471def : Pat<(v16i8 (int_arm_neon_vbsl (v16i8 QPR:$src1), 5472 (v16i8 QPR:$Vn), (v16i8 QPR:$Vm))), 5473 (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>; 5474def : Pat<(v8i16 (int_arm_neon_vbsl (v8i16 QPR:$src1), 5475 (v8i16 QPR:$Vn), (v8i16 QPR:$Vm))), 5476 (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>; 5477def : Pat<(v4i32 (int_arm_neon_vbsl (v4i32 QPR:$src1), 5478 (v4i32 QPR:$Vn), (v4i32 QPR:$Vm))), 5479 (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>; 5480def : Pat<(v4f32 (int_arm_neon_vbsl (v4f32 QPR:$src1), 5481 (v4f32 QPR:$Vn), (v4f32 QPR:$Vm))), 5482 (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>; 5483def : Pat<(v2i64 (int_arm_neon_vbsl (v2i64 QPR:$src1), 5484 (v2i64 QPR:$Vn), (v2i64 QPR:$Vm))), 5485 (VBSLq QPR:$src1, QPR:$Vn, QPR:$Vm)>; 5486 5487def : Pat<(v4i32 (or (and QPR:$Vn, QPR:$Vd), 5488 (and QPR:$Vm, (vnotq QPR:$Vd)))), 5489 (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>; 5490def : Pat<(v2i64 (or (and QPR:$Vn, QPR:$Vd), 5491 (and QPR:$Vm, (vnotq QPR:$Vd)))), 5492 (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm)>; 5493} 5494 5495// VBIF : Vector Bitwise Insert if False 5496// like VBSL but with: "vbif $dst, $src3, $src1", "$src2 = $dst", 5497// FIXME: This instruction's encoding MAY NOT BE correct. 5498def VBIFd : N3VX<1, 0, 0b11, 0b0001, 0, 1, 5499 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), 5500 N3RegFrm, IIC_VBINiD, 5501 "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd", 5502 []>; 5503def VBIFq : N3VX<1, 0, 0b11, 0b0001, 1, 1, 5504 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), 5505 N3RegFrm, IIC_VBINiQ, 5506 "vbif", "$Vd, $Vn, $Vm", "$src1 = $Vd", 5507 []>; 5508 5509// VBIT : Vector Bitwise Insert if True 5510// like VBSL but with: "vbit $dst, $src2, $src1", "$src3 = $dst", 5511// FIXME: This instruction's encoding MAY NOT BE correct. 5512def VBITd : N3VX<1, 0, 0b10, 0b0001, 0, 1, 5513 (outs DPR:$Vd), (ins DPR:$src1, DPR:$Vn, DPR:$Vm), 5514 N3RegFrm, IIC_VBINiD, 5515 "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd", 5516 []>; 5517def VBITq : N3VX<1, 0, 0b10, 0b0001, 1, 1, 5518 (outs QPR:$Vd), (ins QPR:$src1, QPR:$Vn, QPR:$Vm), 5519 N3RegFrm, IIC_VBINiQ, 5520 "vbit", "$Vd, $Vn, $Vm", "$src1 = $Vd", 5521 []>; 5522 5523// VBIT/VBIF are not yet implemented. The TwoAddress pass will not go looking 5524// for equivalent operations with different register constraints; it just 5525// inserts copies. 5526 5527// Vector Absolute Differences. 5528 5529// VABD : Vector Absolute Difference 5530defm VABDs : N3VInt_QHS<0, 0, 0b0111, 0, N3RegFrm, 5531 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5532 "vabd", "s", int_arm_neon_vabds, 1>; 5533defm VABDu : N3VInt_QHS<1, 0, 0b0111, 0, N3RegFrm, 5534 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5535 "vabd", "u", int_arm_neon_vabdu, 1>; 5536def VABDfd : N3VDInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBIND, 5537 "vabd", "f32", v2f32, v2f32, int_arm_neon_vabds, 1>; 5538def VABDfq : N3VQInt<1, 0, 0b10, 0b1101, 0, N3RegFrm, IIC_VBINQ, 5539 "vabd", "f32", v4f32, v4f32, int_arm_neon_vabds, 1>; 5540def VABDhd : N3VDInt<1, 0, 0b11, 0b1101, 0, N3RegFrm, IIC_VBIND, 5541 "vabd", "f16", v4f16, v4f16, int_arm_neon_vabds, 1>, 5542 Requires<[HasNEON, HasFullFP16]>; 5543def VABDhq : N3VQInt<1, 0, 0b11, 0b1101, 0, N3RegFrm, IIC_VBINQ, 5544 "vabd", "f16", v8f16, v8f16, int_arm_neon_vabds, 1>, 5545 Requires<[HasNEON, HasFullFP16]>; 5546 5547// VABDL : Vector Absolute Difference Long (Q = | D - D |) 5548defm VABDLs : N3VLIntExt_QHS<0,1,0b0111,0, IIC_VSUBi4Q, 5549 "vabdl", "s", int_arm_neon_vabds, zext, 1>; 5550defm VABDLu : N3VLIntExt_QHS<1,1,0b0111,0, IIC_VSUBi4Q, 5551 "vabdl", "u", int_arm_neon_vabdu, zext, 1>; 5552 5553let Predicates = [HasNEON] in { 5554def : Pat<(v8i16 (abs (sub (zext (v8i8 DPR:$opA)), (zext (v8i8 DPR:$opB))))), 5555 (VABDLuv8i16 DPR:$opA, DPR:$opB)>; 5556def : Pat<(v4i32 (abs (sub (zext (v4i16 DPR:$opA)), (zext (v4i16 DPR:$opB))))), 5557 (VABDLuv4i32 DPR:$opA, DPR:$opB)>; 5558} 5559 5560// ISD::ABS is not legal for v2i64, so VABDL needs to be matched from the 5561// shift/xor pattern for ABS. 5562 5563def abd_shr : 5564 PatFrag<(ops node:$in1, node:$in2, node:$shift), 5565 (ARMvshrsImm (sub (zext node:$in1), 5566 (zext node:$in2)), (i32 $shift))>; 5567 5568let Predicates = [HasNEON] in { 5569def : Pat<(xor (v4i32 (bitconvert (v2i64 (abd_shr (v2i32 DPR:$opA), (v2i32 DPR:$opB), 63)))), 5570 (v4i32 (bitconvert (v2i64 (add (sub (zext (v2i32 DPR:$opA)), 5571 (zext (v2i32 DPR:$opB))), 5572 (abd_shr (v2i32 DPR:$opA), (v2i32 DPR:$opB), 63)))))), 5573 (VABDLuv2i64 DPR:$opA, DPR:$opB)>; 5574} 5575 5576// VABA : Vector Absolute Difference and Accumulate 5577defm VABAs : N3VIntOp_QHS<0,0,0b0111,1, IIC_VABAD, IIC_VABAQ, 5578 "vaba", "s", int_arm_neon_vabds, add>; 5579defm VABAu : N3VIntOp_QHS<1,0,0b0111,1, IIC_VABAD, IIC_VABAQ, 5580 "vaba", "u", int_arm_neon_vabdu, add>; 5581 5582// VABAL : Vector Absolute Difference and Accumulate Long (Q += | D - D |) 5583defm VABALs : N3VLIntExtOp_QHS<0,1,0b0101,0, IIC_VABAD, 5584 "vabal", "s", int_arm_neon_vabds, zext, add>; 5585defm VABALu : N3VLIntExtOp_QHS<1,1,0b0101,0, IIC_VABAD, 5586 "vabal", "u", int_arm_neon_vabdu, zext, add>; 5587 5588// Vector Maximum and Minimum. 5589 5590// VMAX : Vector Maximum 5591defm VMAXs : N3VInt_QHS<0, 0, 0b0110, 0, N3RegFrm, 5592 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5593 "vmax", "s", smax, 1>; 5594defm VMAXu : N3VInt_QHS<1, 0, 0b0110, 0, N3RegFrm, 5595 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5596 "vmax", "u", umax, 1>; 5597def VMAXfd : N3VDInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBIND, 5598 "vmax", "f32", 5599 v2f32, v2f32, fmaximum, 1>; 5600def VMAXfq : N3VQInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBINQ, 5601 "vmax", "f32", 5602 v4f32, v4f32, fmaximum, 1>; 5603def VMAXhd : N3VDInt<0, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VBIND, 5604 "vmax", "f16", 5605 v4f16, v4f16, fmaximum, 1>, 5606 Requires<[HasNEON, HasFullFP16]>; 5607def VMAXhq : N3VQInt<0, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VBINQ, 5608 "vmax", "f16", 5609 v8f16, v8f16, fmaximum, 1>, 5610 Requires<[HasNEON, HasFullFP16]>; 5611 5612// VMAXNM 5613let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in { 5614 def NEON_VMAXNMNDf : N3VDIntnp<0b00110, 0b00, 0b1111, 0, 1, 5615 N3RegFrm, NoItinerary, "vmaxnm", "f32", 5616 v2f32, v2f32, fmaxnum, 1>, 5617 Requires<[HasV8, HasNEON]>; 5618 def NEON_VMAXNMNQf : N3VQIntnp<0b00110, 0b00, 0b1111, 1, 1, 5619 N3RegFrm, NoItinerary, "vmaxnm", "f32", 5620 v4f32, v4f32, fmaxnum, 1>, 5621 Requires<[HasV8, HasNEON]>; 5622 def NEON_VMAXNMNDh : N3VDIntnp<0b00110, 0b01, 0b1111, 0, 1, 5623 N3RegFrm, NoItinerary, "vmaxnm", "f16", 5624 v4f16, v4f16, fmaxnum, 1>, 5625 Requires<[HasV8, HasNEON, HasFullFP16]>; 5626 def NEON_VMAXNMNQh : N3VQIntnp<0b00110, 0b01, 0b1111, 1, 1, 5627 N3RegFrm, NoItinerary, "vmaxnm", "f16", 5628 v8f16, v8f16, fmaxnum, 1>, 5629 Requires<[HasV8, HasNEON, HasFullFP16]>; 5630} 5631 5632// VMIN : Vector Minimum 5633defm VMINs : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm, 5634 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5635 "vmin", "s", smin, 1>; 5636defm VMINu : N3VInt_QHS<1, 0, 0b0110, 1, N3RegFrm, 5637 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q, 5638 "vmin", "u", umin, 1>; 5639def VMINfd : N3VDInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBIND, 5640 "vmin", "f32", 5641 v2f32, v2f32, fminimum, 1>; 5642def VMINfq : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ, 5643 "vmin", "f32", 5644 v4f32, v4f32, fminimum, 1>; 5645def VMINhd : N3VDInt<0, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VBIND, 5646 "vmin", "f16", 5647 v4f16, v4f16, fminimum, 1>, 5648 Requires<[HasNEON, HasFullFP16]>; 5649def VMINhq : N3VQInt<0, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VBINQ, 5650 "vmin", "f16", 5651 v8f16, v8f16, fminimum, 1>, 5652 Requires<[HasNEON, HasFullFP16]>; 5653 5654// VMINNM 5655let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in { 5656 def NEON_VMINNMNDf : N3VDIntnp<0b00110, 0b10, 0b1111, 0, 1, 5657 N3RegFrm, NoItinerary, "vminnm", "f32", 5658 v2f32, v2f32, fminnum, 1>, 5659 Requires<[HasV8, HasNEON]>; 5660 def NEON_VMINNMNQf : N3VQIntnp<0b00110, 0b10, 0b1111, 1, 1, 5661 N3RegFrm, NoItinerary, "vminnm", "f32", 5662 v4f32, v4f32, fminnum, 1>, 5663 Requires<[HasV8, HasNEON]>; 5664 def NEON_VMINNMNDh : N3VDIntnp<0b00110, 0b11, 0b1111, 0, 1, 5665 N3RegFrm, NoItinerary, "vminnm", "f16", 5666 v4f16, v4f16, fminnum, 1>, 5667 Requires<[HasV8, HasNEON, HasFullFP16]>; 5668 def NEON_VMINNMNQh : N3VQIntnp<0b00110, 0b11, 0b1111, 1, 1, 5669 N3RegFrm, NoItinerary, "vminnm", "f16", 5670 v8f16, v8f16, fminnum, 1>, 5671 Requires<[HasV8, HasNEON, HasFullFP16]>; 5672} 5673 5674// Vector Pairwise Operations. 5675 5676// VPADD : Vector Pairwise Add 5677def VPADDi8 : N3VDInt<0, 0, 0b00, 0b1011, 1, N3RegFrm, IIC_VSHLiD, 5678 "vpadd", "i8", 5679 v8i8, v8i8, int_arm_neon_vpadd, 0>; 5680def VPADDi16 : N3VDInt<0, 0, 0b01, 0b1011, 1, N3RegFrm, IIC_VSHLiD, 5681 "vpadd", "i16", 5682 v4i16, v4i16, int_arm_neon_vpadd, 0>; 5683def VPADDi32 : N3VDInt<0, 0, 0b10, 0b1011, 1, N3RegFrm, IIC_VSHLiD, 5684 "vpadd", "i32", 5685 v2i32, v2i32, int_arm_neon_vpadd, 0>; 5686def VPADDf : N3VDInt<1, 0, 0b00, 0b1101, 0, N3RegFrm, 5687 IIC_VPBIND, "vpadd", "f32", 5688 v2f32, v2f32, int_arm_neon_vpadd, 0>; 5689def VPADDh : N3VDInt<1, 0, 0b01, 0b1101, 0, N3RegFrm, 5690 IIC_VPBIND, "vpadd", "f16", 5691 v4f16, v4f16, int_arm_neon_vpadd, 0>, 5692 Requires<[HasNEON, HasFullFP16]>; 5693 5694// VPADDL : Vector Pairwise Add Long 5695defm VPADDLs : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00100, 0, "vpaddl", "s", 5696 int_arm_neon_vpaddls>; 5697defm VPADDLu : N2VPLInt_QHS<0b11, 0b11, 0b00, 0b00101, 0, "vpaddl", "u", 5698 int_arm_neon_vpaddlu>; 5699 5700// VPADAL : Vector Pairwise Add and Accumulate Long 5701defm VPADALs : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01100, 0, "vpadal", "s", 5702 int_arm_neon_vpadals>; 5703defm VPADALu : N2VPLInt2_QHS<0b11, 0b11, 0b00, 0b01101, 0, "vpadal", "u", 5704 int_arm_neon_vpadalu>; 5705 5706// VPMAX : Vector Pairwise Maximum 5707def VPMAXs8 : N3VDInt<0, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 5708 "s8", v8i8, v8i8, int_arm_neon_vpmaxs, 0>; 5709def VPMAXs16 : N3VDInt<0, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 5710 "s16", v4i16, v4i16, int_arm_neon_vpmaxs, 0>; 5711def VPMAXs32 : N3VDInt<0, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 5712 "s32", v2i32, v2i32, int_arm_neon_vpmaxs, 0>; 5713def VPMAXu8 : N3VDInt<1, 0, 0b00, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 5714 "u8", v8i8, v8i8, int_arm_neon_vpmaxu, 0>; 5715def VPMAXu16 : N3VDInt<1, 0, 0b01, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 5716 "u16", v4i16, v4i16, int_arm_neon_vpmaxu, 0>; 5717def VPMAXu32 : N3VDInt<1, 0, 0b10, 0b1010, 0, N3RegFrm, IIC_VSUBi4D, "vpmax", 5718 "u32", v2i32, v2i32, int_arm_neon_vpmaxu, 0>; 5719def VPMAXf : N3VDInt<1, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax", 5720 "f32", v2f32, v2f32, int_arm_neon_vpmaxs, 0>; 5721def VPMAXh : N3VDInt<1, 0, 0b01, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmax", 5722 "f16", v4f16, v4f16, int_arm_neon_vpmaxs, 0>, 5723 Requires<[HasNEON, HasFullFP16]>; 5724 5725// VPMIN : Vector Pairwise Minimum 5726def VPMINs8 : N3VDInt<0, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 5727 "s8", v8i8, v8i8, int_arm_neon_vpmins, 0>; 5728def VPMINs16 : N3VDInt<0, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 5729 "s16", v4i16, v4i16, int_arm_neon_vpmins, 0>; 5730def VPMINs32 : N3VDInt<0, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 5731 "s32", v2i32, v2i32, int_arm_neon_vpmins, 0>; 5732def VPMINu8 : N3VDInt<1, 0, 0b00, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 5733 "u8", v8i8, v8i8, int_arm_neon_vpminu, 0>; 5734def VPMINu16 : N3VDInt<1, 0, 0b01, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 5735 "u16", v4i16, v4i16, int_arm_neon_vpminu, 0>; 5736def VPMINu32 : N3VDInt<1, 0, 0b10, 0b1010, 1, N3RegFrm, IIC_VSUBi4D, "vpmin", 5737 "u32", v2i32, v2i32, int_arm_neon_vpminu, 0>; 5738def VPMINf : N3VDInt<1, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin", 5739 "f32", v2f32, v2f32, int_arm_neon_vpmins, 0>; 5740def VPMINh : N3VDInt<1, 0, 0b11, 0b1111, 0, N3RegFrm, IIC_VPBIND, "vpmin", 5741 "f16", v4f16, v4f16, int_arm_neon_vpmins, 0>, 5742 Requires<[HasNEON, HasFullFP16]>; 5743 5744// Vector Reciprocal and Reciprocal Square Root Estimate and Step. 5745 5746// VRECPE : Vector Reciprocal Estimate 5747def VRECPEd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, 5748 IIC_VUNAD, "vrecpe", "u32", 5749 v2i32, v2i32, int_arm_neon_vrecpe>; 5750def VRECPEq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01000, 0, 5751 IIC_VUNAQ, "vrecpe", "u32", 5752 v4i32, v4i32, int_arm_neon_vrecpe>; 5753def VRECPEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0, 5754 IIC_VUNAD, "vrecpe", "f32", 5755 v2f32, v2f32, int_arm_neon_vrecpe>; 5756def VRECPEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01010, 0, 5757 IIC_VUNAQ, "vrecpe", "f32", 5758 v4f32, v4f32, int_arm_neon_vrecpe>; 5759def VRECPEhd : N2VDInt<0b11, 0b11, 0b01, 0b11, 0b01010, 0, 5760 IIC_VUNAD, "vrecpe", "f16", 5761 v4f16, v4f16, int_arm_neon_vrecpe>, 5762 Requires<[HasNEON, HasFullFP16]>; 5763def VRECPEhq : N2VQInt<0b11, 0b11, 0b01, 0b11, 0b01010, 0, 5764 IIC_VUNAQ, "vrecpe", "f16", 5765 v8f16, v8f16, int_arm_neon_vrecpe>, 5766 Requires<[HasNEON, HasFullFP16]>; 5767 5768// VRECPS : Vector Reciprocal Step 5769def VRECPSfd : N3VDInt<0, 0, 0b00, 0b1111, 1, N3RegFrm, 5770 IIC_VRECSD, "vrecps", "f32", 5771 v2f32, v2f32, int_arm_neon_vrecps, 1>; 5772def VRECPSfq : N3VQInt<0, 0, 0b00, 0b1111, 1, N3RegFrm, 5773 IIC_VRECSQ, "vrecps", "f32", 5774 v4f32, v4f32, int_arm_neon_vrecps, 1>; 5775def VRECPShd : N3VDInt<0, 0, 0b01, 0b1111, 1, N3RegFrm, 5776 IIC_VRECSD, "vrecps", "f16", 5777 v4f16, v4f16, int_arm_neon_vrecps, 1>, 5778 Requires<[HasNEON, HasFullFP16]>; 5779def VRECPShq : N3VQInt<0, 0, 0b01, 0b1111, 1, N3RegFrm, 5780 IIC_VRECSQ, "vrecps", "f16", 5781 v8f16, v8f16, int_arm_neon_vrecps, 1>, 5782 Requires<[HasNEON, HasFullFP16]>; 5783 5784// VRSQRTE : Vector Reciprocal Square Root Estimate 5785def VRSQRTEd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0, 5786 IIC_VUNAD, "vrsqrte", "u32", 5787 v2i32, v2i32, int_arm_neon_vrsqrte>; 5788def VRSQRTEq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01001, 0, 5789 IIC_VUNAQ, "vrsqrte", "u32", 5790 v4i32, v4i32, int_arm_neon_vrsqrte>; 5791def VRSQRTEfd : N2VDInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, 5792 IIC_VUNAD, "vrsqrte", "f32", 5793 v2f32, v2f32, int_arm_neon_vrsqrte>; 5794def VRSQRTEfq : N2VQInt<0b11, 0b11, 0b10, 0b11, 0b01011, 0, 5795 IIC_VUNAQ, "vrsqrte", "f32", 5796 v4f32, v4f32, int_arm_neon_vrsqrte>; 5797def VRSQRTEhd : N2VDInt<0b11, 0b11, 0b01, 0b11, 0b01011, 0, 5798 IIC_VUNAD, "vrsqrte", "f16", 5799 v4f16, v4f16, int_arm_neon_vrsqrte>, 5800 Requires<[HasNEON, HasFullFP16]>; 5801def VRSQRTEhq : N2VQInt<0b11, 0b11, 0b01, 0b11, 0b01011, 0, 5802 IIC_VUNAQ, "vrsqrte", "f16", 5803 v8f16, v8f16, int_arm_neon_vrsqrte>, 5804 Requires<[HasNEON, HasFullFP16]>; 5805 5806// VRSQRTS : Vector Reciprocal Square Root Step 5807def VRSQRTSfd : N3VDInt<0, 0, 0b10, 0b1111, 1, N3RegFrm, 5808 IIC_VRECSD, "vrsqrts", "f32", 5809 v2f32, v2f32, int_arm_neon_vrsqrts, 1>; 5810def VRSQRTSfq : N3VQInt<0, 0, 0b10, 0b1111, 1, N3RegFrm, 5811 IIC_VRECSQ, "vrsqrts", "f32", 5812 v4f32, v4f32, int_arm_neon_vrsqrts, 1>; 5813def VRSQRTShd : N3VDInt<0, 0, 0b11, 0b1111, 1, N3RegFrm, 5814 IIC_VRECSD, "vrsqrts", "f16", 5815 v4f16, v4f16, int_arm_neon_vrsqrts, 1>, 5816 Requires<[HasNEON, HasFullFP16]>; 5817def VRSQRTShq : N3VQInt<0, 0, 0b11, 0b1111, 1, N3RegFrm, 5818 IIC_VRECSQ, "vrsqrts", "f16", 5819 v8f16, v8f16, int_arm_neon_vrsqrts, 1>, 5820 Requires<[HasNEON, HasFullFP16]>; 5821 5822// Vector Shifts. 5823 5824// VSHL : Vector Shift 5825defm VSHLs : N3VInt_QHSDSh<0, 0, 0b0100, 0, N3RegVShFrm, 5826 IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ, 5827 "vshl", "s", int_arm_neon_vshifts>; 5828defm VSHLu : N3VInt_QHSDSh<1, 0, 0b0100, 0, N3RegVShFrm, 5829 IIC_VSHLiD, IIC_VSHLiD, IIC_VSHLiQ, IIC_VSHLiQ, 5830 "vshl", "u", int_arm_neon_vshiftu>; 5831 5832let Predicates = [HasNEON] in { 5833def : Pat<(v8i8 (ARMvshls (v8i8 DPR:$Dn), (v8i8 DPR:$Dm))), 5834 (VSHLsv8i8 DPR:$Dn, DPR:$Dm)>; 5835def : Pat<(v4i16 (ARMvshls (v4i16 DPR:$Dn), (v4i16 DPR:$Dm))), 5836 (VSHLsv4i16 DPR:$Dn, DPR:$Dm)>; 5837def : Pat<(v2i32 (ARMvshls (v2i32 DPR:$Dn), (v2i32 DPR:$Dm))), 5838 (VSHLsv2i32 DPR:$Dn, DPR:$Dm)>; 5839def : Pat<(v1i64 (ARMvshls (v1i64 DPR:$Dn), (v1i64 DPR:$Dm))), 5840 (VSHLsv1i64 DPR:$Dn, DPR:$Dm)>; 5841def : Pat<(v16i8 (ARMvshls (v16i8 QPR:$Dn), (v16i8 QPR:$Dm))), 5842 (VSHLsv16i8 QPR:$Dn, QPR:$Dm)>; 5843def : Pat<(v8i16 (ARMvshls (v8i16 QPR:$Dn), (v8i16 QPR:$Dm))), 5844 (VSHLsv8i16 QPR:$Dn, QPR:$Dm)>; 5845def : Pat<(v4i32 (ARMvshls (v4i32 QPR:$Dn), (v4i32 QPR:$Dm))), 5846 (VSHLsv4i32 QPR:$Dn, QPR:$Dm)>; 5847def : Pat<(v2i64 (ARMvshls (v2i64 QPR:$Dn), (v2i64 QPR:$Dm))), 5848 (VSHLsv2i64 QPR:$Dn, QPR:$Dm)>; 5849 5850def : Pat<(v8i8 (ARMvshlu (v8i8 DPR:$Dn), (v8i8 DPR:$Dm))), 5851 (VSHLuv8i8 DPR:$Dn, DPR:$Dm)>; 5852def : Pat<(v4i16 (ARMvshlu (v4i16 DPR:$Dn), (v4i16 DPR:$Dm))), 5853 (VSHLuv4i16 DPR:$Dn, DPR:$Dm)>; 5854def : Pat<(v2i32 (ARMvshlu (v2i32 DPR:$Dn), (v2i32 DPR:$Dm))), 5855 (VSHLuv2i32 DPR:$Dn, DPR:$Dm)>; 5856def : Pat<(v1i64 (ARMvshlu (v1i64 DPR:$Dn), (v1i64 DPR:$Dm))), 5857 (VSHLuv1i64 DPR:$Dn, DPR:$Dm)>; 5858def : Pat<(v16i8 (ARMvshlu (v16i8 QPR:$Dn), (v16i8 QPR:$Dm))), 5859 (VSHLuv16i8 QPR:$Dn, QPR:$Dm)>; 5860def : Pat<(v8i16 (ARMvshlu (v8i16 QPR:$Dn), (v8i16 QPR:$Dm))), 5861 (VSHLuv8i16 QPR:$Dn, QPR:$Dm)>; 5862def : Pat<(v4i32 (ARMvshlu (v4i32 QPR:$Dn), (v4i32 QPR:$Dm))), 5863 (VSHLuv4i32 QPR:$Dn, QPR:$Dm)>; 5864def : Pat<(v2i64 (ARMvshlu (v2i64 QPR:$Dn), (v2i64 QPR:$Dm))), 5865 (VSHLuv2i64 QPR:$Dn, QPR:$Dm)>; 5866 5867} 5868 5869// VSHL : Vector Shift Left (Immediate) 5870defm VSHLi : N2VShL_QHSD<0, 1, 0b0101, 1, IIC_VSHLiD, "vshl", "i", ARMvshlImm>; 5871 5872// VSHR : Vector Shift Right (Immediate) 5873defm VSHRs : N2VShR_QHSD<0, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "s", "VSHRs", 5874 ARMvshrsImm>; 5875defm VSHRu : N2VShR_QHSD<1, 1, 0b0000, 1, IIC_VSHLiD, "vshr", "u", "VSHRu", 5876 ARMvshruImm>; 5877 5878// VSHLL : Vector Shift Left Long 5879defm VSHLLs : N2VLSh_QHS<0, 1, 0b1010, 0, 0, 1, "vshll", "s", 5880 PatFrag<(ops node:$LHS, node:$RHS), (ARMvshlImm (sext node:$LHS), node:$RHS)>>; 5881defm VSHLLu : N2VLSh_QHS<1, 1, 0b1010, 0, 0, 1, "vshll", "u", 5882 PatFrag<(ops node:$LHS, node:$RHS), (ARMvshlImm (zext node:$LHS), node:$RHS)>>; 5883 5884// VSHLL : Vector Shift Left Long (with maximum shift count) 5885class N2VLShMax<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7, 5886 bit op6, bit op4, string OpcodeStr, string Dt, ValueType ResTy, 5887 ValueType OpTy, Operand ImmTy> 5888 : N2VLSh<op24, op23, op11_8, op7, op6, op4, OpcodeStr, Dt, 5889 ResTy, OpTy, ImmTy, null_frag> { 5890 let Inst{21-16} = op21_16; 5891 let DecoderMethod = "DecodeVSHLMaxInstruction"; 5892} 5893def VSHLLi8 : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8", 5894 v8i16, v8i8, imm8>; 5895def VSHLLi16 : N2VLShMax<1, 1, 0b110110, 0b0011, 0, 0, 0, "vshll", "i16", 5896 v4i32, v4i16, imm16>; 5897def VSHLLi32 : N2VLShMax<1, 1, 0b111010, 0b0011, 0, 0, 0, "vshll", "i32", 5898 v2i64, v2i32, imm32>; 5899 5900let Predicates = [HasNEON] in { 5901def : Pat<(v8i16 (ARMvshlImm (zext (v8i8 DPR:$Rn)), (i32 8))), 5902 (VSHLLi8 DPR:$Rn, 8)>; 5903def : Pat<(v4i32 (ARMvshlImm (zext (v4i16 DPR:$Rn)), (i32 16))), 5904 (VSHLLi16 DPR:$Rn, 16)>; 5905def : Pat<(v2i64 (ARMvshlImm (zext (v2i32 DPR:$Rn)), (i32 32))), 5906 (VSHLLi32 DPR:$Rn, 32)>; 5907def : Pat<(v8i16 (ARMvshlImm (sext (v8i8 DPR:$Rn)), (i32 8))), 5908 (VSHLLi8 DPR:$Rn, 8)>; 5909def : Pat<(v4i32 (ARMvshlImm (sext (v4i16 DPR:$Rn)), (i32 16))), 5910 (VSHLLi16 DPR:$Rn, 16)>; 5911def : Pat<(v2i64 (ARMvshlImm (sext (v2i32 DPR:$Rn)), (i32 32))), 5912 (VSHLLi32 DPR:$Rn, 32)>; 5913def : Pat<(v8i16 (ARMvshlImm (anyext (v8i8 DPR:$Rn)), (i32 8))), 5914 (VSHLLi8 DPR:$Rn, 8)>; 5915def : Pat<(v4i32 (ARMvshlImm (anyext (v4i16 DPR:$Rn)), (i32 16))), 5916 (VSHLLi16 DPR:$Rn, 16)>; 5917def : Pat<(v2i64 (ARMvshlImm (anyext (v2i32 DPR:$Rn)), (i32 32))), 5918 (VSHLLi32 DPR:$Rn, 32)>; 5919} 5920 5921// VSHRN : Vector Shift Right and Narrow 5922defm VSHRN : N2VNSh_HSD<0,1,0b1000,0,0,1, IIC_VSHLiD, "vshrn", "i", 5923 PatFrag<(ops node:$Rn, node:$amt), 5924 (trunc (ARMvshrsImm node:$Rn, node:$amt))>>; 5925 5926let Predicates = [HasNEON] in { 5927def : Pat<(v8i8 (trunc (ARMvshruImm (v8i16 QPR:$Vn), shr_imm8:$amt))), 5928 (VSHRNv8i8 QPR:$Vn, shr_imm8:$amt)>; 5929def : Pat<(v4i16 (trunc (ARMvshruImm (v4i32 QPR:$Vn), shr_imm16:$amt))), 5930 (VSHRNv4i16 QPR:$Vn, shr_imm16:$amt)>; 5931def : Pat<(v2i32 (trunc (ARMvshruImm (v2i64 QPR:$Vn), shr_imm32:$amt))), 5932 (VSHRNv2i32 QPR:$Vn, shr_imm32:$amt)>; 5933} 5934 5935// VRSHL : Vector Rounding Shift 5936defm VRSHLs : N3VInt_QHSDSh<0, 0, 0b0101, 0, N3RegVShFrm, 5937 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 5938 "vrshl", "s", int_arm_neon_vrshifts>; 5939defm VRSHLu : N3VInt_QHSDSh<1, 0, 0b0101, 0, N3RegVShFrm, 5940 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 5941 "vrshl", "u", int_arm_neon_vrshiftu>; 5942// VRSHR : Vector Rounding Shift Right 5943defm VRSHRs : N2VShR_QHSD<0,1,0b0010,1, IIC_VSHLi4D, "vrshr", "s", "VRSHRs", 5944 NEONvrshrsImm>; 5945defm VRSHRu : N2VShR_QHSD<1,1,0b0010,1, IIC_VSHLi4D, "vrshr", "u", "VRSHRu", 5946 NEONvrshruImm>; 5947 5948// VRSHRN : Vector Rounding Shift Right and Narrow 5949defm VRSHRN : N2VNSh_HSD<0, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vrshrn", "i", 5950 NEONvrshrnImm>; 5951 5952// VQSHL : Vector Saturating Shift 5953defm VQSHLs : N3VInt_QHSDSh<0, 0, 0b0100, 1, N3RegVShFrm, 5954 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 5955 "vqshl", "s", int_arm_neon_vqshifts>; 5956defm VQSHLu : N3VInt_QHSDSh<1, 0, 0b0100, 1, N3RegVShFrm, 5957 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 5958 "vqshl", "u", int_arm_neon_vqshiftu>; 5959// VQSHL : Vector Saturating Shift Left (Immediate) 5960defm VQSHLsi : N2VShL_QHSD<0,1,0b0111,1, IIC_VSHLi4D, "vqshl", "s",NEONvqshlsImm>; 5961defm VQSHLui : N2VShL_QHSD<1,1,0b0111,1, IIC_VSHLi4D, "vqshl", "u",NEONvqshluImm>; 5962 5963// VQSHLU : Vector Saturating Shift Left (Immediate, Unsigned) 5964defm VQSHLsu : N2VShL_QHSD<1,1,0b0110,1, IIC_VSHLi4D,"vqshlu","s",NEONvqshlsuImm>; 5965 5966// VQSHRN : Vector Saturating Shift Right and Narrow 5967defm VQSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "s", 5968 NEONvqshrnsImm>; 5969defm VQSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 0, 1, IIC_VSHLi4D, "vqshrn", "u", 5970 NEONvqshrnuImm>; 5971 5972// VQSHRUN : Vector Saturating Shift Right and Narrow (Unsigned) 5973defm VQSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 0, 1, IIC_VSHLi4D, "vqshrun", "s", 5974 NEONvqshrnsuImm>; 5975 5976// VQRSHL : Vector Saturating Rounding Shift 5977defm VQRSHLs : N3VInt_QHSDSh<0, 0, 0b0101, 1, N3RegVShFrm, 5978 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 5979 "vqrshl", "s", int_arm_neon_vqrshifts>; 5980defm VQRSHLu : N3VInt_QHSDSh<1, 0, 0b0101, 1, N3RegVShFrm, 5981 IIC_VSHLi4D, IIC_VSHLi4D, IIC_VSHLi4Q, IIC_VSHLi4Q, 5982 "vqrshl", "u", int_arm_neon_vqrshiftu>; 5983 5984// VQRSHRN : Vector Saturating Rounding Shift Right and Narrow 5985defm VQRSHRNs : N2VNSh_HSD<0, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "s", 5986 NEONvqrshrnsImm>; 5987defm VQRSHRNu : N2VNSh_HSD<1, 1, 0b1001, 0, 1, 1, IIC_VSHLi4D, "vqrshrn", "u", 5988 NEONvqrshrnuImm>; 5989 5990// VQRSHRUN : Vector Saturating Rounding Shift Right and Narrow (Unsigned) 5991defm VQRSHRUN : N2VNSh_HSD<1, 1, 0b1000, 0, 1, 1, IIC_VSHLi4D, "vqrshrun", "s", 5992 NEONvqrshrnsuImm>; 5993 5994// VSRA : Vector Shift Right and Accumulate 5995defm VSRAs : N2VShAdd_QHSD<0, 1, 0b0001, 1, "vsra", "s", ARMvshrsImm>; 5996defm VSRAu : N2VShAdd_QHSD<1, 1, 0b0001, 1, "vsra", "u", ARMvshruImm>; 5997// VRSRA : Vector Rounding Shift Right and Accumulate 5998defm VRSRAs : N2VShAdd_QHSD<0, 1, 0b0011, 1, "vrsra", "s", NEONvrshrsImm>; 5999defm VRSRAu : N2VShAdd_QHSD<1, 1, 0b0011, 1, "vrsra", "u", NEONvrshruImm>; 6000 6001// VSLI : Vector Shift Left and Insert 6002defm VSLI : N2VShInsL_QHSD<1, 1, 0b0101, 1, "vsli">; 6003 6004// VSRI : Vector Shift Right and Insert 6005defm VSRI : N2VShInsR_QHSD<1, 1, 0b0100, 1, "vsri">; 6006 6007// Vector Absolute and Saturating Absolute. 6008 6009// VABS : Vector Absolute Value 6010defm VABS : N2VInt_QHS<0b11, 0b11, 0b01, 0b00110, 0, 6011 IIC_VUNAiD, IIC_VUNAiQ, "vabs", "s", abs>; 6012def VABSfd : N2VD<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 6013 "vabs", "f32", 6014 v2f32, v2f32, fabs>; 6015def VABSfq : N2VQ<0b11, 0b11, 0b10, 0b01, 0b01110, 0, 6016 "vabs", "f32", 6017 v4f32, v4f32, fabs>; 6018def VABShd : N2VD<0b11, 0b11, 0b01, 0b01, 0b01110, 0, 6019 "vabs", "f16", 6020 v4f16, v4f16, fabs>, 6021 Requires<[HasNEON, HasFullFP16]>; 6022def VABShq : N2VQ<0b11, 0b11, 0b01, 0b01, 0b01110, 0, 6023 "vabs", "f16", 6024 v8f16, v8f16, fabs>, 6025 Requires<[HasNEON, HasFullFP16]>; 6026 6027// VQABS : Vector Saturating Absolute Value 6028defm VQABS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01110, 0, 6029 IIC_VQUNAiD, IIC_VQUNAiQ, "vqabs", "s", 6030 int_arm_neon_vqabs>; 6031 6032// Vector Negate. 6033 6034def vnegd : PatFrag<(ops node:$in), 6035 (sub (bitconvert (v2i32 NEONimmAllZerosV)), node:$in)>; 6036def vnegq : PatFrag<(ops node:$in), 6037 (sub (bitconvert (v4i32 NEONimmAllZerosV)), node:$in)>; 6038 6039class VNEGD<bits<2> size, string OpcodeStr, string Dt, ValueType Ty> 6040 : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$Vd), (ins DPR:$Vm), 6041 IIC_VSHLiD, OpcodeStr, Dt, "$Vd, $Vm", "", 6042 [(set DPR:$Vd, (Ty (vnegd DPR:$Vm)))]>; 6043class VNEGQ<bits<2> size, string OpcodeStr, string Dt, ValueType Ty> 6044 : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$Vd), (ins QPR:$Vm), 6045 IIC_VSHLiQ, OpcodeStr, Dt, "$Vd, $Vm", "", 6046 [(set QPR:$Vd, (Ty (vnegq QPR:$Vm)))]>; 6047 6048// VNEG : Vector Negate (integer) 6049def VNEGs8d : VNEGD<0b00, "vneg", "s8", v8i8>; 6050def VNEGs16d : VNEGD<0b01, "vneg", "s16", v4i16>; 6051def VNEGs32d : VNEGD<0b10, "vneg", "s32", v2i32>; 6052def VNEGs8q : VNEGQ<0b00, "vneg", "s8", v16i8>; 6053def VNEGs16q : VNEGQ<0b01, "vneg", "s16", v8i16>; 6054def VNEGs32q : VNEGQ<0b10, "vneg", "s32", v4i32>; 6055 6056// VNEG : Vector Negate (floating-point) 6057def VNEGfd : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0, 6058 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD, 6059 "vneg", "f32", "$Vd, $Vm", "", 6060 [(set DPR:$Vd, (v2f32 (fneg DPR:$Vm)))]>; 6061def VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0, 6062 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ, 6063 "vneg", "f32", "$Vd, $Vm", "", 6064 [(set QPR:$Vd, (v4f32 (fneg QPR:$Vm)))]>; 6065def VNEGhd : N2V<0b11, 0b11, 0b01, 0b01, 0b01111, 0, 0, 6066 (outs DPR:$Vd), (ins DPR:$Vm), IIC_VUNAD, 6067 "vneg", "f16", "$Vd, $Vm", "", 6068 [(set DPR:$Vd, (v4f16 (fneg DPR:$Vm)))]>, 6069 Requires<[HasNEON, HasFullFP16]>; 6070def VNEGhq : N2V<0b11, 0b11, 0b01, 0b01, 0b01111, 1, 0, 6071 (outs QPR:$Vd), (ins QPR:$Vm), IIC_VUNAQ, 6072 "vneg", "f16", "$Vd, $Vm", "", 6073 [(set QPR:$Vd, (v8f16 (fneg QPR:$Vm)))]>, 6074 Requires<[HasNEON, HasFullFP16]>; 6075 6076let Predicates = [HasNEON] in { 6077def : Pat<(v8i8 (vnegd DPR:$src)), (VNEGs8d DPR:$src)>; 6078def : Pat<(v4i16 (vnegd DPR:$src)), (VNEGs16d DPR:$src)>; 6079def : Pat<(v2i32 (vnegd DPR:$src)), (VNEGs32d DPR:$src)>; 6080def : Pat<(v16i8 (vnegq QPR:$src)), (VNEGs8q QPR:$src)>; 6081def : Pat<(v8i16 (vnegq QPR:$src)), (VNEGs16q QPR:$src)>; 6082def : Pat<(v4i32 (vnegq QPR:$src)), (VNEGs32q QPR:$src)>; 6083} 6084 6085// VQNEG : Vector Saturating Negate 6086defm VQNEG : N2VInt_QHS<0b11, 0b11, 0b00, 0b01111, 0, 6087 IIC_VQUNAiD, IIC_VQUNAiQ, "vqneg", "s", 6088 int_arm_neon_vqneg>; 6089 6090// Vector Bit Counting Operations. 6091 6092// VCLS : Vector Count Leading Sign Bits 6093defm VCLS : N2VInt_QHS<0b11, 0b11, 0b00, 0b01000, 0, 6094 IIC_VCNTiD, IIC_VCNTiQ, "vcls", "s", 6095 int_arm_neon_vcls>; 6096// VCLZ : Vector Count Leading Zeros 6097defm VCLZ : N2VInt_QHS<0b11, 0b11, 0b00, 0b01001, 0, 6098 IIC_VCNTiD, IIC_VCNTiQ, "vclz", "i", 6099 ctlz>; 6100// VCNT : Vector Count One Bits 6101def VCNTd : N2VDInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, 6102 IIC_VCNTiD, "vcnt", "8", 6103 v8i8, v8i8, ctpop>; 6104def VCNTq : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, 6105 IIC_VCNTiQ, "vcnt", "8", 6106 v16i8, v16i8, ctpop>; 6107 6108// Vector Swap 6109def VSWPd : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 0, 0, 6110 (outs DPR:$Vd, DPR:$Vm), (ins DPR:$in1, DPR:$in2), 6111 NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm", 6112 []>; 6113def VSWPq : N2VX<0b11, 0b11, 0b00, 0b10, 0b00000, 1, 0, 6114 (outs QPR:$Vd, QPR:$Vm), (ins QPR:$in1, QPR:$in2), 6115 NoItinerary, "vswp", "$Vd, $Vm", "$in1 = $Vd, $in2 = $Vm", 6116 []>; 6117 6118// Vector Move Operations. 6119 6120// VMOV : Vector Move (Register) 6121def : NEONInstAlias<"vmov${p} $Vd, $Vm", 6122 (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>; 6123def : NEONInstAlias<"vmov${p} $Vd, $Vm", 6124 (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>; 6125 6126// VMOV : Vector Move (Immediate) 6127 6128// Although VMOVs are not strictly speaking cheap, they are as expensive 6129// as their copies counterpart (VORR), so we should prefer rematerialization 6130// over splitting when it applies. 6131let isReMaterializable = 1, isAsCheapAsAMove=1 in { 6132def VMOVv8i8 : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$Vd), 6133 (ins nImmSplatI8:$SIMM), IIC_VMOVImm, 6134 "vmov", "i8", "$Vd, $SIMM", "", 6135 [(set DPR:$Vd, (v8i8 (ARMvmovImm timm:$SIMM)))]>; 6136def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$Vd), 6137 (ins nImmSplatI8:$SIMM), IIC_VMOVImm, 6138 "vmov", "i8", "$Vd, $SIMM", "", 6139 [(set QPR:$Vd, (v16i8 (ARMvmovImm timm:$SIMM)))]>; 6140 6141def VMOVv4i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 0, 0, 1, (outs DPR:$Vd), 6142 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 6143 "vmov", "i16", "$Vd, $SIMM", "", 6144 [(set DPR:$Vd, (v4i16 (ARMvmovImm timm:$SIMM)))]> { 6145 let Inst{9} = SIMM{9}; 6146} 6147 6148def VMOVv8i16 : N1ModImm<1, 0b000, {1,0,?,0}, 0, 1, 0, 1, (outs QPR:$Vd), 6149 (ins nImmSplatI16:$SIMM), IIC_VMOVImm, 6150 "vmov", "i16", "$Vd, $SIMM", "", 6151 [(set QPR:$Vd, (v8i16 (ARMvmovImm timm:$SIMM)))]> { 6152 let Inst{9} = SIMM{9}; 6153} 6154 6155def VMOVv2i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 0, 0, 1, (outs DPR:$Vd), 6156 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 6157 "vmov", "i32", "$Vd, $SIMM", "", 6158 [(set DPR:$Vd, (v2i32 (ARMvmovImm timm:$SIMM)))]> { 6159 let Inst{11-8} = SIMM{11-8}; 6160} 6161 6162def VMOVv4i32 : N1ModImm<1, 0b000, {?,?,?,?}, 0, 1, 0, 1, (outs QPR:$Vd), 6163 (ins nImmVMOVI32:$SIMM), IIC_VMOVImm, 6164 "vmov", "i32", "$Vd, $SIMM", "", 6165 [(set QPR:$Vd, (v4i32 (ARMvmovImm timm:$SIMM)))]> { 6166 let Inst{11-8} = SIMM{11-8}; 6167} 6168 6169def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$Vd), 6170 (ins nImmSplatI64:$SIMM), IIC_VMOVImm, 6171 "vmov", "i64", "$Vd, $SIMM", "", 6172 [(set DPR:$Vd, (v1i64 (ARMvmovImm timm:$SIMM)))]>; 6173def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$Vd), 6174 (ins nImmSplatI64:$SIMM), IIC_VMOVImm, 6175 "vmov", "i64", "$Vd, $SIMM", "", 6176 [(set QPR:$Vd, (v2i64 (ARMvmovImm timm:$SIMM)))]>; 6177 6178def VMOVv2f32 : N1ModImm<1, 0b000, 0b1111, 0, 0, 0, 1, (outs DPR:$Vd), 6179 (ins nImmVMOVF32:$SIMM), IIC_VMOVImm, 6180 "vmov", "f32", "$Vd, $SIMM", "", 6181 [(set DPR:$Vd, (v2f32 (ARMvmovFPImm timm:$SIMM)))]>; 6182def VMOVv4f32 : N1ModImm<1, 0b000, 0b1111, 0, 1, 0, 1, (outs QPR:$Vd), 6183 (ins nImmVMOVF32:$SIMM), IIC_VMOVImm, 6184 "vmov", "f32", "$Vd, $SIMM", "", 6185 [(set QPR:$Vd, (v4f32 (ARMvmovFPImm timm:$SIMM)))]>; 6186} // isReMaterializable, isAsCheapAsAMove 6187 6188// Add support for bytes replication feature, so it could be GAS compatible. 6189multiclass NEONImmReplicateI8InstAlias<ValueType To> { 6190 // E.g. instructions below: 6191 // "vmov.i32 d0, #0xffffffff" 6192 // "vmov.i32 d0, #0xabababab" 6193 // "vmov.i16 d0, #0xabab" 6194 // are incorrect, but we could deal with such cases. 6195 // For last two instructions, for example, it should emit: 6196 // "vmov.i8 d0, #0xab" 6197 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm", 6198 (VMOVv8i8 DPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>; 6199 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm", 6200 (VMOVv16i8 QPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>; 6201 // Also add same support for VMVN instructions. So instruction: 6202 // "vmvn.i32 d0, #0xabababab" 6203 // actually means: 6204 // "vmov.i8 d0, #0x54" 6205 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm", 6206 (VMOVv8i8 DPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>; 6207 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm", 6208 (VMOVv16i8 QPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>; 6209} 6210 6211defm : NEONImmReplicateI8InstAlias<i16>; 6212defm : NEONImmReplicateI8InstAlias<i32>; 6213defm : NEONImmReplicateI8InstAlias<i64>; 6214 6215// Similar to above for types other than i8, e.g.: 6216// "vmov.i32 d0, #0xab00ab00" -> "vmov.i16 d0, #0xab00" 6217// "vmvn.i64 q0, #0xab000000ab000000" -> "vmvn.i32 q0, #0xab000000" 6218// In this case we do not canonicalize VMVN to VMOV 6219multiclass NEONImmReplicateInstAlias<ValueType From, NeonI V8, NeonI V16, 6220 NeonI NV8, NeonI NV16, ValueType To> { 6221 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm", 6222 (V8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>; 6223 def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm", 6224 (V16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>; 6225 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm", 6226 (NV8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>; 6227 def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm", 6228 (NV16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>; 6229} 6230 6231defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16, 6232 VMVNv4i16, VMVNv8i16, i32>; 6233defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16, 6234 VMVNv4i16, VMVNv8i16, i64>; 6235defm : NEONImmReplicateInstAlias<i32, VMOVv2i32, VMOVv4i32, 6236 VMVNv2i32, VMVNv4i32, i64>; 6237// TODO: add "VMOV <-> VMVN" conversion for cases like 6238// "vmov.i32 d0, #0xffaaffaa" -> "vmvn.i16 d0, #0x55" 6239// "vmvn.i32 d0, #0xaaffaaff" -> "vmov.i16 d0, #0xff00" 6240 6241// On some CPUs the two instructions "vmov.i32 dD, #0" and "vmov.i32 qD, #0" 6242// require zero cycles to execute so they should be used wherever possible for 6243// setting a register to zero. 6244 6245// Even without these pseudo-insts we would probably end up with the correct 6246// instruction, but we could not mark the general ones with "isAsCheapAsAMove" 6247// since they are sometimes rather expensive (in general). 6248 6249let AddedComplexity = 50, isAsCheapAsAMove = 1, isReMaterializable = 1 in { 6250 def VMOVD0 : ARMPseudoExpand<(outs DPR:$Vd), (ins), 4, IIC_VMOVImm, 6251 [(set DPR:$Vd, (v2i32 NEONimmAllZerosV))], 6252 (VMOVv2i32 DPR:$Vd, 0, (ops 14, zero_reg))>, 6253 Requires<[HasZCZ]>; 6254 def VMOVQ0 : ARMPseudoExpand<(outs QPR:$Vd), (ins), 4, IIC_VMOVImm, 6255 [(set QPR:$Vd, (v4i32 NEONimmAllZerosV))], 6256 (VMOVv4i32 QPR:$Vd, 0, (ops 14, zero_reg))>, 6257 Requires<[HasZCZ]>; 6258} 6259 6260// VMOV : Vector Get Lane (move scalar to ARM core register) 6261 6262def VGETLNs8 : NVGetLane<{1,1,1,0,0,1,?,1}, 0b1011, {?,?}, 6263 (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane), 6264 IIC_VMOVSI, "vmov", "s8", "$R, $V$lane", 6265 [(set GPR:$R, (ARMvgetlanes (v8i8 DPR:$V), 6266 imm:$lane))]> { 6267 let Inst{21} = lane{2}; 6268 let Inst{6-5} = lane{1-0}; 6269} 6270def VGETLNs16 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, {?,1}, 6271 (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane), 6272 IIC_VMOVSI, "vmov", "s16", "$R, $V$lane", 6273 [(set GPR:$R, (ARMvgetlanes (v4i16 DPR:$V), 6274 imm:$lane))]> { 6275 let Inst{21} = lane{1}; 6276 let Inst{6} = lane{0}; 6277} 6278def VGETLNu8 : NVGetLane<{1,1,1,0,1,1,?,1}, 0b1011, {?,?}, 6279 (outs GPR:$R), (ins DPR:$V, VectorIndex8:$lane), 6280 IIC_VMOVSI, "vmov", "u8", "$R, $V$lane", 6281 [(set GPR:$R, (ARMvgetlaneu (v8i8 DPR:$V), 6282 imm:$lane))]> { 6283 let Inst{21} = lane{2}; 6284 let Inst{6-5} = lane{1-0}; 6285} 6286def VGETLNu16 : NVGetLane<{1,1,1,0,1,0,?,1}, 0b1011, {?,1}, 6287 (outs GPR:$R), (ins DPR:$V, VectorIndex16:$lane), 6288 IIC_VMOVSI, "vmov", "u16", "$R, $V$lane", 6289 [(set GPR:$R, (ARMvgetlaneu (v4i16 DPR:$V), 6290 imm:$lane))]> { 6291 let Inst{21} = lane{1}; 6292 let Inst{6} = lane{0}; 6293} 6294def VGETLNi32 : NVGetLane<{1,1,1,0,0,0,?,1}, 0b1011, 0b00, 6295 (outs GPR:$R), (ins DPR:$V, VectorIndex32:$lane), 6296 IIC_VMOVSI, "vmov", "32", "$R, $V$lane", 6297 [(set GPR:$R, (extractelt (v2i32 DPR:$V), 6298 imm:$lane))]>, 6299 Requires<[HasFPRegs, HasFastVGETLNi32]> { 6300 let Inst{21} = lane{0}; 6301} 6302let Predicates = [HasNEON] in { 6303// def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td 6304def : Pat<(ARMvgetlanes (v16i8 QPR:$src), imm:$lane), 6305 (VGETLNs8 (v8i8 (EXTRACT_SUBREG QPR:$src, 6306 (DSubReg_i8_reg imm:$lane))), 6307 (SubReg_i8_lane imm:$lane))>; 6308def : Pat<(ARMvgetlanes (v8i16 QPR:$src), imm:$lane), 6309 (VGETLNs16 (v4i16 (EXTRACT_SUBREG QPR:$src, 6310 (DSubReg_i16_reg imm:$lane))), 6311 (SubReg_i16_lane imm:$lane))>; 6312def : Pat<(ARMvgetlaneu (v16i8 QPR:$src), imm:$lane), 6313 (VGETLNu8 (v8i8 (EXTRACT_SUBREG QPR:$src, 6314 (DSubReg_i8_reg imm:$lane))), 6315 (SubReg_i8_lane imm:$lane))>; 6316def : Pat<(ARMvgetlaneu (v8i16 QPR:$src), imm:$lane), 6317 (VGETLNu16 (v4i16 (EXTRACT_SUBREG QPR:$src, 6318 (DSubReg_i16_reg imm:$lane))), 6319 (SubReg_i16_lane imm:$lane))>; 6320} 6321def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane), 6322 (VGETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src, 6323 (DSubReg_i32_reg imm:$lane))), 6324 (SubReg_i32_lane imm:$lane))>, 6325 Requires<[HasNEON, HasFastVGETLNi32]>; 6326def : Pat<(extractelt (v2i32 DPR:$src), imm:$lane), 6327 (COPY_TO_REGCLASS 6328 (i32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>, 6329 Requires<[HasNEON, HasSlowVGETLNi32]>; 6330def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane), 6331 (COPY_TO_REGCLASS 6332 (i32 (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane))), GPR)>, 6333 Requires<[HasNEON, HasSlowVGETLNi32]>; 6334let Predicates = [HasNEON] in { 6335def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2), 6336 (EXTRACT_SUBREG (v2f32 (COPY_TO_REGCLASS (v2f32 DPR:$src1),DPR_VFP2)), 6337 (SSubReg_f32_reg imm:$src2))>; 6338def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2), 6339 (EXTRACT_SUBREG (v4f32 (COPY_TO_REGCLASS (v4f32 QPR:$src1),QPR_VFP2)), 6340 (SSubReg_f32_reg imm:$src2))>; 6341//def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2), 6342// (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; 6343def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2), 6344 (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; 6345} 6346 6347def imm_even : ImmLeaf<i32, [{ return (Imm & 1) == 0; }]>; 6348def imm_odd : ImmLeaf<i32, [{ return (Imm & 1) == 1; }]>; 6349 6350let Predicates = [HasNEON] in { 6351def : Pat<(extractelt (v4f16 DPR:$src), imm_even:$lane), 6352 (EXTRACT_SUBREG 6353 (v2f32 (COPY_TO_REGCLASS (v4f16 DPR:$src), DPR_VFP2)), 6354 (SSubReg_f16_reg imm_even:$lane))>; 6355 6356def : Pat<(extractelt (v4f16 DPR:$src), imm_odd:$lane), 6357 (COPY_TO_REGCLASS 6358 (VMOVH (EXTRACT_SUBREG 6359 (v2f32 (COPY_TO_REGCLASS (v4f16 DPR:$src), DPR_VFP2)), 6360 (SSubReg_f16_reg imm_odd:$lane))), 6361 HPR)>; 6362 6363def : Pat<(extractelt (v8f16 QPR:$src), imm_even:$lane), 6364 (EXTRACT_SUBREG 6365 (v4f32 (COPY_TO_REGCLASS (v8f16 QPR:$src), QPR_VFP2)), 6366 (SSubReg_f16_reg imm_even:$lane))>; 6367 6368def : Pat<(extractelt (v8f16 QPR:$src), imm_odd:$lane), 6369 (COPY_TO_REGCLASS 6370 (VMOVH (EXTRACT_SUBREG 6371 (v4f32 (COPY_TO_REGCLASS (v8f16 QPR:$src), QPR_VFP2)), 6372 (SSubReg_f16_reg imm_odd:$lane))), 6373 HPR)>; 6374} 6375 6376// VMOV : Vector Set Lane (move ARM core register to scalar) 6377 6378let Constraints = "$src1 = $V" in { 6379def VSETLNi8 : NVSetLane<{1,1,1,0,0,1,?,0}, 0b1011, {?,?}, (outs DPR:$V), 6380 (ins DPR:$src1, GPR:$R, VectorIndex8:$lane), 6381 IIC_VMOVISL, "vmov", "8", "$V$lane, $R", 6382 [(set DPR:$V, (vector_insert (v8i8 DPR:$src1), 6383 GPR:$R, imm:$lane))]> { 6384 let Inst{21} = lane{2}; 6385 let Inst{6-5} = lane{1-0}; 6386} 6387def VSETLNi16 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, {?,1}, (outs DPR:$V), 6388 (ins DPR:$src1, GPR:$R, VectorIndex16:$lane), 6389 IIC_VMOVISL, "vmov", "16", "$V$lane, $R", 6390 [(set DPR:$V, (vector_insert (v4i16 DPR:$src1), 6391 GPR:$R, imm:$lane))]> { 6392 let Inst{21} = lane{1}; 6393 let Inst{6} = lane{0}; 6394} 6395def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$V), 6396 (ins DPR:$src1, GPR:$R, VectorIndex32:$lane), 6397 IIC_VMOVISL, "vmov", "32", "$V$lane, $R", 6398 [(set DPR:$V, (insertelt (v2i32 DPR:$src1), 6399 GPR:$R, imm:$lane))]>, 6400 Requires<[HasVFP2]> { 6401 let Inst{21} = lane{0}; 6402 // This instruction is equivalent as 6403 // $V = INSERT_SUBREG $src1, $R, translateImmToSubIdx($imm) 6404 let isInsertSubreg = 1; 6405} 6406} 6407 6408let Predicates = [HasNEON] in { 6409def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane), 6410 (v16i8 (INSERT_SUBREG QPR:$src1, 6411 (v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1, 6412 (DSubReg_i8_reg imm:$lane))), 6413 GPR:$src2, (SubReg_i8_lane imm:$lane))), 6414 (DSubReg_i8_reg imm:$lane)))>; 6415def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane), 6416 (v8i16 (INSERT_SUBREG QPR:$src1, 6417 (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1, 6418 (DSubReg_i16_reg imm:$lane))), 6419 GPR:$src2, (SubReg_i16_lane imm:$lane))), 6420 (DSubReg_i16_reg imm:$lane)))>; 6421def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane), 6422 (v4i32 (INSERT_SUBREG QPR:$src1, 6423 (v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1, 6424 (DSubReg_i32_reg imm:$lane))), 6425 GPR:$src2, (SubReg_i32_lane imm:$lane))), 6426 (DSubReg_i32_reg imm:$lane)))>; 6427 6428def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)), 6429 (INSERT_SUBREG (v2f32 (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2)), 6430 SPR:$src2, (SSubReg_f32_reg imm:$src3))>; 6431def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)), 6432 (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2)), 6433 SPR:$src2, (SSubReg_f32_reg imm:$src3))>; 6434 6435def : Pat<(insertelt (v4f16 DPR:$src1), HPR:$src2, imm:$lane), 6436 (v4f16 (VSETLNi16 DPR:$src1, (VMOVRH $src2), imm:$lane))>; 6437def : Pat<(insertelt (v8f16 QPR:$src1), HPR:$src2, imm:$lane), 6438 (v8f16 (INSERT_SUBREG QPR:$src1, 6439 (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1, 6440 (DSubReg_i16_reg imm:$lane))), 6441 (VMOVRH $src2), (SubReg_i16_lane imm:$lane))), 6442 (DSubReg_i16_reg imm:$lane)))>; 6443 6444//def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), 6445// (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; 6446def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), 6447 (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; 6448 6449def : Pat<(v2f32 (scalar_to_vector SPR:$src)), 6450 (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>; 6451def : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))), 6452 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, dsub_0)>; 6453def : Pat<(v4f32 (scalar_to_vector SPR:$src)), 6454 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>; 6455 6456def : Pat<(v8i8 (scalar_to_vector GPR:$src)), 6457 (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; 6458def : Pat<(v4i16 (scalar_to_vector GPR:$src)), 6459 (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; 6460def : Pat<(v2i32 (scalar_to_vector GPR:$src)), 6461 (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0))>; 6462 6463def : Pat<(v16i8 (scalar_to_vector GPR:$src)), 6464 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)), 6465 (VSETLNi8 (v8i8 (IMPLICIT_DEF)), GPR:$src, (i32 0)), 6466 dsub_0)>; 6467def : Pat<(v8i16 (scalar_to_vector GPR:$src)), 6468 (INSERT_SUBREG (v8i16 (IMPLICIT_DEF)), 6469 (VSETLNi16 (v4i16 (IMPLICIT_DEF)), GPR:$src, (i32 0)), 6470 dsub_0)>; 6471def : Pat<(v4i32 (scalar_to_vector GPR:$src)), 6472 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 6473 (VSETLNi32 (v2i32 (IMPLICIT_DEF)), GPR:$src, (i32 0)), 6474 dsub_0)>; 6475} 6476 6477// VDUP : Vector Duplicate (from ARM core register to all elements) 6478 6479class VDUPD<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty> 6480 : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$V), (ins GPR:$R), 6481 IIC_VMOVIS, "vdup", Dt, "$V, $R", 6482 [(set DPR:$V, (Ty (ARMvdup (i32 GPR:$R))))]>; 6483class VDUPQ<bits<8> opcod1, bits<2> opcod3, string Dt, ValueType Ty> 6484 : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$V), (ins GPR:$R), 6485 IIC_VMOVIS, "vdup", Dt, "$V, $R", 6486 [(set QPR:$V, (Ty (ARMvdup (i32 GPR:$R))))]>; 6487 6488def VDUP8d : VDUPD<0b11101100, 0b00, "8", v8i8>; 6489def VDUP16d : VDUPD<0b11101000, 0b01, "16", v4i16>; 6490def VDUP32d : VDUPD<0b11101000, 0b00, "32", v2i32>, 6491 Requires<[HasNEON, HasFastVDUP32]>; 6492def VDUP8q : VDUPQ<0b11101110, 0b00, "8", v16i8>; 6493def VDUP16q : VDUPQ<0b11101010, 0b01, "16", v8i16>; 6494def VDUP32q : VDUPQ<0b11101010, 0b00, "32", v4i32>; 6495 6496// ARMvdup patterns for uarchs with fast VDUP.32. 6497def : Pat<(v2f32 (ARMvdup (f32 (bitconvert GPR:$R)))), (VDUP32d GPR:$R)>, 6498 Requires<[HasNEON,HasFastVDUP32]>; 6499def : Pat<(v4f32 (ARMvdup (f32 (bitconvert GPR:$R)))), (VDUP32q GPR:$R)>, 6500 Requires<[HasNEON]>; 6501 6502// ARMvdup patterns for uarchs with slow VDUP.32 - use VMOVDRR instead. 6503def : Pat<(v2i32 (ARMvdup (i32 GPR:$R))), (VMOVDRR GPR:$R, GPR:$R)>, 6504 Requires<[HasNEON,HasSlowVDUP32]>; 6505def : Pat<(v2f32 (ARMvdup (f32 (bitconvert GPR:$R)))), (VMOVDRR GPR:$R, GPR:$R)>, 6506 Requires<[HasNEON,HasSlowVDUP32]>; 6507 6508// VDUP : Vector Duplicate Lane (from scalar to all elements) 6509 6510class VDUPLND<bits<4> op19_16, string OpcodeStr, string Dt, 6511 ValueType Ty, Operand IdxTy> 6512 : NVDupLane<op19_16, 0, (outs DPR:$Vd), (ins DPR:$Vm, IdxTy:$lane), 6513 IIC_VMOVD, OpcodeStr, Dt, "$Vd, $Vm$lane", 6514 [(set DPR:$Vd, (Ty (ARMvduplane (Ty DPR:$Vm), imm:$lane)))]>; 6515 6516class VDUPLNQ<bits<4> op19_16, string OpcodeStr, string Dt, 6517 ValueType ResTy, ValueType OpTy, Operand IdxTy> 6518 : NVDupLane<op19_16, 1, (outs QPR:$Vd), (ins DPR:$Vm, IdxTy:$lane), 6519 IIC_VMOVQ, OpcodeStr, Dt, "$Vd, $Vm$lane", 6520 [(set QPR:$Vd, (ResTy (ARMvduplane (OpTy DPR:$Vm), 6521 VectorIndex32:$lane)))]>; 6522 6523// Inst{19-16} is partially specified depending on the element size. 6524 6525def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> { 6526 bits<3> lane; 6527 let Inst{19-17} = lane{2-0}; 6528} 6529def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> { 6530 bits<2> lane; 6531 let Inst{19-18} = lane{1-0}; 6532} 6533def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> { 6534 bits<1> lane; 6535 let Inst{19} = lane{0}; 6536} 6537def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> { 6538 bits<3> lane; 6539 let Inst{19-17} = lane{2-0}; 6540} 6541def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> { 6542 bits<2> lane; 6543 let Inst{19-18} = lane{1-0}; 6544} 6545def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> { 6546 bits<1> lane; 6547 let Inst{19} = lane{0}; 6548} 6549 6550let Predicates = [HasNEON] in { 6551def : Pat<(v4f16 (ARMvduplane (v4f16 DPR:$Vm), imm:$lane)), 6552 (VDUPLN32d DPR:$Vm, imm:$lane)>; 6553 6554def : Pat<(v2f32 (ARMvduplane (v2f32 DPR:$Vm), imm:$lane)), 6555 (VDUPLN32d DPR:$Vm, imm:$lane)>; 6556 6557def : Pat<(v4f32 (ARMvduplane (v2f32 DPR:$Vm), imm:$lane)), 6558 (VDUPLN32q DPR:$Vm, imm:$lane)>; 6559 6560def : Pat<(v16i8 (ARMvduplane (v16i8 QPR:$src), imm:$lane)), 6561 (v16i8 (VDUPLN8q (v8i8 (EXTRACT_SUBREG QPR:$src, 6562 (DSubReg_i8_reg imm:$lane))), 6563 (SubReg_i8_lane imm:$lane)))>; 6564def : Pat<(v8i16 (ARMvduplane (v8i16 QPR:$src), imm:$lane)), 6565 (v8i16 (VDUPLN16q (v4i16 (EXTRACT_SUBREG QPR:$src, 6566 (DSubReg_i16_reg imm:$lane))), 6567 (SubReg_i16_lane imm:$lane)))>; 6568def : Pat<(v8f16 (ARMvduplane (v8f16 QPR:$src), imm:$lane)), 6569 (v8f16 (VDUPLN16q (v4f16 (EXTRACT_SUBREG QPR:$src, 6570 (DSubReg_i16_reg imm:$lane))), 6571 (SubReg_i16_lane imm:$lane)))>; 6572def : Pat<(v4i32 (ARMvduplane (v4i32 QPR:$src), imm:$lane)), 6573 (v4i32 (VDUPLN32q (v2i32 (EXTRACT_SUBREG QPR:$src, 6574 (DSubReg_i32_reg imm:$lane))), 6575 (SubReg_i32_lane imm:$lane)))>; 6576def : Pat<(v4f32 (ARMvduplane (v4f32 QPR:$src), imm:$lane)), 6577 (v4f32 (VDUPLN32q (v2f32 (EXTRACT_SUBREG QPR:$src, 6578 (DSubReg_i32_reg imm:$lane))), 6579 (SubReg_i32_lane imm:$lane)))>; 6580 6581def : Pat<(v4f16 (ARMvdup HPR:$src)), 6582 (v4f16 (VDUPLN16d (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), 6583 HPR:$src, ssub_0), (i32 0)))>; 6584def : Pat<(v2f32 (ARMvdup (f32 SPR:$src))), 6585 (v2f32 (VDUPLN32d (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), 6586 SPR:$src, ssub_0), (i32 0)))>; 6587def : Pat<(v4f32 (ARMvdup (f32 SPR:$src))), 6588 (v4f32 (VDUPLN32q (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), 6589 SPR:$src, ssub_0), (i32 0)))>; 6590def : Pat<(v8f16 (ARMvdup HPR:$src)), 6591 (v8f16 (VDUPLN16q (INSERT_SUBREG (v4f16 (IMPLICIT_DEF)), 6592 HPR:$src, ssub_0), (i32 0)))>; 6593} 6594 6595// VMOVN : Vector Narrowing Move 6596defm VMOVN : N2VN_HSD<0b11,0b11,0b10,0b00100,0,0, IIC_VMOVN, 6597 "vmovn", "i", trunc>; 6598// VQMOVN : Vector Saturating Narrowing Move 6599defm VQMOVNs : N2VNInt_HSD<0b11,0b11,0b10,0b00101,0,0, IIC_VQUNAiD, 6600 "vqmovn", "s", int_arm_neon_vqmovns>; 6601defm VQMOVNu : N2VNInt_HSD<0b11,0b11,0b10,0b00101,1,0, IIC_VQUNAiD, 6602 "vqmovn", "u", int_arm_neon_vqmovnu>; 6603defm VQMOVNsu : N2VNInt_HSD<0b11,0b11,0b10,0b00100,1,0, IIC_VQUNAiD, 6604 "vqmovun", "s", int_arm_neon_vqmovnsu>; 6605// VMOVL : Vector Lengthening Move 6606defm VMOVLs : N2VL_QHS<0b01,0b10100,0,1, "vmovl", "s", sext>; 6607defm VMOVLu : N2VL_QHS<0b11,0b10100,0,1, "vmovl", "u", zext>; 6608 6609let Predicates = [HasNEON] in { 6610def : Pat<(v8i16 (anyext (v8i8 DPR:$Vm))), (VMOVLuv8i16 DPR:$Vm)>; 6611def : Pat<(v4i32 (anyext (v4i16 DPR:$Vm))), (VMOVLuv4i32 DPR:$Vm)>; 6612def : Pat<(v2i64 (anyext (v2i32 DPR:$Vm))), (VMOVLuv2i64 DPR:$Vm)>; 6613} 6614 6615// Vector Conversions. 6616 6617// VCVT : Vector Convert Between Floating-Point and Integers 6618def VCVTf2sd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32", 6619 v2i32, v2f32, fp_to_sint>; 6620def VCVTf2ud : N2VD<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32", 6621 v2i32, v2f32, fp_to_uint>; 6622def VCVTs2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32", 6623 v2f32, v2i32, sint_to_fp>; 6624def VCVTu2fd : N2VD<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32", 6625 v2f32, v2i32, uint_to_fp>; 6626 6627def VCVTf2sq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01110, 0, "vcvt", "s32.f32", 6628 v4i32, v4f32, fp_to_sint>; 6629def VCVTf2uq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01111, 0, "vcvt", "u32.f32", 6630 v4i32, v4f32, fp_to_uint>; 6631def VCVTs2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01100, 0, "vcvt", "f32.s32", 6632 v4f32, v4i32, sint_to_fp>; 6633def VCVTu2fq : N2VQ<0b11, 0b11, 0b10, 0b11, 0b01101, 0, "vcvt", "f32.u32", 6634 v4f32, v4i32, uint_to_fp>; 6635 6636def VCVTh2sd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01110, 0, "vcvt", "s16.f16", 6637 v4i16, v4f16, fp_to_sint>, 6638 Requires<[HasNEON, HasFullFP16]>; 6639def VCVTh2ud : N2VD<0b11, 0b11, 0b01, 0b11, 0b01111, 0, "vcvt", "u16.f16", 6640 v4i16, v4f16, fp_to_uint>, 6641 Requires<[HasNEON, HasFullFP16]>; 6642def VCVTs2hd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01100, 0, "vcvt", "f16.s16", 6643 v4f16, v4i16, sint_to_fp>, 6644 Requires<[HasNEON, HasFullFP16]>; 6645def VCVTu2hd : N2VD<0b11, 0b11, 0b01, 0b11, 0b01101, 0, "vcvt", "f16.u16", 6646 v4f16, v4i16, uint_to_fp>, 6647 Requires<[HasNEON, HasFullFP16]>; 6648 6649def VCVTh2sq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01110, 0, "vcvt", "s16.f16", 6650 v8i16, v8f16, fp_to_sint>, 6651 Requires<[HasNEON, HasFullFP16]>; 6652def VCVTh2uq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01111, 0, "vcvt", "u16.f16", 6653 v8i16, v8f16, fp_to_uint>, 6654 Requires<[HasNEON, HasFullFP16]>; 6655def VCVTs2hq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01100, 0, "vcvt", "f16.s16", 6656 v8f16, v8i16, sint_to_fp>, 6657 Requires<[HasNEON, HasFullFP16]>; 6658def VCVTu2hq : N2VQ<0b11, 0b11, 0b01, 0b11, 0b01101, 0, "vcvt", "f16.u16", 6659 v8f16, v8i16, uint_to_fp>, 6660 Requires<[HasNEON, HasFullFP16]>; 6661 6662// VCVT{A, N, P, M} 6663multiclass VCVT_FPI<string op, bits<3> op10_8, SDPatternOperator IntS, 6664 SDPatternOperator IntU> { 6665 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in { 6666 def SDf : N2VDIntnp<0b10, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op), 6667 "s32.f32", v2i32, v2f32, IntS>, Requires<[HasV8, HasNEON]>; 6668 def SQf : N2VQIntnp<0b10, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op), 6669 "s32.f32", v4i32, v4f32, IntS>, Requires<[HasV8, HasNEON]>; 6670 def UDf : N2VDIntnp<0b10, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op), 6671 "u32.f32", v2i32, v2f32, IntU>, Requires<[HasV8, HasNEON]>; 6672 def UQf : N2VQIntnp<0b10, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op), 6673 "u32.f32", v4i32, v4f32, IntU>, Requires<[HasV8, HasNEON]>; 6674 def SDh : N2VDIntnp<0b01, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op), 6675 "s16.f16", v4i16, v4f16, IntS>, 6676 Requires<[HasV8, HasNEON, HasFullFP16]>; 6677 def SQh : N2VQIntnp<0b01, 0b11, op10_8, 0, NoItinerary, !strconcat("vcvt", op), 6678 "s16.f16", v8i16, v8f16, IntS>, 6679 Requires<[HasV8, HasNEON, HasFullFP16]>; 6680 def UDh : N2VDIntnp<0b01, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op), 6681 "u16.f16", v4i16, v4f16, IntU>, 6682 Requires<[HasV8, HasNEON, HasFullFP16]>; 6683 def UQh : N2VQIntnp<0b01, 0b11, op10_8, 1, NoItinerary, !strconcat("vcvt", op), 6684 "u16.f16", v8i16, v8f16, IntU>, 6685 Requires<[HasV8, HasNEON, HasFullFP16]>; 6686 } 6687} 6688 6689defm VCVTAN : VCVT_FPI<"a", 0b000, int_arm_neon_vcvtas, int_arm_neon_vcvtau>; 6690defm VCVTNN : VCVT_FPI<"n", 0b001, int_arm_neon_vcvtns, int_arm_neon_vcvtnu>; 6691defm VCVTPN : VCVT_FPI<"p", 0b010, int_arm_neon_vcvtps, int_arm_neon_vcvtpu>; 6692defm VCVTMN : VCVT_FPI<"m", 0b011, int_arm_neon_vcvtms, int_arm_neon_vcvtmu>; 6693 6694// VCVT : Vector Convert Between Floating-Point and Fixed-Point. 6695let DecoderMethod = "DecodeVCVTD" in { 6696def VCVTf2xsd : N2VCvtD<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32", 6697 v2i32, v2f32, int_arm_neon_vcvtfp2fxs>; 6698def VCVTf2xud : N2VCvtD<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32", 6699 v2i32, v2f32, int_arm_neon_vcvtfp2fxu>; 6700def VCVTxs2fd : N2VCvtD<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32", 6701 v2f32, v2i32, int_arm_neon_vcvtfxs2fp>; 6702def VCVTxu2fd : N2VCvtD<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32", 6703 v2f32, v2i32, int_arm_neon_vcvtfxu2fp>; 6704let Predicates = [HasNEON, HasFullFP16] in { 6705def VCVTh2xsd : N2VCvtD<0, 1, 0b1101, 0, 1, "vcvt", "s16.f16", 6706 v4i16, v4f16, int_arm_neon_vcvtfp2fxs>; 6707def VCVTh2xud : N2VCvtD<1, 1, 0b1101, 0, 1, "vcvt", "u16.f16", 6708 v4i16, v4f16, int_arm_neon_vcvtfp2fxu>; 6709def VCVTxs2hd : N2VCvtD<0, 1, 0b1100, 0, 1, "vcvt", "f16.s16", 6710 v4f16, v4i16, int_arm_neon_vcvtfxs2fp>; 6711def VCVTxu2hd : N2VCvtD<1, 1, 0b1100, 0, 1, "vcvt", "f16.u16", 6712 v4f16, v4i16, int_arm_neon_vcvtfxu2fp>; 6713} // Predicates = [HasNEON, HasFullFP16] 6714} 6715 6716let DecoderMethod = "DecodeVCVTQ" in { 6717def VCVTf2xsq : N2VCvtQ<0, 1, 0b1111, 0, 1, "vcvt", "s32.f32", 6718 v4i32, v4f32, int_arm_neon_vcvtfp2fxs>; 6719def VCVTf2xuq : N2VCvtQ<1, 1, 0b1111, 0, 1, "vcvt", "u32.f32", 6720 v4i32, v4f32, int_arm_neon_vcvtfp2fxu>; 6721def VCVTxs2fq : N2VCvtQ<0, 1, 0b1110, 0, 1, "vcvt", "f32.s32", 6722 v4f32, v4i32, int_arm_neon_vcvtfxs2fp>; 6723def VCVTxu2fq : N2VCvtQ<1, 1, 0b1110, 0, 1, "vcvt", "f32.u32", 6724 v4f32, v4i32, int_arm_neon_vcvtfxu2fp>; 6725let Predicates = [HasNEON, HasFullFP16] in { 6726def VCVTh2xsq : N2VCvtQ<0, 1, 0b1101, 0, 1, "vcvt", "s16.f16", 6727 v8i16, v8f16, int_arm_neon_vcvtfp2fxs>; 6728def VCVTh2xuq : N2VCvtQ<1, 1, 0b1101, 0, 1, "vcvt", "u16.f16", 6729 v8i16, v8f16, int_arm_neon_vcvtfp2fxu>; 6730def VCVTxs2hq : N2VCvtQ<0, 1, 0b1100, 0, 1, "vcvt", "f16.s16", 6731 v8f16, v8i16, int_arm_neon_vcvtfxs2fp>; 6732def VCVTxu2hq : N2VCvtQ<1, 1, 0b1100, 0, 1, "vcvt", "f16.u16", 6733 v8f16, v8i16, int_arm_neon_vcvtfxu2fp>; 6734} // Predicates = [HasNEON, HasFullFP16] 6735} 6736 6737def : NEONInstAlias<"vcvt${p}.s32.f32 $Dd, $Dm, #0", 6738 (VCVTf2sd DPR:$Dd, DPR:$Dm, pred:$p)>; 6739def : NEONInstAlias<"vcvt${p}.u32.f32 $Dd, $Dm, #0", 6740 (VCVTf2ud DPR:$Dd, DPR:$Dm, pred:$p)>; 6741def : NEONInstAlias<"vcvt${p}.f32.s32 $Dd, $Dm, #0", 6742 (VCVTs2fd DPR:$Dd, DPR:$Dm, pred:$p)>; 6743def : NEONInstAlias<"vcvt${p}.f32.u32 $Dd, $Dm, #0", 6744 (VCVTu2fd DPR:$Dd, DPR:$Dm, pred:$p)>; 6745 6746def : NEONInstAlias<"vcvt${p}.s32.f32 $Qd, $Qm, #0", 6747 (VCVTf2sq QPR:$Qd, QPR:$Qm, pred:$p)>; 6748def : NEONInstAlias<"vcvt${p}.u32.f32 $Qd, $Qm, #0", 6749 (VCVTf2uq QPR:$Qd, QPR:$Qm, pred:$p)>; 6750def : NEONInstAlias<"vcvt${p}.f32.s32 $Qd, $Qm, #0", 6751 (VCVTs2fq QPR:$Qd, QPR:$Qm, pred:$p)>; 6752def : NEONInstAlias<"vcvt${p}.f32.u32 $Qd, $Qm, #0", 6753 (VCVTu2fq QPR:$Qd, QPR:$Qm, pred:$p)>; 6754 6755def : NEONInstAlias<"vcvt${p}.s16.f16 $Dd, $Dm, #0", 6756 (VCVTh2sd DPR:$Dd, DPR:$Dm, pred:$p)>; 6757def : NEONInstAlias<"vcvt${p}.u16.f16 $Dd, $Dm, #0", 6758 (VCVTh2ud DPR:$Dd, DPR:$Dm, pred:$p)>; 6759def : NEONInstAlias<"vcvt${p}.f16.s16 $Dd, $Dm, #0", 6760 (VCVTs2hd DPR:$Dd, DPR:$Dm, pred:$p)>; 6761def : NEONInstAlias<"vcvt${p}.f16.u16 $Dd, $Dm, #0", 6762 (VCVTu2hd DPR:$Dd, DPR:$Dm, pred:$p)>; 6763 6764def : NEONInstAlias<"vcvt${p}.s16.f16 $Qd, $Qm, #0", 6765 (VCVTh2sq QPR:$Qd, QPR:$Qm, pred:$p)>; 6766def : NEONInstAlias<"vcvt${p}.u16.f16 $Qd, $Qm, #0", 6767 (VCVTh2uq QPR:$Qd, QPR:$Qm, pred:$p)>; 6768def : NEONInstAlias<"vcvt${p}.f16.s16 $Qd, $Qm, #0", 6769 (VCVTs2hq QPR:$Qd, QPR:$Qm, pred:$p)>; 6770def : NEONInstAlias<"vcvt${p}.f16.u16 $Qd, $Qm, #0", 6771 (VCVTu2hq QPR:$Qd, QPR:$Qm, pred:$p)>; 6772 6773 6774// VCVT : Vector Convert Between Half-Precision and Single-Precision. 6775def VCVTf2h : N2VNInt<0b11, 0b11, 0b01, 0b10, 0b01100, 0, 0, 6776 IIC_VUNAQ, "vcvt", "f16.f32", 6777 v4i16, v4f32, int_arm_neon_vcvtfp2hf>, 6778 Requires<[HasNEON, HasFP16]>; 6779def VCVTh2f : N2VLInt<0b11, 0b11, 0b01, 0b10, 0b01110, 0, 0, 6780 IIC_VUNAQ, "vcvt", "f32.f16", 6781 v4f32, v4i16, int_arm_neon_vcvthf2fp>, 6782 Requires<[HasNEON, HasFP16]>; 6783 6784// Vector Reverse. 6785 6786// VREV64 : Vector Reverse elements within 64-bit doublewords 6787 6788class VREV64D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 6789 : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$Vd), 6790 (ins DPR:$Vm), IIC_VMOVD, 6791 OpcodeStr, Dt, "$Vd, $Vm", "", 6792 [(set DPR:$Vd, (Ty (ARMvrev64 (Ty DPR:$Vm))))]>; 6793class VREV64Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 6794 : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$Vd), 6795 (ins QPR:$Vm), IIC_VMOVQ, 6796 OpcodeStr, Dt, "$Vd, $Vm", "", 6797 [(set QPR:$Vd, (Ty (ARMvrev64 (Ty QPR:$Vm))))]>; 6798 6799def VREV64d8 : VREV64D<0b00, "vrev64", "8", v8i8>; 6800def VREV64d16 : VREV64D<0b01, "vrev64", "16", v4i16>; 6801def VREV64d32 : VREV64D<0b10, "vrev64", "32", v2i32>; 6802let Predicates = [HasNEON] in { 6803def : Pat<(v2f32 (ARMvrev64 (v2f32 DPR:$Vm))), (VREV64d32 DPR:$Vm)>; 6804} 6805 6806def VREV64q8 : VREV64Q<0b00, "vrev64", "8", v16i8>; 6807def VREV64q16 : VREV64Q<0b01, "vrev64", "16", v8i16>; 6808def VREV64q32 : VREV64Q<0b10, "vrev64", "32", v4i32>; 6809 6810let Predicates = [HasNEON] in { 6811 def : Pat<(v4f32 (ARMvrev64 (v4f32 QPR:$Vm))), 6812 (VREV64q32 QPR:$Vm)>; 6813 def : Pat<(v8f16 (ARMvrev64 (v8f16 QPR:$Vm))), 6814 (VREV64q16 QPR:$Vm)>; 6815 def : Pat<(v4f16 (ARMvrev64 (v4f16 DPR:$Vm))), 6816 (VREV64d16 DPR:$Vm)>; 6817} 6818 6819// VREV32 : Vector Reverse elements within 32-bit words 6820 6821class VREV32D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 6822 : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$Vd), 6823 (ins DPR:$Vm), IIC_VMOVD, 6824 OpcodeStr, Dt, "$Vd, $Vm", "", 6825 [(set DPR:$Vd, (Ty (ARMvrev32 (Ty DPR:$Vm))))]>; 6826class VREV32Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 6827 : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$Vd), 6828 (ins QPR:$Vm), IIC_VMOVQ, 6829 OpcodeStr, Dt, "$Vd, $Vm", "", 6830 [(set QPR:$Vd, (Ty (ARMvrev32 (Ty QPR:$Vm))))]>; 6831 6832def VREV32d8 : VREV32D<0b00, "vrev32", "8", v8i8>; 6833def VREV32d16 : VREV32D<0b01, "vrev32", "16", v4i16>; 6834 6835def VREV32q8 : VREV32Q<0b00, "vrev32", "8", v16i8>; 6836def VREV32q16 : VREV32Q<0b01, "vrev32", "16", v8i16>; 6837 6838let Predicates = [HasNEON] in { 6839 def : Pat<(v8f16 (ARMvrev32 (v8f16 QPR:$Vm))), 6840 (VREV32q16 QPR:$Vm)>; 6841 def : Pat<(v4f16 (ARMvrev32 (v4f16 DPR:$Vm))), 6842 (VREV32d16 DPR:$Vm)>; 6843} 6844 6845// VREV16 : Vector Reverse elements within 16-bit halfwords 6846 6847class VREV16D<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 6848 : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$Vd), 6849 (ins DPR:$Vm), IIC_VMOVD, 6850 OpcodeStr, Dt, "$Vd, $Vm", "", 6851 [(set DPR:$Vd, (Ty (ARMvrev16 (Ty DPR:$Vm))))]>; 6852class VREV16Q<bits<2> op19_18, string OpcodeStr, string Dt, ValueType Ty> 6853 : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$Vd), 6854 (ins QPR:$Vm), IIC_VMOVQ, 6855 OpcodeStr, Dt, "$Vd, $Vm", "", 6856 [(set QPR:$Vd, (Ty (ARMvrev16 (Ty QPR:$Vm))))]>; 6857 6858def VREV16d8 : VREV16D<0b00, "vrev16", "8", v8i8>; 6859def VREV16q8 : VREV16Q<0b00, "vrev16", "8", v16i8>; 6860 6861// Other Vector Shuffles. 6862 6863// Aligned extractions: really just dropping registers 6864 6865class AlignedVEXTq<ValueType DestTy, ValueType SrcTy, SDNodeXForm LaneCVT> 6866 : Pat<(DestTy (vector_extract_subvec (SrcTy QPR:$src), (i32 imm:$start))), 6867 (EXTRACT_SUBREG (SrcTy QPR:$src), (LaneCVT imm:$start))>, 6868 Requires<[HasNEON]>; 6869 6870def : AlignedVEXTq<v8i8, v16i8, DSubReg_i8_reg>; 6871 6872def : AlignedVEXTq<v4i16, v8i16, DSubReg_i16_reg>; 6873 6874def : AlignedVEXTq<v2i32, v4i32, DSubReg_i32_reg>; 6875 6876def : AlignedVEXTq<v1i64, v2i64, DSubReg_f64_reg>; 6877 6878def : AlignedVEXTq<v2f32, v4f32, DSubReg_i32_reg>; 6879 6880def : AlignedVEXTq<v4f16, v8f16, DSubReg_i16_reg>; // v8f16 -> v4f16 6881 6882// VEXT : Vector Extract 6883 6884 6885// All of these have a two-operand InstAlias. 6886let TwoOperandAliasConstraint = "$Vn = $Vd" in { 6887class VEXTd<string OpcodeStr, string Dt, ValueType Ty, Operand immTy> 6888 : N3V<0,1,0b11,{?,?,?,?},0,0, (outs DPR:$Vd), 6889 (ins DPR:$Vn, DPR:$Vm, immTy:$index), NVExtFrm, 6890 IIC_VEXTD, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "", 6891 [(set DPR:$Vd, (Ty (NEONvext (Ty DPR:$Vn), 6892 (Ty DPR:$Vm), imm:$index)))]> { 6893 bits<3> index; 6894 let Inst{11} = 0b0; 6895 let Inst{10-8} = index{2-0}; 6896} 6897 6898class VEXTq<string OpcodeStr, string Dt, ValueType Ty, Operand immTy> 6899 : N3V<0,1,0b11,{?,?,?,?},1,0, (outs QPR:$Vd), 6900 (ins QPR:$Vn, QPR:$Vm, imm0_15:$index), NVExtFrm, 6901 IIC_VEXTQ, OpcodeStr, Dt, "$Vd, $Vn, $Vm, $index", "", 6902 [(set QPR:$Vd, (Ty (NEONvext (Ty QPR:$Vn), 6903 (Ty QPR:$Vm), imm:$index)))]> { 6904 bits<4> index; 6905 let Inst{11-8} = index{3-0}; 6906} 6907} 6908 6909def VEXTd8 : VEXTd<"vext", "8", v8i8, imm0_7> { 6910 let Inst{10-8} = index{2-0}; 6911} 6912def VEXTd16 : VEXTd<"vext", "16", v4i16, imm0_3> { 6913 let Inst{10-9} = index{1-0}; 6914 let Inst{8} = 0b0; 6915} 6916let Predicates = [HasNEON] in { 6917def : Pat<(v4f16 (NEONvext (v4f16 DPR:$Vn), (v4f16 DPR:$Vm), (i32 imm:$index))), 6918 (VEXTd16 DPR:$Vn, DPR:$Vm, imm:$index)>; 6919} 6920 6921def VEXTd32 : VEXTd<"vext", "32", v2i32, imm0_1> { 6922 let Inst{10} = index{0}; 6923 let Inst{9-8} = 0b00; 6924} 6925let Predicates = [HasNEON] in { 6926def : Pat<(v2f32 (NEONvext (v2f32 DPR:$Vn), (v2f32 DPR:$Vm), (i32 imm:$index))), 6927 (VEXTd32 DPR:$Vn, DPR:$Vm, imm:$index)>; 6928} 6929 6930def VEXTq8 : VEXTq<"vext", "8", v16i8, imm0_15> { 6931 let Inst{11-8} = index{3-0}; 6932} 6933def VEXTq16 : VEXTq<"vext", "16", v8i16, imm0_7> { 6934 let Inst{11-9} = index{2-0}; 6935 let Inst{8} = 0b0; 6936} 6937let Predicates = [HasNEON] in { 6938def : Pat<(v8f16 (NEONvext (v8f16 QPR:$Vn), (v8f16 QPR:$Vm), (i32 imm:$index))), 6939 (VEXTq16 QPR:$Vn, QPR:$Vm, imm:$index)>; 6940} 6941 6942def VEXTq32 : VEXTq<"vext", "32", v4i32, imm0_3> { 6943 let Inst{11-10} = index{1-0}; 6944 let Inst{9-8} = 0b00; 6945} 6946def VEXTq64 : VEXTq<"vext", "64", v2i64, imm0_1> { 6947 let Inst{11} = index{0}; 6948 let Inst{10-8} = 0b000; 6949} 6950let Predicates = [HasNEON] in { 6951def : Pat<(v4f32 (NEONvext (v4f32 QPR:$Vn), (v4f32 QPR:$Vm), (i32 imm:$index))), 6952 (VEXTq32 QPR:$Vn, QPR:$Vm, imm:$index)>; 6953} 6954 6955// VTRN : Vector Transpose 6956 6957def VTRNd8 : N2VDShuffle<0b00, 0b00001, "vtrn", "8">; 6958def VTRNd16 : N2VDShuffle<0b01, 0b00001, "vtrn", "16">; 6959def VTRNd32 : N2VDShuffle<0b10, 0b00001, "vtrn", "32">; 6960 6961def VTRNq8 : N2VQShuffle<0b00, 0b00001, IIC_VPERMQ, "vtrn", "8">; 6962def VTRNq16 : N2VQShuffle<0b01, 0b00001, IIC_VPERMQ, "vtrn", "16">; 6963def VTRNq32 : N2VQShuffle<0b10, 0b00001, IIC_VPERMQ, "vtrn", "32">; 6964 6965// VUZP : Vector Unzip (Deinterleave) 6966 6967def VUZPd8 : N2VDShuffle<0b00, 0b00010, "vuzp", "8">; 6968def VUZPd16 : N2VDShuffle<0b01, 0b00010, "vuzp", "16">; 6969// vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 6970def : NEONInstAlias<"vuzp${p}.32 $Dd, $Dm", 6971 (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>; 6972 6973def VUZPq8 : N2VQShuffle<0b00, 0b00010, IIC_VPERMQ3, "vuzp", "8">; 6974def VUZPq16 : N2VQShuffle<0b01, 0b00010, IIC_VPERMQ3, "vuzp", "16">; 6975def VUZPq32 : N2VQShuffle<0b10, 0b00010, IIC_VPERMQ3, "vuzp", "32">; 6976 6977// VZIP : Vector Zip (Interleave) 6978 6979def VZIPd8 : N2VDShuffle<0b00, 0b00011, "vzip", "8">; 6980def VZIPd16 : N2VDShuffle<0b01, 0b00011, "vzip", "16">; 6981// vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 6982def : NEONInstAlias<"vzip${p}.32 $Dd, $Dm", 6983 (VTRNd32 DPR:$Dd, DPR:$Dm, pred:$p)>; 6984 6985def VZIPq8 : N2VQShuffle<0b00, 0b00011, IIC_VPERMQ3, "vzip", "8">; 6986def VZIPq16 : N2VQShuffle<0b01, 0b00011, IIC_VPERMQ3, "vzip", "16">; 6987def VZIPq32 : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">; 6988 6989// Vector Table Lookup and Table Extension. 6990 6991// VTBL : Vector Table Lookup 6992let DecoderMethod = "DecodeTBLInstruction" in { 6993def VTBL1 6994 : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd), 6995 (ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1, 6996 "vtbl", "8", "$Vd, $Vn, $Vm", "", 6997 [(set DPR:$Vd, (v8i8 (NEONvtbl1 VecListOneD:$Vn, DPR:$Vm)))]>; 6998 6999let hasExtraSrcRegAllocReq = 1 in { 7000def VTBL2 7001 : N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd), 7002 (ins VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB2, 7003 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>; 7004def VTBL3 7005 : N3V<1,1,0b11,0b1010,0,0, (outs DPR:$Vd), 7006 (ins VecListThreeD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB3, 7007 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>; 7008def VTBL4 7009 : N3V<1,1,0b11,0b1011,0,0, (outs DPR:$Vd), 7010 (ins VecListFourD:$Vn, DPR:$Vm), 7011 NVTBLFrm, IIC_VTB4, 7012 "vtbl", "8", "$Vd, $Vn, $Vm", "", []>; 7013} // hasExtraSrcRegAllocReq = 1 7014 7015def VTBL3Pseudo 7016 : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB3, "", []>; 7017def VTBL4Pseudo 7018 : PseudoNeonI<(outs DPR:$dst), (ins QQPR:$tbl, DPR:$src), IIC_VTB4, "", []>; 7019 7020// VTBX : Vector Table Extension 7021def VTBX1 7022 : N3V<1,1,0b11,0b1000,1,0, (outs DPR:$Vd), 7023 (ins DPR:$orig, VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX1, 7024 "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", 7025 [(set DPR:$Vd, (v8i8 (int_arm_neon_vtbx1 7026 DPR:$orig, VecListOneD:$Vn, DPR:$Vm)))]>; 7027let hasExtraSrcRegAllocReq = 1 in { 7028def VTBX2 7029 : N3V<1,1,0b11,0b1001,1,0, (outs DPR:$Vd), 7030 (ins DPR:$orig, VecListDPair:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX2, 7031 "vtbx", "8", "$Vd, $Vn, $Vm", "$orig = $Vd", []>; 7032def VTBX3 7033 : N3V<1,1,0b11,0b1010,1,0, (outs DPR:$Vd), 7034 (ins DPR:$orig, VecListThreeD:$Vn, DPR:$Vm), 7035 NVTBLFrm, IIC_VTBX3, 7036 "vtbx", "8", "$Vd, $Vn, $Vm", 7037 "$orig = $Vd", []>; 7038def VTBX4 7039 : N3V<1,1,0b11,0b1011,1,0, (outs DPR:$Vd), 7040 (ins DPR:$orig, VecListFourD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTBX4, 7041 "vtbx", "8", "$Vd, $Vn, $Vm", 7042 "$orig = $Vd", []>; 7043} // hasExtraSrcRegAllocReq = 1 7044 7045def VTBX3Pseudo 7046 : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src), 7047 IIC_VTBX3, "$orig = $dst", []>; 7048def VTBX4Pseudo 7049 : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src), 7050 IIC_VTBX4, "$orig = $dst", []>; 7051} // DecoderMethod = "DecodeTBLInstruction" 7052 7053let Predicates = [HasNEON] in { 7054def : Pat<(v8i8 (NEONvtbl2 v8i8:$Vn0, v8i8:$Vn1, v8i8:$Vm)), 7055 (v8i8 (VTBL2 (REG_SEQUENCE DPair, v8i8:$Vn0, dsub_0, 7056 v8i8:$Vn1, dsub_1), 7057 v8i8:$Vm))>; 7058def : Pat<(v8i8 (int_arm_neon_vtbx2 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1, 7059 v8i8:$Vm)), 7060 (v8i8 (VTBX2 v8i8:$orig, 7061 (REG_SEQUENCE DPair, v8i8:$Vn0, dsub_0, 7062 v8i8:$Vn1, dsub_1), 7063 v8i8:$Vm))>; 7064 7065def : Pat<(v8i8 (int_arm_neon_vtbl3 v8i8:$Vn0, v8i8:$Vn1, 7066 v8i8:$Vn2, v8i8:$Vm)), 7067 (v8i8 (VTBL3Pseudo (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0, 7068 v8i8:$Vn1, dsub_1, 7069 v8i8:$Vn2, dsub_2, 7070 (v8i8 (IMPLICIT_DEF)), dsub_3), 7071 v8i8:$Vm))>; 7072def : Pat<(v8i8 (int_arm_neon_vtbx3 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1, 7073 v8i8:$Vn2, v8i8:$Vm)), 7074 (v8i8 (VTBX3Pseudo v8i8:$orig, 7075 (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0, 7076 v8i8:$Vn1, dsub_1, 7077 v8i8:$Vn2, dsub_2, 7078 (v8i8 (IMPLICIT_DEF)), dsub_3), 7079 v8i8:$Vm))>; 7080 7081def : Pat<(v8i8 (int_arm_neon_vtbl4 v8i8:$Vn0, v8i8:$Vn1, 7082 v8i8:$Vn2, v8i8:$Vn3, v8i8:$Vm)), 7083 (v8i8 (VTBL4Pseudo (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0, 7084 v8i8:$Vn1, dsub_1, 7085 v8i8:$Vn2, dsub_2, 7086 v8i8:$Vn3, dsub_3), 7087 v8i8:$Vm))>; 7088def : Pat<(v8i8 (int_arm_neon_vtbx4 v8i8:$orig, v8i8:$Vn0, v8i8:$Vn1, 7089 v8i8:$Vn2, v8i8:$Vn3, v8i8:$Vm)), 7090 (v8i8 (VTBX4Pseudo v8i8:$orig, 7091 (REG_SEQUENCE QQPR, v8i8:$Vn0, dsub_0, 7092 v8i8:$Vn1, dsub_1, 7093 v8i8:$Vn2, dsub_2, 7094 v8i8:$Vn3, dsub_3), 7095 v8i8:$Vm))>; 7096} 7097 7098// VRINT : Vector Rounding 7099multiclass VRINT_FPI<string op, bits<3> op9_7, SDPatternOperator Int> { 7100 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in { 7101 def Df : N2VDIntnp<0b10, 0b10, 0b100, 0, NoItinerary, 7102 !strconcat("vrint", op), "f32", 7103 v2f32, v2f32, Int>, Requires<[HasV8, HasNEON]> { 7104 let Inst{9-7} = op9_7; 7105 } 7106 def Qf : N2VQIntnp<0b10, 0b10, 0b100, 0, NoItinerary, 7107 !strconcat("vrint", op), "f32", 7108 v4f32, v4f32, Int>, Requires<[HasV8, HasNEON]> { 7109 let Inst{9-7} = op9_7; 7110 } 7111 def Dh : N2VDIntnp<0b01, 0b10, 0b100, 0, NoItinerary, 7112 !strconcat("vrint", op), "f16", 7113 v4f16, v4f16, Int>, 7114 Requires<[HasV8, HasNEON, HasFullFP16]> { 7115 let Inst{9-7} = op9_7; 7116 } 7117 def Qh : N2VQIntnp<0b01, 0b10, 0b100, 0, NoItinerary, 7118 !strconcat("vrint", op), "f16", 7119 v8f16, v8f16, Int>, 7120 Requires<[HasV8, HasNEON, HasFullFP16]> { 7121 let Inst{9-7} = op9_7; 7122 } 7123 } 7124 7125 def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Dd, $Dm"), 7126 (!cast<Instruction>(NAME#"Df") DPR:$Dd, DPR:$Dm)>; 7127 def : NEONInstAlias<!strconcat("vrint", op, ".f32.f32\t$Qd, $Qm"), 7128 (!cast<Instruction>(NAME#"Qf") QPR:$Qd, QPR:$Qm)>; 7129 let Predicates = [HasNEON, HasFullFP16] in { 7130 def : NEONInstAlias<!strconcat("vrint", op, ".f16.f16\t$Dd, $Dm"), 7131 (!cast<Instruction>(NAME#"Dh") DPR:$Dd, DPR:$Dm)>; 7132 def : NEONInstAlias<!strconcat("vrint", op, ".f16.f16\t$Qd, $Qm"), 7133 (!cast<Instruction>(NAME#"Qh") QPR:$Qd, QPR:$Qm)>; 7134 } 7135} 7136 7137defm VRINTNN : VRINT_FPI<"n", 0b000, int_arm_neon_vrintn>; 7138defm VRINTXN : VRINT_FPI<"x", 0b001, int_arm_neon_vrintx>; 7139defm VRINTAN : VRINT_FPI<"a", 0b010, int_arm_neon_vrinta>; 7140defm VRINTZN : VRINT_FPI<"z", 0b011, int_arm_neon_vrintz>; 7141defm VRINTMN : VRINT_FPI<"m", 0b101, int_arm_neon_vrintm>; 7142defm VRINTPN : VRINT_FPI<"p", 0b111, int_arm_neon_vrintp>; 7143 7144// Cryptography instructions 7145let PostEncoderMethod = "NEONThumb2DataIPostEncoder", 7146 DecoderNamespace = "v8Crypto", hasSideEffects = 0 in { 7147 class AES<string op, bit op7, bit op6, SDPatternOperator Int> 7148 : N2VQIntXnp<0b00, 0b00, 0b011, op6, op7, NoItinerary, 7149 !strconcat("aes", op), "8", v16i8, v16i8, Int>, 7150 Requires<[HasV8, HasCrypto]>; 7151 class AES2Op<string op, bit op7, bit op6, SDPatternOperator Int> 7152 : N2VQIntX2np<0b00, 0b00, 0b011, op6, op7, NoItinerary, 7153 !strconcat("aes", op), "8", v16i8, v16i8, Int>, 7154 Requires<[HasV8, HasCrypto]>; 7155 class N2SHA<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 7156 SDPatternOperator Int> 7157 : N2VQIntXnp<0b10, op17_16, op10_8, op6, op7, NoItinerary, 7158 !strconcat("sha", op), "32", v4i32, v4i32, Int>, 7159 Requires<[HasV8, HasCrypto]>; 7160 class N2SHA2Op<string op, bits<2> op17_16, bits<3> op10_8, bit op7, bit op6, 7161 SDPatternOperator Int> 7162 : N2VQIntX2np<0b10, op17_16, op10_8, op6, op7, NoItinerary, 7163 !strconcat("sha", op), "32", v4i32, v4i32, Int>, 7164 Requires<[HasV8, HasCrypto]>; 7165 class N3SHA3Op<string op, bits<5> op27_23, bits<2> op21_20, SDPatternOperator Int> 7166 : N3VQInt3np<op27_23, op21_20, 0b1100, 1, 0, N3RegFrm, NoItinerary, 7167 !strconcat("sha", op), "32", v4i32, v4i32, Int, 0>, 7168 Requires<[HasV8, HasCrypto]>; 7169} 7170 7171def AESD : AES2Op<"d", 0, 1, int_arm_neon_aesd>; 7172def AESE : AES2Op<"e", 0, 0, int_arm_neon_aese>; 7173def AESIMC : AES<"imc", 1, 1, int_arm_neon_aesimc>; 7174def AESMC : AES<"mc", 1, 0, int_arm_neon_aesmc>; 7175 7176def SHA1H : N2SHA<"1h", 0b01, 0b010, 1, 1, null_frag>; 7177def SHA1SU1 : N2SHA2Op<"1su1", 0b10, 0b011, 1, 0, int_arm_neon_sha1su1>; 7178def SHA256SU0 : N2SHA2Op<"256su0", 0b10, 0b011, 1, 1, int_arm_neon_sha256su0>; 7179def SHA1C : N3SHA3Op<"1c", 0b00100, 0b00, null_frag>; 7180def SHA1M : N3SHA3Op<"1m", 0b00100, 0b10, null_frag>; 7181def SHA1P : N3SHA3Op<"1p", 0b00100, 0b01, null_frag>; 7182def SHA1SU0 : N3SHA3Op<"1su0", 0b00100, 0b11, int_arm_neon_sha1su0>; 7183def SHA256H : N3SHA3Op<"256h", 0b00110, 0b00, int_arm_neon_sha256h>; 7184def SHA256H2 : N3SHA3Op<"256h2", 0b00110, 0b01, int_arm_neon_sha256h2>; 7185def SHA256SU1 : N3SHA3Op<"256su1", 0b00110, 0b10, int_arm_neon_sha256su1>; 7186 7187let Predicates = [HasNEON] in { 7188def : Pat<(i32 (int_arm_neon_sha1h i32:$Rn)), 7189 (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG 7190 (SHA1H (SUBREG_TO_REG (i64 0), 7191 (f32 (COPY_TO_REGCLASS i32:$Rn, SPR)), 7192 ssub_0)), 7193 ssub_0)), GPR)>; 7194 7195def : Pat<(v4i32 (int_arm_neon_sha1c v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)), 7196 (SHA1C v4i32:$hash_abcd, 7197 (SUBREG_TO_REG (i64 0), 7198 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)), 7199 ssub_0), 7200 v4i32:$wk)>; 7201 7202def : Pat<(v4i32 (int_arm_neon_sha1m v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)), 7203 (SHA1M v4i32:$hash_abcd, 7204 (SUBREG_TO_REG (i64 0), 7205 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)), 7206 ssub_0), 7207 v4i32:$wk)>; 7208 7209def : Pat<(v4i32 (int_arm_neon_sha1p v4i32:$hash_abcd, i32:$hash_e, v4i32:$wk)), 7210 (SHA1P v4i32:$hash_abcd, 7211 (SUBREG_TO_REG (i64 0), 7212 (f32 (COPY_TO_REGCLASS i32:$hash_e, SPR)), 7213 ssub_0), 7214 v4i32:$wk)>; 7215} 7216 7217//===----------------------------------------------------------------------===// 7218// NEON instructions for single-precision FP math 7219//===----------------------------------------------------------------------===// 7220 7221class N2VSPat<SDNode OpNode, NeonI Inst> 7222 : NEONFPPat<(f32 (OpNode SPR:$a)), 7223 (EXTRACT_SUBREG 7224 (v2f32 (COPY_TO_REGCLASS (Inst 7225 (INSERT_SUBREG 7226 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 7227 SPR:$a, ssub_0)), DPR_VFP2)), ssub_0)>; 7228 7229class N3VSPat<SDNode OpNode, NeonI Inst> 7230 : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), 7231 (EXTRACT_SUBREG 7232 (v2f32 (COPY_TO_REGCLASS (Inst 7233 (INSERT_SUBREG 7234 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 7235 SPR:$a, ssub_0), 7236 (INSERT_SUBREG 7237 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 7238 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; 7239 7240class N3VSPatFP16<SDNode OpNode, NeonI Inst> 7241 : NEONFPPat<(f16 (OpNode HPR:$a, HPR:$b)), 7242 (EXTRACT_SUBREG 7243 (v4f16 (COPY_TO_REGCLASS (Inst 7244 (INSERT_SUBREG 7245 (v4f16 (COPY_TO_REGCLASS (v4f16 (IMPLICIT_DEF)), DPR_VFP2)), 7246 HPR:$a, ssub_0), 7247 (INSERT_SUBREG 7248 (v4f16 (COPY_TO_REGCLASS (v4f16 (IMPLICIT_DEF)), DPR_VFP2)), 7249 HPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; 7250 7251class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst> 7252 : NEONFPPat<(f32 (OpNode SPR:$acc, (f32 (MulNode SPR:$a, SPR:$b)))), 7253 (EXTRACT_SUBREG 7254 (v2f32 (COPY_TO_REGCLASS (Inst 7255 (INSERT_SUBREG 7256 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 7257 SPR:$acc, ssub_0), 7258 (INSERT_SUBREG 7259 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 7260 SPR:$a, ssub_0), 7261 (INSERT_SUBREG 7262 (v2f32 (COPY_TO_REGCLASS (v2f32 (IMPLICIT_DEF)), DPR_VFP2)), 7263 SPR:$b, ssub_0)), DPR_VFP2)), ssub_0)>; 7264 7265class NVCVTIFPat<SDNode OpNode, NeonI Inst> 7266 : NEONFPPat<(f32 (OpNode GPR:$a)), 7267 (f32 (EXTRACT_SUBREG 7268 (v2f32 (Inst 7269 (INSERT_SUBREG 7270 (v2f32 (IMPLICIT_DEF)), 7271 (i32 (COPY_TO_REGCLASS GPR:$a, SPR)), ssub_0))), 7272 ssub_0))>; 7273class NVCVTFIPat<SDNode OpNode, NeonI Inst> 7274 : NEONFPPat<(i32 (OpNode SPR:$a)), 7275 (i32 (EXTRACT_SUBREG 7276 (v2f32 (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), 7277 SPR:$a, ssub_0))), 7278 ssub_0))>; 7279 7280def : N3VSPat<fadd, VADDfd>; 7281def : N3VSPat<fsub, VSUBfd>; 7282def : N3VSPat<fmul, VMULfd>; 7283def : N3VSMulOpPat<fmul, fadd, VMLAfd>, 7284 Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; 7285def : N3VSMulOpPat<fmul, fsub, VMLSfd>, 7286 Requires<[HasNEON, UseNEONForFP, UseFPVMLx]>; 7287def : N3VSMulOpPat<fmul, fadd, VFMAfd>, 7288 Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>; 7289def : N3VSMulOpPat<fmul, fsub, VFMSfd>, 7290 Requires<[HasVFP4, UseNEONForFP, UseFusedMAC]>; 7291def : N2VSPat<fabs, VABSfd>; 7292def : N2VSPat<fneg, VNEGfd>; 7293def : N3VSPatFP16<fmaximum, VMAXhd>, Requires<[HasFullFP16]>; 7294def : N3VSPatFP16<fminimum, VMINhd>, Requires<[HasFullFP16]>; 7295def : N3VSPat<fmaximum, VMAXfd>, Requires<[HasNEON]>; 7296def : N3VSPat<fminimum, VMINfd>, Requires<[HasNEON]>; 7297def : NVCVTFIPat<fp_to_sint, VCVTf2sd>; 7298def : NVCVTFIPat<fp_to_uint, VCVTf2ud>; 7299def : NVCVTIFPat<sint_to_fp, VCVTs2fd>; 7300def : NVCVTIFPat<uint_to_fp, VCVTu2fd>; 7301 7302// NEON doesn't have any f64 conversions, so provide patterns to make 7303// sure the VFP conversions match when extracting from a vector. 7304def : VFPPat<(f64 (sint_to_fp (extractelt (v2i32 DPR:$src), imm:$lane))), 7305 (VSITOD (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>; 7306def : VFPPat<(f64 (sint_to_fp (extractelt (v4i32 QPR:$src), imm:$lane))), 7307 (VSITOD (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane)))>; 7308def : VFPPat<(f64 (uint_to_fp (extractelt (v2i32 DPR:$src), imm:$lane))), 7309 (VUITOD (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>; 7310def : VFPPat<(f64 (uint_to_fp (extractelt (v4i32 QPR:$src), imm:$lane))), 7311 (VUITOD (EXTRACT_SUBREG QPR:$src, (SSubReg_f32_reg imm:$lane)))>; 7312 7313 7314// Prefer VMOVDRR for i32 -> f32 bitcasts, it can write all DPR registers. 7315def : Pat<(f32 (bitconvert GPR:$a)), 7316 (EXTRACT_SUBREG (VMOVDRR GPR:$a, GPR:$a), ssub_0)>, 7317 Requires<[HasNEON, DontUseVMOVSR]>; 7318def : Pat<(arm_vmovsr GPR:$a), 7319 (EXTRACT_SUBREG (VMOVDRR GPR:$a, GPR:$a), ssub_0)>, 7320 Requires<[HasNEON, DontUseVMOVSR]>; 7321 7322//===----------------------------------------------------------------------===// 7323// Non-Instruction Patterns or Endiness - Revert Patterns 7324//===----------------------------------------------------------------------===// 7325 7326// bit_convert 7327// 64 bit conversions 7328let Predicates = [HasNEON] in { 7329def : Pat<(f64 (bitconvert (v1i64 DPR:$src))), (f64 DPR:$src)>; 7330def : Pat<(v1i64 (bitconvert (f64 DPR:$src))), (v1i64 DPR:$src)>; 7331 7332def : Pat<(v2f32 (bitconvert (v2i32 DPR:$src))), (v2f32 DPR:$src)>; 7333def : Pat<(v2i32 (bitconvert (v2f32 DPR:$src))), (v2i32 DPR:$src)>; 7334 7335def : Pat<(v4i16 (bitconvert (v4f16 DPR:$src))), (v4i16 DPR:$src)>; 7336def : Pat<(v4f16 (bitconvert (v4i16 DPR:$src))), (v4f16 DPR:$src)>; 7337 7338// 128 bit conversions 7339def : Pat<(v2f64 (bitconvert (v2i64 QPR:$src))), (v2f64 QPR:$src)>; 7340def : Pat<(v2i64 (bitconvert (v2f64 QPR:$src))), (v2i64 QPR:$src)>; 7341 7342def : Pat<(v4i32 (bitconvert (v4f32 QPR:$src))), (v4i32 QPR:$src)>; 7343def : Pat<(v4f32 (bitconvert (v4i32 QPR:$src))), (v4f32 QPR:$src)>; 7344 7345def : Pat<(v8i16 (bitconvert (v8f16 QPR:$src))), (v8i16 QPR:$src)>; 7346def : Pat<(v8f16 (bitconvert (v8i16 QPR:$src))), (v8f16 QPR:$src)>; 7347} 7348 7349let Predicates = [IsLE,HasNEON] in { 7350 // 64 bit conversions 7351 def : Pat<(f64 (bitconvert (v2f32 DPR:$src))), (f64 DPR:$src)>; 7352 def : Pat<(f64 (bitconvert (v2i32 DPR:$src))), (f64 DPR:$src)>; 7353 def : Pat<(f64 (bitconvert (v4f16 DPR:$src))), (f64 DPR:$src)>; 7354 def : Pat<(f64 (bitconvert (v4i16 DPR:$src))), (f64 DPR:$src)>; 7355 def : Pat<(f64 (bitconvert (v8i8 DPR:$src))), (f64 DPR:$src)>; 7356 7357 def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (v1i64 DPR:$src)>; 7358 def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (v1i64 DPR:$src)>; 7359 def : Pat<(v1i64 (bitconvert (v4f16 DPR:$src))), (v1i64 DPR:$src)>; 7360 def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (v1i64 DPR:$src)>; 7361 def : Pat<(v1i64 (bitconvert (v8i8 DPR:$src))), (v1i64 DPR:$src)>; 7362 7363 def : Pat<(v2f32 (bitconvert (f64 DPR:$src))), (v2f32 DPR:$src)>; 7364 def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (v2f32 DPR:$src)>; 7365 def : Pat<(v2f32 (bitconvert (v4f16 DPR:$src))), (v2f32 DPR:$src)>; 7366 def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (v2f32 DPR:$src)>; 7367 def : Pat<(v2f32 (bitconvert (v8i8 DPR:$src))), (v2f32 DPR:$src)>; 7368 7369 def : Pat<(v2i32 (bitconvert (f64 DPR:$src))), (v2i32 DPR:$src)>; 7370 def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (v2i32 DPR:$src)>; 7371 def : Pat<(v2i32 (bitconvert (v4f16 DPR:$src))), (v2i32 DPR:$src)>; 7372 def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (v2i32 DPR:$src)>; 7373 def : Pat<(v2i32 (bitconvert (v8i8 DPR:$src))), (v2i32 DPR:$src)>; 7374 7375 def : Pat<(v4f16 (bitconvert (f64 DPR:$src))), (v4f16 DPR:$src)>; 7376 def : Pat<(v4f16 (bitconvert (v1i64 DPR:$src))), (v4f16 DPR:$src)>; 7377 def : Pat<(v4f16 (bitconvert (v2f32 DPR:$src))), (v4f16 DPR:$src)>; 7378 def : Pat<(v4f16 (bitconvert (v2i32 DPR:$src))), (v4f16 DPR:$src)>; 7379 def : Pat<(v4f16 (bitconvert (v8i8 DPR:$src))), (v4f16 DPR:$src)>; 7380 7381 def : Pat<(v4i16 (bitconvert (f64 DPR:$src))), (v4i16 DPR:$src)>; 7382 def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (v4i16 DPR:$src)>; 7383 def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (v4i16 DPR:$src)>; 7384 def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (v4i16 DPR:$src)>; 7385 def : Pat<(v4i16 (bitconvert (v8i8 DPR:$src))), (v4i16 DPR:$src)>; 7386 7387 def : Pat<(v8i8 (bitconvert (f64 DPR:$src))), (v8i8 DPR:$src)>; 7388 def : Pat<(v8i8 (bitconvert (v1i64 DPR:$src))), (v8i8 DPR:$src)>; 7389 def : Pat<(v8i8 (bitconvert (v2f32 DPR:$src))), (v8i8 DPR:$src)>; 7390 def : Pat<(v8i8 (bitconvert (v2i32 DPR:$src))), (v8i8 DPR:$src)>; 7391 def : Pat<(v8i8 (bitconvert (v4f16 DPR:$src))), (v8i8 DPR:$src)>; 7392 def : Pat<(v8i8 (bitconvert (v4i16 DPR:$src))), (v8i8 DPR:$src)>; 7393 7394 // 128 bit conversions 7395 def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (v2f64 QPR:$src)>; 7396 def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (v2f64 QPR:$src)>; 7397 def : Pat<(v2f64 (bitconvert (v8f16 QPR:$src))), (v2f64 QPR:$src)>; 7398 def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (v2f64 QPR:$src)>; 7399 def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (v2f64 QPR:$src)>; 7400 7401 def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (v2i64 QPR:$src)>; 7402 def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (v2i64 QPR:$src)>; 7403 def : Pat<(v2i64 (bitconvert (v8f16 QPR:$src))), (v2i64 QPR:$src)>; 7404 def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (v2i64 QPR:$src)>; 7405 def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (v2i64 QPR:$src)>; 7406 7407 def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (v4f32 QPR:$src)>; 7408 def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (v4f32 QPR:$src)>; 7409 def : Pat<(v4f32 (bitconvert (v8f16 QPR:$src))), (v4f32 QPR:$src)>; 7410 def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (v4f32 QPR:$src)>; 7411 def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (v4f32 QPR:$src)>; 7412 7413 def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (v4i32 QPR:$src)>; 7414 def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (v4i32 QPR:$src)>; 7415 def : Pat<(v4i32 (bitconvert (v8f16 QPR:$src))), (v4i32 QPR:$src)>; 7416 def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (v4i32 QPR:$src)>; 7417 def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (v4i32 QPR:$src)>; 7418 7419 def : Pat<(v8f16 (bitconvert (v2f64 QPR:$src))), (v8f16 QPR:$src)>; 7420 def : Pat<(v8f16 (bitconvert (v2i64 QPR:$src))), (v8f16 QPR:$src)>; 7421 def : Pat<(v8f16 (bitconvert (v4f32 QPR:$src))), (v8f16 QPR:$src)>; 7422 def : Pat<(v8f16 (bitconvert (v4i32 QPR:$src))), (v8f16 QPR:$src)>; 7423 def : Pat<(v8f16 (bitconvert (v16i8 QPR:$src))), (v8f16 QPR:$src)>; 7424 7425 def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (v8i16 QPR:$src)>; 7426 def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (v8i16 QPR:$src)>; 7427 def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (v8i16 QPR:$src)>; 7428 def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (v8i16 QPR:$src)>; 7429 def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (v8i16 QPR:$src)>; 7430 7431 def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (v16i8 QPR:$src)>; 7432 def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (v16i8 QPR:$src)>; 7433 def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (v16i8 QPR:$src)>; 7434 def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (v16i8 QPR:$src)>; 7435 def : Pat<(v16i8 (bitconvert (v8f16 QPR:$src))), (v16i8 QPR:$src)>; 7436 def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (v16i8 QPR:$src)>; 7437} 7438 7439let Predicates = [IsBE,HasNEON] in { 7440 // 64 bit conversions 7441 def : Pat<(f64 (bitconvert (v2f32 DPR:$src))), (VREV64d32 DPR:$src)>; 7442 def : Pat<(f64 (bitconvert (v2i32 DPR:$src))), (VREV64d32 DPR:$src)>; 7443 def : Pat<(f64 (bitconvert (v4f16 DPR:$src))), (VREV64d16 DPR:$src)>; 7444 def : Pat<(f64 (bitconvert (v4i16 DPR:$src))), (VREV64d16 DPR:$src)>; 7445 def : Pat<(f64 (bitconvert (v8i8 DPR:$src))), (VREV64d8 DPR:$src)>; 7446 7447 def : Pat<(v1i64 (bitconvert (v2f32 DPR:$src))), (VREV64d32 DPR:$src)>; 7448 def : Pat<(v1i64 (bitconvert (v2i32 DPR:$src))), (VREV64d32 DPR:$src)>; 7449 def : Pat<(v1i64 (bitconvert (v4f16 DPR:$src))), (VREV64d16 DPR:$src)>; 7450 def : Pat<(v1i64 (bitconvert (v4i16 DPR:$src))), (VREV64d16 DPR:$src)>; 7451 def : Pat<(v1i64 (bitconvert (v8i8 DPR:$src))), (VREV64d8 DPR:$src)>; 7452 7453 def : Pat<(v2f32 (bitconvert (f64 DPR:$src))), (VREV64d32 DPR:$src)>; 7454 def : Pat<(v2f32 (bitconvert (v1i64 DPR:$src))), (VREV64d32 DPR:$src)>; 7455 def : Pat<(v2f32 (bitconvert (v4f16 DPR:$src))), (VREV32d16 DPR:$src)>; 7456 def : Pat<(v2f32 (bitconvert (v4i16 DPR:$src))), (VREV32d16 DPR:$src)>; 7457 def : Pat<(v2f32 (bitconvert (v8i8 DPR:$src))), (VREV32d8 DPR:$src)>; 7458 7459 def : Pat<(v2i32 (bitconvert (f64 DPR:$src))), (VREV64d32 DPR:$src)>; 7460 def : Pat<(v2i32 (bitconvert (v1i64 DPR:$src))), (VREV64d32 DPR:$src)>; 7461 def : Pat<(v2i32 (bitconvert (v4f16 DPR:$src))), (VREV32d16 DPR:$src)>; 7462 def : Pat<(v2i32 (bitconvert (v4i16 DPR:$src))), (VREV32d16 DPR:$src)>; 7463 def : Pat<(v2i32 (bitconvert (v8i8 DPR:$src))), (VREV32d8 DPR:$src)>; 7464 7465 def : Pat<(v4f16 (bitconvert (f64 DPR:$src))), (VREV64d16 DPR:$src)>; 7466 def : Pat<(v4f16 (bitconvert (v1i64 DPR:$src))), (VREV64d16 DPR:$src)>; 7467 def : Pat<(v4f16 (bitconvert (v2f32 DPR:$src))), (VREV32d16 DPR:$src)>; 7468 def : Pat<(v4f16 (bitconvert (v2i32 DPR:$src))), (VREV32d16 DPR:$src)>; 7469 def : Pat<(v4f16 (bitconvert (v8i8 DPR:$src))), (VREV16d8 DPR:$src)>; 7470 7471 def : Pat<(v4i16 (bitconvert (f64 DPR:$src))), (VREV64d16 DPR:$src)>; 7472 def : Pat<(v4i16 (bitconvert (v1i64 DPR:$src))), (VREV64d16 DPR:$src)>; 7473 def : Pat<(v4i16 (bitconvert (v2f32 DPR:$src))), (VREV32d16 DPR:$src)>; 7474 def : Pat<(v4i16 (bitconvert (v2i32 DPR:$src))), (VREV32d16 DPR:$src)>; 7475 def : Pat<(v4i16 (bitconvert (v8i8 DPR:$src))), (VREV16d8 DPR:$src)>; 7476 7477 def : Pat<(v8i8 (bitconvert (f64 DPR:$src))), (VREV64d8 DPR:$src)>; 7478 def : Pat<(v8i8 (bitconvert (v1i64 DPR:$src))), (VREV64d8 DPR:$src)>; 7479 def : Pat<(v8i8 (bitconvert (v2f32 DPR:$src))), (VREV32d8 DPR:$src)>; 7480 def : Pat<(v8i8 (bitconvert (v2i32 DPR:$src))), (VREV32d8 DPR:$src)>; 7481 def : Pat<(v8i8 (bitconvert (v4f16 DPR:$src))), (VREV16d8 DPR:$src)>; 7482 def : Pat<(v8i8 (bitconvert (v4i16 DPR:$src))), (VREV16d8 DPR:$src)>; 7483 7484 // 128 bit conversions 7485 def : Pat<(v2f64 (bitconvert (v4f32 QPR:$src))), (VREV64q32 QPR:$src)>; 7486 def : Pat<(v2f64 (bitconvert (v4i32 QPR:$src))), (VREV64q32 QPR:$src)>; 7487 def : Pat<(v2f64 (bitconvert (v8f16 QPR:$src))), (VREV64q16 QPR:$src)>; 7488 def : Pat<(v2f64 (bitconvert (v8i16 QPR:$src))), (VREV64q16 QPR:$src)>; 7489 def : Pat<(v2f64 (bitconvert (v16i8 QPR:$src))), (VREV64q8 QPR:$src)>; 7490 7491 def : Pat<(v2i64 (bitconvert (v4f32 QPR:$src))), (VREV64q32 QPR:$src)>; 7492 def : Pat<(v2i64 (bitconvert (v4i32 QPR:$src))), (VREV64q32 QPR:$src)>; 7493 def : Pat<(v2i64 (bitconvert (v8f16 QPR:$src))), (VREV64q16 QPR:$src)>; 7494 def : Pat<(v2i64 (bitconvert (v8i16 QPR:$src))), (VREV64q16 QPR:$src)>; 7495 def : Pat<(v2i64 (bitconvert (v16i8 QPR:$src))), (VREV64q8 QPR:$src)>; 7496 7497 def : Pat<(v4f32 (bitconvert (v2f64 QPR:$src))), (VREV64q32 QPR:$src)>; 7498 def : Pat<(v4f32 (bitconvert (v2i64 QPR:$src))), (VREV64q32 QPR:$src)>; 7499 def : Pat<(v4f32 (bitconvert (v8f16 QPR:$src))), (VREV32q16 QPR:$src)>; 7500 def : Pat<(v4f32 (bitconvert (v8i16 QPR:$src))), (VREV32q16 QPR:$src)>; 7501 def : Pat<(v4f32 (bitconvert (v16i8 QPR:$src))), (VREV32q8 QPR:$src)>; 7502 7503 def : Pat<(v4i32 (bitconvert (v2f64 QPR:$src))), (VREV64q32 QPR:$src)>; 7504 def : Pat<(v4i32 (bitconvert (v2i64 QPR:$src))), (VREV64q32 QPR:$src)>; 7505 def : Pat<(v4i32 (bitconvert (v8f16 QPR:$src))), (VREV32q16 QPR:$src)>; 7506 def : Pat<(v4i32 (bitconvert (v8i16 QPR:$src))), (VREV32q16 QPR:$src)>; 7507 def : Pat<(v4i32 (bitconvert (v16i8 QPR:$src))), (VREV32q8 QPR:$src)>; 7508 7509 def : Pat<(v8f16 (bitconvert (v2f64 QPR:$src))), (VREV64q16 QPR:$src)>; 7510 def : Pat<(v8f16 (bitconvert (v2i64 QPR:$src))), (VREV64q16 QPR:$src)>; 7511 def : Pat<(v8f16 (bitconvert (v4f32 QPR:$src))), (VREV32q16 QPR:$src)>; 7512 def : Pat<(v8f16 (bitconvert (v4i32 QPR:$src))), (VREV32q16 QPR:$src)>; 7513 def : Pat<(v8f16 (bitconvert (v16i8 QPR:$src))), (VREV16q8 QPR:$src)>; 7514 7515 def : Pat<(v8i16 (bitconvert (v2f64 QPR:$src))), (VREV64q16 QPR:$src)>; 7516 def : Pat<(v8i16 (bitconvert (v2i64 QPR:$src))), (VREV64q16 QPR:$src)>; 7517 def : Pat<(v8i16 (bitconvert (v4f32 QPR:$src))), (VREV32q16 QPR:$src)>; 7518 def : Pat<(v8i16 (bitconvert (v4i32 QPR:$src))), (VREV32q16 QPR:$src)>; 7519 def : Pat<(v8i16 (bitconvert (v16i8 QPR:$src))), (VREV16q8 QPR:$src)>; 7520 7521 def : Pat<(v16i8 (bitconvert (v2f64 QPR:$src))), (VREV64q8 QPR:$src)>; 7522 def : Pat<(v16i8 (bitconvert (v2i64 QPR:$src))), (VREV64q8 QPR:$src)>; 7523 def : Pat<(v16i8 (bitconvert (v4f32 QPR:$src))), (VREV32q8 QPR:$src)>; 7524 def : Pat<(v16i8 (bitconvert (v4i32 QPR:$src))), (VREV32q8 QPR:$src)>; 7525 def : Pat<(v16i8 (bitconvert (v8f16 QPR:$src))), (VREV16q8 QPR:$src)>; 7526 def : Pat<(v16i8 (bitconvert (v8i16 QPR:$src))), (VREV16q8 QPR:$src)>; 7527} 7528 7529let Predicates = [HasNEON] in { 7530 // Here we match the specific SDNode type 'ARMVectorRegCastImpl' 7531 // rather than the more general 'ARMVectorRegCast' which would also 7532 // match some bitconverts. If we use the latter in cases where the 7533 // input and output types are the same, the bitconvert gets elided 7534 // and we end up generating a nonsense match of nothing. 7535 7536 foreach VT = [ v16i8, v8i16, v8f16, v4i32, v4f32, v2i64, v2f64 ] in 7537 foreach VT2 = [ v16i8, v8i16, v8f16, v4i32, v4f32, v2i64, v2f64 ] in 7538 def : Pat<(VT (ARMVectorRegCastImpl (VT2 QPR:$src))), (VT QPR:$src)>; 7539 7540 foreach VT = [ v8i8, v4i16, v4f16, v2i32, v2f32, v1i64, f64 ] in 7541 foreach VT2 = [ v8i8, v4i16, v4f16, v2i32, v2f32, v1i64, f64 ] in 7542 def : Pat<(VT (ARMVectorRegCastImpl (VT2 DPR:$src))), (VT DPR:$src)>; 7543} 7544 7545// Use VLD1/VST1 + VREV for non-word-aligned v2f64 load/store on Big Endian 7546let Predicates = [IsBE,HasNEON] in { 7547def : Pat<(v2f64 (byte_alignedload addrmode6:$addr)), 7548 (VREV64q8 (VLD1q8 addrmode6:$addr))>; 7549def : Pat<(byte_alignedstore (v2f64 QPR:$value), addrmode6:$addr), 7550 (VST1q8 addrmode6:$addr, (VREV64q8 QPR:$value))>; 7551def : Pat<(v2f64 (hword_alignedload addrmode6:$addr)), 7552 (VREV64q16 (VLD1q16 addrmode6:$addr))>; 7553def : Pat<(hword_alignedstore (v2f64 QPR:$value), addrmode6:$addr), 7554 (VST1q16 addrmode6:$addr, (VREV64q16 QPR:$value))>; 7555} 7556 7557// Fold extracting an element out of a v2i32 into a vfp register. 7558def : Pat<(f32 (bitconvert (i32 (extractelt (v2i32 DPR:$src), imm:$lane)))), 7559 (f32 (EXTRACT_SUBREG DPR:$src, (SSubReg_f32_reg imm:$lane)))>, 7560 Requires<[HasNEON]>; 7561 7562// Vector lengthening move with load, matching extending loads. 7563 7564// extload, zextload and sextload for a standard lengthening load. Example: 7565// Lengthen_Single<"8", "i16", "8"> = 7566// Pat<(v8i16 (extloadvi8 addrmode6:$addr)) 7567// (VMOVLuv8i16 (VLD1d8 addrmode6:$addr, 7568// (f64 (IMPLICIT_DEF)), (i32 0)))>; 7569multiclass Lengthen_Single<string DestLanes, string DestTy, string SrcTy> { 7570 let AddedComplexity = 10 in { 7571 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7572 (!cast<PatFrag>("extloadvi" # SrcTy) addrmode6:$addr)), 7573 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy) 7574 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>, 7575 Requires<[HasNEON]>; 7576 7577 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7578 (!cast<PatFrag>("zextloadvi" # SrcTy) addrmode6:$addr)), 7579 (!cast<Instruction>("VMOVLuv" # DestLanes # DestTy) 7580 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>, 7581 Requires<[HasNEON]>; 7582 7583 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7584 (!cast<PatFrag>("sextloadvi" # SrcTy) addrmode6:$addr)), 7585 (!cast<Instruction>("VMOVLsv" # DestLanes # DestTy) 7586 (!cast<Instruction>("VLD1d" # SrcTy) addrmode6:$addr))>, 7587 Requires<[HasNEON]>; 7588 } 7589} 7590 7591// extload, zextload and sextload for a lengthening load which only uses 7592// half the lanes available. Example: 7593// Lengthen_HalfSingle<"4", "i16", "8", "i16", "i8"> = 7594// Pat<(v4i16 (extloadvi8 addrmode6oneL32:$addr)), 7595// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr, 7596// (f64 (IMPLICIT_DEF)), (i32 0))), 7597// dsub_0)>; 7598multiclass Lengthen_HalfSingle<string DestLanes, string DestTy, string SrcTy, 7599 string InsnLanes, string InsnTy> { 7600 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7601 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)), 7602 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy) 7603 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7604 dsub_0)>, 7605 Requires<[HasNEON]>; 7606 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7607 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)), 7608 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy) 7609 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7610 dsub_0)>, 7611 Requires<[HasNEON]>; 7612 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7613 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)), 7614 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy) 7615 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7616 dsub_0)>, 7617 Requires<[HasNEON]>; 7618} 7619 7620// The following class definition is basically a copy of the 7621// Lengthen_HalfSingle definition above, however with an additional parameter 7622// "RevLanes" to select the correct VREV32dXX instruction. This is to convert 7623// data loaded by VLD1LN into proper vector format in big endian mode. 7624multiclass Lengthen_HalfSingle_Big_Endian<string DestLanes, string DestTy, string SrcTy, 7625 string InsnLanes, string InsnTy, string RevLanes> { 7626 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7627 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)), 7628 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy) 7629 (!cast<Instruction>("VREV32d" # RevLanes) 7630 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7631 dsub_0)>, 7632 Requires<[HasNEON]>; 7633 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7634 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)), 7635 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # InsnLanes # InsnTy) 7636 (!cast<Instruction>("VREV32d" # RevLanes) 7637 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7638 dsub_0)>, 7639 Requires<[HasNEON]>; 7640 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7641 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)), 7642 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # InsnLanes # InsnTy) 7643 (!cast<Instruction>("VREV32d" # RevLanes) 7644 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7645 dsub_0)>, 7646 Requires<[HasNEON]>; 7647} 7648 7649// extload, zextload and sextload for a lengthening load followed by another 7650// lengthening load, to quadruple the initial length. 7651// 7652// Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32"> = 7653// Pat<(v4i32 (extloadvi8 addrmode6oneL32:$addr)) 7654// (EXTRACT_SUBREG (VMOVLuv4i32 7655// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd32 addrmode6oneL32:$addr, 7656// (f64 (IMPLICIT_DEF)), 7657// (i32 0))), 7658// dsub_0)), 7659// dsub_0)>; 7660multiclass Lengthen_Double<string DestLanes, string DestTy, string SrcTy, 7661 string Insn1Lanes, string Insn1Ty, string Insn2Lanes, 7662 string Insn2Ty> { 7663 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7664 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)), 7665 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7666 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7667 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7668 dsub_0))>, 7669 Requires<[HasNEON]>; 7670 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7671 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)), 7672 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7673 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7674 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7675 dsub_0))>, 7676 Requires<[HasNEON]>; 7677 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7678 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)), 7679 (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) 7680 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) 7681 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7682 dsub_0))>, 7683 Requires<[HasNEON]>; 7684} 7685 7686// The following class definition is basically a copy of the 7687// Lengthen_Double definition above, however with an additional parameter 7688// "RevLanes" to select the correct VREV32dXX instruction. This is to convert 7689// data loaded by VLD1LN into proper vector format in big endian mode. 7690multiclass Lengthen_Double_Big_Endian<string DestLanes, string DestTy, string SrcTy, 7691 string Insn1Lanes, string Insn1Ty, string Insn2Lanes, 7692 string Insn2Ty, string RevLanes> { 7693 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7694 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6oneL32:$addr)), 7695 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7696 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7697 (!cast<Instruction>("VREV32d" # RevLanes) 7698 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7699 dsub_0))>, 7700 Requires<[HasNEON]>; 7701 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7702 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6oneL32:$addr)), 7703 (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7704 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7705 (!cast<Instruction>("VREV32d" # RevLanes) 7706 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7707 dsub_0))>, 7708 Requires<[HasNEON]>; 7709 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7710 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6oneL32:$addr)), 7711 (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) 7712 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) 7713 (!cast<Instruction>("VREV32d" # RevLanes) 7714 (VLD1LNd32 addrmode6oneL32:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7715 dsub_0))>, 7716 Requires<[HasNEON]>; 7717} 7718 7719// extload, zextload and sextload for a lengthening load followed by another 7720// lengthening load, to quadruple the initial length, but which ends up only 7721// requiring half the available lanes (a 64-bit outcome instead of a 128-bit). 7722// 7723// Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32"> = 7724// Pat<(v2i32 (extloadvi8 addrmode6:$addr)) 7725// (EXTRACT_SUBREG (VMOVLuv4i32 7726// (EXTRACT_SUBREG (VMOVLuv8i16 (VLD1LNd16 addrmode6:$addr, 7727// (f64 (IMPLICIT_DEF)), (i32 0))), 7728// dsub_0)), 7729// dsub_0)>; 7730multiclass Lengthen_HalfDouble<string DestLanes, string DestTy, string SrcTy, 7731 string Insn1Lanes, string Insn1Ty, string Insn2Lanes, 7732 string Insn2Ty> { 7733 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7734 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)), 7735 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7736 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7737 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7738 dsub_0)), 7739 dsub_0)>, 7740 Requires<[HasNEON]>; 7741 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7742 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)), 7743 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7744 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7745 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7746 dsub_0)), 7747 dsub_0)>, 7748 Requires<[HasNEON]>; 7749 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7750 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)), 7751 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) 7752 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) 7753 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0))), 7754 dsub_0)), 7755 dsub_0)>, 7756 Requires<[HasNEON]>; 7757} 7758 7759// The following class definition is basically a copy of the 7760// Lengthen_HalfDouble definition above, however with an additional VREV16d8 7761// instruction to convert data loaded by VLD1LN into proper vector format 7762// in big endian mode. 7763multiclass Lengthen_HalfDouble_Big_Endian<string DestLanes, string DestTy, string SrcTy, 7764 string Insn1Lanes, string Insn1Ty, string Insn2Lanes, 7765 string Insn2Ty> { 7766 def _Any : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7767 (!cast<PatFrag>("extloadv" # SrcTy) addrmode6:$addr)), 7768 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7769 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7770 (!cast<Instruction>("VREV16d8") 7771 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7772 dsub_0)), 7773 dsub_0)>, 7774 Requires<[HasNEON]>; 7775 def _Z : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7776 (!cast<PatFrag>("zextloadv" # SrcTy) addrmode6:$addr)), 7777 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn2Lanes # Insn2Ty) 7778 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLuv" # Insn1Lanes # Insn1Ty) 7779 (!cast<Instruction>("VREV16d8") 7780 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7781 dsub_0)), 7782 dsub_0)>, 7783 Requires<[HasNEON]>; 7784 def _S : Pat<(!cast<ValueType>("v" # DestLanes # DestTy) 7785 (!cast<PatFrag>("sextloadv" # SrcTy) addrmode6:$addr)), 7786 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn2Lanes # Insn2Ty) 7787 (EXTRACT_SUBREG (!cast<Instruction>("VMOVLsv" # Insn1Lanes # Insn1Ty) 7788 (!cast<Instruction>("VREV16d8") 7789 (VLD1LNd16 addrmode6:$addr, (f64 (IMPLICIT_DEF)), (i32 0)))), 7790 dsub_0)), 7791 dsub_0)>, 7792 Requires<[HasNEON]>; 7793} 7794 7795defm : Lengthen_Single<"8", "i16", "8">; // v8i8 -> v8i16 7796defm : Lengthen_Single<"4", "i32", "16">; // v4i16 -> v4i32 7797defm : Lengthen_Single<"2", "i64", "32">; // v2i32 -> v2i64 7798 7799let Predicates = [HasNEON,IsLE] in { 7800 defm : Lengthen_HalfSingle<"4", "i16", "i8", "8", "i16">; // v4i8 -> v4i16 7801 defm : Lengthen_HalfSingle<"2", "i32", "i16", "4", "i32">; // v2i16 -> v2i32 7802 7803 // Double lengthening - v4i8 -> v4i16 -> v4i32 7804 defm : Lengthen_Double<"4", "i32", "i8", "8", "i16", "4", "i32">; 7805 // v2i8 -> v2i16 -> v2i32 7806 defm : Lengthen_HalfDouble<"2", "i32", "i8", "8", "i16", "4", "i32">; 7807 // v2i16 -> v2i32 -> v2i64 7808 defm : Lengthen_Double<"2", "i64", "i16", "4", "i32", "2", "i64">; 7809} 7810 7811let Predicates = [HasNEON,IsBE] in { 7812 defm : Lengthen_HalfSingle_Big_Endian<"4", "i16", "i8", "8", "i16", "8">; // v4i8 -> v4i16 7813 defm : Lengthen_HalfSingle_Big_Endian<"2", "i32", "i16", "4", "i32", "16">; // v2i16 -> v2i32 7814 7815 // Double lengthening - v4i8 -> v4i16 -> v4i32 7816 defm : Lengthen_Double_Big_Endian<"4", "i32", "i8", "8", "i16", "4", "i32", "8">; 7817 // v2i8 -> v2i16 -> v2i32 7818 defm : Lengthen_HalfDouble_Big_Endian<"2", "i32", "i8", "8", "i16", "4", "i32">; 7819 // v2i16 -> v2i32 -> v2i64 7820 defm : Lengthen_Double_Big_Endian<"2", "i64", "i16", "4", "i32", "2", "i64", "16">; 7821} 7822 7823// Triple lengthening - v2i8 -> v2i16 -> v2i32 -> v2i64 7824let Predicates = [HasNEON,IsLE] in { 7825 def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)), 7826 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16 7827 (VLD1LNd16 addrmode6:$addr, 7828 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>; 7829 def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)), 7830 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16 7831 (VLD1LNd16 addrmode6:$addr, 7832 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>; 7833 def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)), 7834 (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i16 7835 (VLD1LNd16 addrmode6:$addr, 7836 (f64 (IMPLICIT_DEF)), (i32 0))), dsub_0)), dsub_0))>; 7837} 7838// The following patterns are basically a copy of the patterns above, 7839// however with an additional VREV16d instruction to convert data 7840// loaded by VLD1LN into proper vector format in big endian mode. 7841let Predicates = [HasNEON,IsBE] in { 7842 def : Pat<(v2i64 (extloadvi8 addrmode6:$addr)), 7843 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16 7844 (!cast<Instruction>("VREV16d8") 7845 (VLD1LNd16 addrmode6:$addr, 7846 (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>; 7847 def : Pat<(v2i64 (zextloadvi8 addrmode6:$addr)), 7848 (VMOVLuv2i64 (EXTRACT_SUBREG (VMOVLuv4i32 (EXTRACT_SUBREG (VMOVLuv8i16 7849 (!cast<Instruction>("VREV16d8") 7850 (VLD1LNd16 addrmode6:$addr, 7851 (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>; 7852 def : Pat<(v2i64 (sextloadvi8 addrmode6:$addr)), 7853 (VMOVLsv2i64 (EXTRACT_SUBREG (VMOVLsv4i32 (EXTRACT_SUBREG (VMOVLsv8i16 7854 (!cast<Instruction>("VREV16d8") 7855 (VLD1LNd16 addrmode6:$addr, 7856 (f64 (IMPLICIT_DEF)), (i32 0)))), dsub_0)), dsub_0))>; 7857} 7858 7859let Predicates = [HasNEON] in { 7860def : Pat<(v2i64 (concat_vectors DPR:$Dn, DPR:$Dm)), 7861 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>; 7862def : Pat<(v4i32 (concat_vectors DPR:$Dn, DPR:$Dm)), 7863 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>; 7864def : Pat<(v8i16 (concat_vectors DPR:$Dn, DPR:$Dm)), 7865 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>; 7866def : Pat<(v16i8 (concat_vectors DPR:$Dn, DPR:$Dm)), 7867 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>; 7868def : Pat<(v4f32 (concat_vectors DPR:$Dn, DPR:$Dm)), 7869 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>; 7870def : Pat<(v8f16 (concat_vectors DPR:$Dn, DPR:$Dm)), 7871 (REG_SEQUENCE QPR, DPR:$Dn, dsub_0, DPR:$Dm, dsub_1)>; 7872} 7873 7874//===----------------------------------------------------------------------===// 7875// Assembler aliases 7876// 7877 7878def : VFP2InstAlias<"fmdhr${p} $Dd, $Rn", 7879 (VSETLNi32 DPR:$Dd, GPR:$Rn, 1, pred:$p)>; 7880def : VFP2InstAlias<"fmdlr${p} $Dd, $Rn", 7881 (VSETLNi32 DPR:$Dd, GPR:$Rn, 0, pred:$p)>; 7882 7883// VAND/VBIC/VEOR/VORR accept but do not require a type suffix. 7884defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm", 7885 (VANDd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 7886defm : NEONDTAnyInstAlias<"vand${p}", "$Vd, $Vn, $Vm", 7887 (VANDq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 7888defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm", 7889 (VBICd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 7890defm : NEONDTAnyInstAlias<"vbic${p}", "$Vd, $Vn, $Vm", 7891 (VBICq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 7892defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm", 7893 (VEORd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 7894defm : NEONDTAnyInstAlias<"veor${p}", "$Vd, $Vn, $Vm", 7895 (VEORq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 7896defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm", 7897 (VORRd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 7898defm : NEONDTAnyInstAlias<"vorr${p}", "$Vd, $Vn, $Vm", 7899 (VORRq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 7900// ... two-operand aliases 7901defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm", 7902 (VANDd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; 7903defm : NEONDTAnyInstAlias<"vand${p}", "$Vdn, $Vm", 7904 (VANDq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; 7905defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm", 7906 (VEORd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; 7907defm : NEONDTAnyInstAlias<"veor${p}", "$Vdn, $Vm", 7908 (VEORq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; 7909defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm", 7910 (VORRd DPR:$Vdn, DPR:$Vdn, DPR:$Vm, pred:$p)>; 7911defm : NEONDTAnyInstAlias<"vorr${p}", "$Vdn, $Vm", 7912 (VORRq QPR:$Vdn, QPR:$Vdn, QPR:$Vm, pred:$p)>; 7913// ... immediates 7914def : NEONInstAlias<"vand${p}.i16 $Vd, $imm", 7915 (VBICiv4i16 DPR:$Vd, nImmSplatNotI16:$imm, pred:$p)>; 7916def : NEONInstAlias<"vand${p}.i32 $Vd, $imm", 7917 (VBICiv2i32 DPR:$Vd, nImmSplatNotI32:$imm, pred:$p)>; 7918def : NEONInstAlias<"vand${p}.i16 $Vd, $imm", 7919 (VBICiv8i16 QPR:$Vd, nImmSplatNotI16:$imm, pred:$p)>; 7920def : NEONInstAlias<"vand${p}.i32 $Vd, $imm", 7921 (VBICiv4i32 QPR:$Vd, nImmSplatNotI32:$imm, pred:$p)>; 7922 7923 7924// VLD1 single-lane pseudo-instructions. These need special handling for 7925// the lane index that an InstAlias can't handle, so we use these instead. 7926def VLD1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr", 7927 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr, 7928 pred:$p)>; 7929def VLD1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr", 7930 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr, 7931 pred:$p)>; 7932def VLD1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr", 7933 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr, 7934 pred:$p)>; 7935 7936def VLD1LNdWB_fixed_Asm_8 : 7937 NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr!", 7938 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr, 7939 pred:$p)>; 7940def VLD1LNdWB_fixed_Asm_16 : 7941 NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr!", 7942 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr, 7943 pred:$p)>; 7944def VLD1LNdWB_fixed_Asm_32 : 7945 NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr!", 7946 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr, 7947 pred:$p)>; 7948def VLD1LNdWB_register_Asm_8 : 7949 NEONDataTypeAsmPseudoInst<"vld1${p}", ".8", "$list, $addr, $Rm", 7950 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr, 7951 rGPR:$Rm, pred:$p)>; 7952def VLD1LNdWB_register_Asm_16 : 7953 NEONDataTypeAsmPseudoInst<"vld1${p}", ".16", "$list, $addr, $Rm", 7954 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr, 7955 rGPR:$Rm, pred:$p)>; 7956def VLD1LNdWB_register_Asm_32 : 7957 NEONDataTypeAsmPseudoInst<"vld1${p}", ".32", "$list, $addr, $Rm", 7958 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr, 7959 rGPR:$Rm, pred:$p)>; 7960 7961 7962// VST1 single-lane pseudo-instructions. These need special handling for 7963// the lane index that an InstAlias can't handle, so we use these instead. 7964def VST1LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr", 7965 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr, 7966 pred:$p)>; 7967def VST1LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr", 7968 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr, 7969 pred:$p)>; 7970def VST1LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr", 7971 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr, 7972 pred:$p)>; 7973 7974def VST1LNdWB_fixed_Asm_8 : 7975 NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr!", 7976 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr, 7977 pred:$p)>; 7978def VST1LNdWB_fixed_Asm_16 : 7979 NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr!", 7980 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr, 7981 pred:$p)>; 7982def VST1LNdWB_fixed_Asm_32 : 7983 NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr!", 7984 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr, 7985 pred:$p)>; 7986def VST1LNdWB_register_Asm_8 : 7987 NEONDataTypeAsmPseudoInst<"vst1${p}", ".8", "$list, $addr, $Rm", 7988 (ins VecListOneDByteIndexed:$list, addrmode6alignNone:$addr, 7989 rGPR:$Rm, pred:$p)>; 7990def VST1LNdWB_register_Asm_16 : 7991 NEONDataTypeAsmPseudoInst<"vst1${p}", ".16", "$list, $addr, $Rm", 7992 (ins VecListOneDHWordIndexed:$list, addrmode6align16:$addr, 7993 rGPR:$Rm, pred:$p)>; 7994def VST1LNdWB_register_Asm_32 : 7995 NEONDataTypeAsmPseudoInst<"vst1${p}", ".32", "$list, $addr, $Rm", 7996 (ins VecListOneDWordIndexed:$list, addrmode6align32:$addr, 7997 rGPR:$Rm, pred:$p)>; 7998 7999// VLD2 single-lane pseudo-instructions. These need special handling for 8000// the lane index that an InstAlias can't handle, so we use these instead. 8001def VLD2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr", 8002 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr, 8003 pred:$p)>; 8004def VLD2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr", 8005 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr, 8006 pred:$p)>; 8007def VLD2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr", 8008 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, pred:$p)>; 8009def VLD2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr", 8010 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr, 8011 pred:$p)>; 8012def VLD2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr", 8013 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr, 8014 pred:$p)>; 8015 8016def VLD2LNdWB_fixed_Asm_8 : 8017 NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr!", 8018 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr, 8019 pred:$p)>; 8020def VLD2LNdWB_fixed_Asm_16 : 8021 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!", 8022 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr, 8023 pred:$p)>; 8024def VLD2LNdWB_fixed_Asm_32 : 8025 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!", 8026 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, 8027 pred:$p)>; 8028def VLD2LNqWB_fixed_Asm_16 : 8029 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr!", 8030 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr, 8031 pred:$p)>; 8032def VLD2LNqWB_fixed_Asm_32 : 8033 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr!", 8034 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr, 8035 pred:$p)>; 8036def VLD2LNdWB_register_Asm_8 : 8037 NEONDataTypeAsmPseudoInst<"vld2${p}", ".8", "$list, $addr, $Rm", 8038 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr, 8039 rGPR:$Rm, pred:$p)>; 8040def VLD2LNdWB_register_Asm_16 : 8041 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm", 8042 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr, 8043 rGPR:$Rm, pred:$p)>; 8044def VLD2LNdWB_register_Asm_32 : 8045 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm", 8046 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, 8047 rGPR:$Rm, pred:$p)>; 8048def VLD2LNqWB_register_Asm_16 : 8049 NEONDataTypeAsmPseudoInst<"vld2${p}", ".16", "$list, $addr, $Rm", 8050 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr, 8051 rGPR:$Rm, pred:$p)>; 8052def VLD2LNqWB_register_Asm_32 : 8053 NEONDataTypeAsmPseudoInst<"vld2${p}", ".32", "$list, $addr, $Rm", 8054 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr, 8055 rGPR:$Rm, pred:$p)>; 8056 8057 8058// VST2 single-lane pseudo-instructions. These need special handling for 8059// the lane index that an InstAlias can't handle, so we use these instead. 8060def VST2LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr", 8061 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr, 8062 pred:$p)>; 8063def VST2LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr", 8064 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr, 8065 pred:$p)>; 8066def VST2LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr", 8067 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, 8068 pred:$p)>; 8069def VST2LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr", 8070 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr, 8071 pred:$p)>; 8072def VST2LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr", 8073 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr, 8074 pred:$p)>; 8075 8076def VST2LNdWB_fixed_Asm_8 : 8077 NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr!", 8078 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr, 8079 pred:$p)>; 8080def VST2LNdWB_fixed_Asm_16 : 8081 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!", 8082 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr, 8083 pred:$p)>; 8084def VST2LNdWB_fixed_Asm_32 : 8085 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!", 8086 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, 8087 pred:$p)>; 8088def VST2LNqWB_fixed_Asm_16 : 8089 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16", "$list, $addr!", 8090 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr, 8091 pred:$p)>; 8092def VST2LNqWB_fixed_Asm_32 : 8093 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr!", 8094 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr, 8095 pred:$p)>; 8096def VST2LNdWB_register_Asm_8 : 8097 NEONDataTypeAsmPseudoInst<"vst2${p}", ".8", "$list, $addr, $Rm", 8098 (ins VecListTwoDByteIndexed:$list, addrmode6align16:$addr, 8099 rGPR:$Rm, pred:$p)>; 8100def VST2LNdWB_register_Asm_16 : 8101 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm", 8102 (ins VecListTwoDHWordIndexed:$list, addrmode6align32:$addr, 8103 rGPR:$Rm, pred:$p)>; 8104def VST2LNdWB_register_Asm_32 : 8105 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm", 8106 (ins VecListTwoDWordIndexed:$list, addrmode6align64:$addr, 8107 rGPR:$Rm, pred:$p)>; 8108def VST2LNqWB_register_Asm_16 : 8109 NEONDataTypeAsmPseudoInst<"vst2${p}", ".16","$list, $addr, $Rm", 8110 (ins VecListTwoQHWordIndexed:$list, addrmode6align32:$addr, 8111 rGPR:$Rm, pred:$p)>; 8112def VST2LNqWB_register_Asm_32 : 8113 NEONDataTypeAsmPseudoInst<"vst2${p}", ".32", "$list, $addr, $Rm", 8114 (ins VecListTwoQWordIndexed:$list, addrmode6align64:$addr, 8115 rGPR:$Rm, pred:$p)>; 8116 8117// VLD3 all-lanes pseudo-instructions. These need special handling for 8118// the lane index that an InstAlias can't handle, so we use these instead. 8119def VLD3DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 8120 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8121 pred:$p)>; 8122def VLD3DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 8123 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8124 pred:$p)>; 8125def VLD3DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 8126 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8127 pred:$p)>; 8128def VLD3DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 8129 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8130 pred:$p)>; 8131def VLD3DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 8132 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8133 pred:$p)>; 8134def VLD3DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 8135 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8136 pred:$p)>; 8137 8138def VLD3DUPdWB_fixed_Asm_8 : 8139 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 8140 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8141 pred:$p)>; 8142def VLD3DUPdWB_fixed_Asm_16 : 8143 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 8144 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8145 pred:$p)>; 8146def VLD3DUPdWB_fixed_Asm_32 : 8147 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 8148 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8149 pred:$p)>; 8150def VLD3DUPqWB_fixed_Asm_8 : 8151 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 8152 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8153 pred:$p)>; 8154def VLD3DUPqWB_fixed_Asm_16 : 8155 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 8156 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8157 pred:$p)>; 8158def VLD3DUPqWB_fixed_Asm_32 : 8159 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 8160 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8161 pred:$p)>; 8162def VLD3DUPdWB_register_Asm_8 : 8163 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 8164 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8165 rGPR:$Rm, pred:$p)>; 8166def VLD3DUPdWB_register_Asm_16 : 8167 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 8168 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8169 rGPR:$Rm, pred:$p)>; 8170def VLD3DUPdWB_register_Asm_32 : 8171 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 8172 (ins VecListThreeDAllLanes:$list, addrmode6dupalignNone:$addr, 8173 rGPR:$Rm, pred:$p)>; 8174def VLD3DUPqWB_register_Asm_8 : 8175 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 8176 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8177 rGPR:$Rm, pred:$p)>; 8178def VLD3DUPqWB_register_Asm_16 : 8179 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 8180 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8181 rGPR:$Rm, pred:$p)>; 8182def VLD3DUPqWB_register_Asm_32 : 8183 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 8184 (ins VecListThreeQAllLanes:$list, addrmode6dupalignNone:$addr, 8185 rGPR:$Rm, pred:$p)>; 8186 8187 8188// VLD3 single-lane pseudo-instructions. These need special handling for 8189// the lane index that an InstAlias can't handle, so we use these instead. 8190def VLD3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 8191 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr, 8192 pred:$p)>; 8193def VLD3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 8194 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr, 8195 pred:$p)>; 8196def VLD3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 8197 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr, 8198 pred:$p)>; 8199def VLD3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 8200 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr, 8201 pred:$p)>; 8202def VLD3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 8203 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr, 8204 pred:$p)>; 8205 8206def VLD3LNdWB_fixed_Asm_8 : 8207 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 8208 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr, 8209 pred:$p)>; 8210def VLD3LNdWB_fixed_Asm_16 : 8211 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 8212 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr, 8213 pred:$p)>; 8214def VLD3LNdWB_fixed_Asm_32 : 8215 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 8216 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr, 8217 pred:$p)>; 8218def VLD3LNqWB_fixed_Asm_16 : 8219 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 8220 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr, 8221 pred:$p)>; 8222def VLD3LNqWB_fixed_Asm_32 : 8223 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 8224 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr, 8225 pred:$p)>; 8226def VLD3LNdWB_register_Asm_8 : 8227 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 8228 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr, 8229 rGPR:$Rm, pred:$p)>; 8230def VLD3LNdWB_register_Asm_16 : 8231 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 8232 (ins VecListThreeDHWordIndexed:$list, 8233 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>; 8234def VLD3LNdWB_register_Asm_32 : 8235 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 8236 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr, 8237 rGPR:$Rm, pred:$p)>; 8238def VLD3LNqWB_register_Asm_16 : 8239 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 8240 (ins VecListThreeQHWordIndexed:$list, 8241 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>; 8242def VLD3LNqWB_register_Asm_32 : 8243 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 8244 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr, 8245 rGPR:$Rm, pred:$p)>; 8246 8247// VLD3 multiple structure pseudo-instructions. These need special handling for 8248// the vector operands that the normal instructions don't yet model. 8249// FIXME: Remove these when the register classes and instructions are updated. 8250def VLD3dAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 8251 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8252def VLD3dAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 8253 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8254def VLD3dAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 8255 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8256def VLD3qAsm_8 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr", 8257 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8258def VLD3qAsm_16 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr", 8259 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8260def VLD3qAsm_32 : NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr", 8261 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8262 8263def VLD3dWB_fixed_Asm_8 : 8264 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 8265 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8266def VLD3dWB_fixed_Asm_16 : 8267 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 8268 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8269def VLD3dWB_fixed_Asm_32 : 8270 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 8271 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8272def VLD3qWB_fixed_Asm_8 : 8273 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr!", 8274 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8275def VLD3qWB_fixed_Asm_16 : 8276 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr!", 8277 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8278def VLD3qWB_fixed_Asm_32 : 8279 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr!", 8280 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8281def VLD3dWB_register_Asm_8 : 8282 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 8283 (ins VecListThreeD:$list, addrmode6align64:$addr, 8284 rGPR:$Rm, pred:$p)>; 8285def VLD3dWB_register_Asm_16 : 8286 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 8287 (ins VecListThreeD:$list, addrmode6align64:$addr, 8288 rGPR:$Rm, pred:$p)>; 8289def VLD3dWB_register_Asm_32 : 8290 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 8291 (ins VecListThreeD:$list, addrmode6align64:$addr, 8292 rGPR:$Rm, pred:$p)>; 8293def VLD3qWB_register_Asm_8 : 8294 NEONDataTypeAsmPseudoInst<"vld3${p}", ".8", "$list, $addr, $Rm", 8295 (ins VecListThreeQ:$list, addrmode6align64:$addr, 8296 rGPR:$Rm, pred:$p)>; 8297def VLD3qWB_register_Asm_16 : 8298 NEONDataTypeAsmPseudoInst<"vld3${p}", ".16", "$list, $addr, $Rm", 8299 (ins VecListThreeQ:$list, addrmode6align64:$addr, 8300 rGPR:$Rm, pred:$p)>; 8301def VLD3qWB_register_Asm_32 : 8302 NEONDataTypeAsmPseudoInst<"vld3${p}", ".32", "$list, $addr, $Rm", 8303 (ins VecListThreeQ:$list, addrmode6align64:$addr, 8304 rGPR:$Rm, pred:$p)>; 8305 8306// VST3 single-lane pseudo-instructions. These need special handling for 8307// the lane index that an InstAlias can't handle, so we use these instead. 8308def VST3LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr", 8309 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr, 8310 pred:$p)>; 8311def VST3LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 8312 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr, 8313 pred:$p)>; 8314def VST3LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 8315 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr, 8316 pred:$p)>; 8317def VST3LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 8318 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr, 8319 pred:$p)>; 8320def VST3LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 8321 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr, 8322 pred:$p)>; 8323 8324def VST3LNdWB_fixed_Asm_8 : 8325 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!", 8326 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr, 8327 pred:$p)>; 8328def VST3LNdWB_fixed_Asm_16 : 8329 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 8330 (ins VecListThreeDHWordIndexed:$list, addrmode6alignNone:$addr, 8331 pred:$p)>; 8332def VST3LNdWB_fixed_Asm_32 : 8333 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 8334 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr, 8335 pred:$p)>; 8336def VST3LNqWB_fixed_Asm_16 : 8337 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 8338 (ins VecListThreeQHWordIndexed:$list, addrmode6alignNone:$addr, 8339 pred:$p)>; 8340def VST3LNqWB_fixed_Asm_32 : 8341 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 8342 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr, 8343 pred:$p)>; 8344def VST3LNdWB_register_Asm_8 : 8345 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm", 8346 (ins VecListThreeDByteIndexed:$list, addrmode6alignNone:$addr, 8347 rGPR:$Rm, pred:$p)>; 8348def VST3LNdWB_register_Asm_16 : 8349 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 8350 (ins VecListThreeDHWordIndexed:$list, 8351 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>; 8352def VST3LNdWB_register_Asm_32 : 8353 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 8354 (ins VecListThreeDWordIndexed:$list, addrmode6alignNone:$addr, 8355 rGPR:$Rm, pred:$p)>; 8356def VST3LNqWB_register_Asm_16 : 8357 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 8358 (ins VecListThreeQHWordIndexed:$list, 8359 addrmode6alignNone:$addr, rGPR:$Rm, pred:$p)>; 8360def VST3LNqWB_register_Asm_32 : 8361 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 8362 (ins VecListThreeQWordIndexed:$list, addrmode6alignNone:$addr, 8363 rGPR:$Rm, pred:$p)>; 8364 8365 8366// VST3 multiple structure pseudo-instructions. These need special handling for 8367// the vector operands that the normal instructions don't yet model. 8368// FIXME: Remove these when the register classes and instructions are updated. 8369def VST3dAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr", 8370 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8371def VST3dAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 8372 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8373def VST3dAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 8374 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8375def VST3qAsm_8 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr", 8376 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8377def VST3qAsm_16 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr", 8378 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8379def VST3qAsm_32 : NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr", 8380 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8381 8382def VST3dWB_fixed_Asm_8 : 8383 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!", 8384 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8385def VST3dWB_fixed_Asm_16 : 8386 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 8387 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8388def VST3dWB_fixed_Asm_32 : 8389 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 8390 (ins VecListThreeD:$list, addrmode6align64:$addr, pred:$p)>; 8391def VST3qWB_fixed_Asm_8 : 8392 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr!", 8393 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8394def VST3qWB_fixed_Asm_16 : 8395 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr!", 8396 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8397def VST3qWB_fixed_Asm_32 : 8398 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr!", 8399 (ins VecListThreeQ:$list, addrmode6align64:$addr, pred:$p)>; 8400def VST3dWB_register_Asm_8 : 8401 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm", 8402 (ins VecListThreeD:$list, addrmode6align64:$addr, 8403 rGPR:$Rm, pred:$p)>; 8404def VST3dWB_register_Asm_16 : 8405 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 8406 (ins VecListThreeD:$list, addrmode6align64:$addr, 8407 rGPR:$Rm, pred:$p)>; 8408def VST3dWB_register_Asm_32 : 8409 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 8410 (ins VecListThreeD:$list, addrmode6align64:$addr, 8411 rGPR:$Rm, pred:$p)>; 8412def VST3qWB_register_Asm_8 : 8413 NEONDataTypeAsmPseudoInst<"vst3${p}", ".8", "$list, $addr, $Rm", 8414 (ins VecListThreeQ:$list, addrmode6align64:$addr, 8415 rGPR:$Rm, pred:$p)>; 8416def VST3qWB_register_Asm_16 : 8417 NEONDataTypeAsmPseudoInst<"vst3${p}", ".16", "$list, $addr, $Rm", 8418 (ins VecListThreeQ:$list, addrmode6align64:$addr, 8419 rGPR:$Rm, pred:$p)>; 8420def VST3qWB_register_Asm_32 : 8421 NEONDataTypeAsmPseudoInst<"vst3${p}", ".32", "$list, $addr, $Rm", 8422 (ins VecListThreeQ:$list, addrmode6align64:$addr, 8423 rGPR:$Rm, pred:$p)>; 8424 8425// VLD4 all-lanes pseudo-instructions. These need special handling for 8426// the lane index that an InstAlias can't handle, so we use these instead. 8427def VLD4DUPdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 8428 (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr, 8429 pred:$p)>; 8430def VLD4DUPdAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 8431 (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr, 8432 pred:$p)>; 8433def VLD4DUPdAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 8434 (ins VecListFourDAllLanes:$list, addrmode6dupalign64or128:$addr, 8435 pred:$p)>; 8436def VLD4DUPqAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 8437 (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr, 8438 pred:$p)>; 8439def VLD4DUPqAsm_16: NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 8440 (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr, 8441 pred:$p)>; 8442def VLD4DUPqAsm_32: NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 8443 (ins VecListFourQAllLanes:$list, addrmode6dupalign64or128:$addr, 8444 pred:$p)>; 8445 8446def VLD4DUPdWB_fixed_Asm_8 : 8447 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 8448 (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr, 8449 pred:$p)>; 8450def VLD4DUPdWB_fixed_Asm_16 : 8451 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 8452 (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr, 8453 pred:$p)>; 8454def VLD4DUPdWB_fixed_Asm_32 : 8455 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 8456 (ins VecListFourDAllLanes:$list, addrmode6dupalign64or128:$addr, 8457 pred:$p)>; 8458def VLD4DUPqWB_fixed_Asm_8 : 8459 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 8460 (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr, 8461 pred:$p)>; 8462def VLD4DUPqWB_fixed_Asm_16 : 8463 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 8464 (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr, 8465 pred:$p)>; 8466def VLD4DUPqWB_fixed_Asm_32 : 8467 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 8468 (ins VecListFourQAllLanes:$list, addrmode6dupalign64or128:$addr, 8469 pred:$p)>; 8470def VLD4DUPdWB_register_Asm_8 : 8471 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 8472 (ins VecListFourDAllLanes:$list, addrmode6dupalign32:$addr, 8473 rGPR:$Rm, pred:$p)>; 8474def VLD4DUPdWB_register_Asm_16 : 8475 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 8476 (ins VecListFourDAllLanes:$list, addrmode6dupalign64:$addr, 8477 rGPR:$Rm, pred:$p)>; 8478def VLD4DUPdWB_register_Asm_32 : 8479 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 8480 (ins VecListFourDAllLanes:$list, 8481 addrmode6dupalign64or128:$addr, rGPR:$Rm, pred:$p)>; 8482def VLD4DUPqWB_register_Asm_8 : 8483 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 8484 (ins VecListFourQAllLanes:$list, addrmode6dupalign32:$addr, 8485 rGPR:$Rm, pred:$p)>; 8486def VLD4DUPqWB_register_Asm_16 : 8487 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 8488 (ins VecListFourQAllLanes:$list, addrmode6dupalign64:$addr, 8489 rGPR:$Rm, pred:$p)>; 8490def VLD4DUPqWB_register_Asm_32 : 8491 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 8492 (ins VecListFourQAllLanes:$list, 8493 addrmode6dupalign64or128:$addr, rGPR:$Rm, pred:$p)>; 8494 8495 8496// VLD4 single-lane pseudo-instructions. These need special handling for 8497// the lane index that an InstAlias can't handle, so we use these instead. 8498def VLD4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 8499 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr, 8500 pred:$p)>; 8501def VLD4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 8502 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr, 8503 pred:$p)>; 8504def VLD4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 8505 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr, 8506 pred:$p)>; 8507def VLD4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 8508 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr, 8509 pred:$p)>; 8510def VLD4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 8511 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr, 8512 pred:$p)>; 8513 8514def VLD4LNdWB_fixed_Asm_8 : 8515 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 8516 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr, 8517 pred:$p)>; 8518def VLD4LNdWB_fixed_Asm_16 : 8519 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 8520 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr, 8521 pred:$p)>; 8522def VLD4LNdWB_fixed_Asm_32 : 8523 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 8524 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr, 8525 pred:$p)>; 8526def VLD4LNqWB_fixed_Asm_16 : 8527 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 8528 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr, 8529 pred:$p)>; 8530def VLD4LNqWB_fixed_Asm_32 : 8531 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 8532 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr, 8533 pred:$p)>; 8534def VLD4LNdWB_register_Asm_8 : 8535 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 8536 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr, 8537 rGPR:$Rm, pred:$p)>; 8538def VLD4LNdWB_register_Asm_16 : 8539 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 8540 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr, 8541 rGPR:$Rm, pred:$p)>; 8542def VLD4LNdWB_register_Asm_32 : 8543 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 8544 (ins VecListFourDWordIndexed:$list, 8545 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>; 8546def VLD4LNqWB_register_Asm_16 : 8547 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 8548 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr, 8549 rGPR:$Rm, pred:$p)>; 8550def VLD4LNqWB_register_Asm_32 : 8551 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 8552 (ins VecListFourQWordIndexed:$list, 8553 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>; 8554 8555 8556 8557// VLD4 multiple structure pseudo-instructions. These need special handling for 8558// the vector operands that the normal instructions don't yet model. 8559// FIXME: Remove these when the register classes and instructions are updated. 8560def VLD4dAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 8561 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8562 pred:$p)>; 8563def VLD4dAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 8564 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8565 pred:$p)>; 8566def VLD4dAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 8567 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8568 pred:$p)>; 8569def VLD4qAsm_8 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr", 8570 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8571 pred:$p)>; 8572def VLD4qAsm_16 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr", 8573 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8574 pred:$p)>; 8575def VLD4qAsm_32 : NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr", 8576 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8577 pred:$p)>; 8578 8579def VLD4dWB_fixed_Asm_8 : 8580 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 8581 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8582 pred:$p)>; 8583def VLD4dWB_fixed_Asm_16 : 8584 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 8585 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8586 pred:$p)>; 8587def VLD4dWB_fixed_Asm_32 : 8588 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 8589 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8590 pred:$p)>; 8591def VLD4qWB_fixed_Asm_8 : 8592 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr!", 8593 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8594 pred:$p)>; 8595def VLD4qWB_fixed_Asm_16 : 8596 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr!", 8597 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8598 pred:$p)>; 8599def VLD4qWB_fixed_Asm_32 : 8600 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr!", 8601 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8602 pred:$p)>; 8603def VLD4dWB_register_Asm_8 : 8604 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 8605 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8606 rGPR:$Rm, pred:$p)>; 8607def VLD4dWB_register_Asm_16 : 8608 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 8609 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8610 rGPR:$Rm, pred:$p)>; 8611def VLD4dWB_register_Asm_32 : 8612 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 8613 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8614 rGPR:$Rm, pred:$p)>; 8615def VLD4qWB_register_Asm_8 : 8616 NEONDataTypeAsmPseudoInst<"vld4${p}", ".8", "$list, $addr, $Rm", 8617 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8618 rGPR:$Rm, pred:$p)>; 8619def VLD4qWB_register_Asm_16 : 8620 NEONDataTypeAsmPseudoInst<"vld4${p}", ".16", "$list, $addr, $Rm", 8621 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8622 rGPR:$Rm, pred:$p)>; 8623def VLD4qWB_register_Asm_32 : 8624 NEONDataTypeAsmPseudoInst<"vld4${p}", ".32", "$list, $addr, $Rm", 8625 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8626 rGPR:$Rm, pred:$p)>; 8627 8628// VST4 single-lane pseudo-instructions. These need special handling for 8629// the lane index that an InstAlias can't handle, so we use these instead. 8630def VST4LNdAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr", 8631 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr, 8632 pred:$p)>; 8633def VST4LNdAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 8634 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr, 8635 pred:$p)>; 8636def VST4LNdAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 8637 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr, 8638 pred:$p)>; 8639def VST4LNqAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 8640 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr, 8641 pred:$p)>; 8642def VST4LNqAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 8643 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr, 8644 pred:$p)>; 8645 8646def VST4LNdWB_fixed_Asm_8 : 8647 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!", 8648 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr, 8649 pred:$p)>; 8650def VST4LNdWB_fixed_Asm_16 : 8651 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 8652 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr, 8653 pred:$p)>; 8654def VST4LNdWB_fixed_Asm_32 : 8655 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 8656 (ins VecListFourDWordIndexed:$list, addrmode6align64or128:$addr, 8657 pred:$p)>; 8658def VST4LNqWB_fixed_Asm_16 : 8659 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 8660 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr, 8661 pred:$p)>; 8662def VST4LNqWB_fixed_Asm_32 : 8663 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 8664 (ins VecListFourQWordIndexed:$list, addrmode6align64or128:$addr, 8665 pred:$p)>; 8666def VST4LNdWB_register_Asm_8 : 8667 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm", 8668 (ins VecListFourDByteIndexed:$list, addrmode6align32:$addr, 8669 rGPR:$Rm, pred:$p)>; 8670def VST4LNdWB_register_Asm_16 : 8671 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 8672 (ins VecListFourDHWordIndexed:$list, addrmode6align64:$addr, 8673 rGPR:$Rm, pred:$p)>; 8674def VST4LNdWB_register_Asm_32 : 8675 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 8676 (ins VecListFourDWordIndexed:$list, 8677 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>; 8678def VST4LNqWB_register_Asm_16 : 8679 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 8680 (ins VecListFourQHWordIndexed:$list, addrmode6align64:$addr, 8681 rGPR:$Rm, pred:$p)>; 8682def VST4LNqWB_register_Asm_32 : 8683 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 8684 (ins VecListFourQWordIndexed:$list, 8685 addrmode6align64or128:$addr, rGPR:$Rm, pred:$p)>; 8686 8687 8688// VST4 multiple structure pseudo-instructions. These need special handling for 8689// the vector operands that the normal instructions don't yet model. 8690// FIXME: Remove these when the register classes and instructions are updated. 8691def VST4dAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr", 8692 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8693 pred:$p)>; 8694def VST4dAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 8695 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8696 pred:$p)>; 8697def VST4dAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 8698 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8699 pred:$p)>; 8700def VST4qAsm_8 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr", 8701 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8702 pred:$p)>; 8703def VST4qAsm_16 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr", 8704 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8705 pred:$p)>; 8706def VST4qAsm_32 : NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr", 8707 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8708 pred:$p)>; 8709 8710def VST4dWB_fixed_Asm_8 : 8711 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!", 8712 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8713 pred:$p)>; 8714def VST4dWB_fixed_Asm_16 : 8715 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 8716 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8717 pred:$p)>; 8718def VST4dWB_fixed_Asm_32 : 8719 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 8720 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8721 pred:$p)>; 8722def VST4qWB_fixed_Asm_8 : 8723 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr!", 8724 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8725 pred:$p)>; 8726def VST4qWB_fixed_Asm_16 : 8727 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr!", 8728 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8729 pred:$p)>; 8730def VST4qWB_fixed_Asm_32 : 8731 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr!", 8732 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8733 pred:$p)>; 8734def VST4dWB_register_Asm_8 : 8735 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm", 8736 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8737 rGPR:$Rm, pred:$p)>; 8738def VST4dWB_register_Asm_16 : 8739 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 8740 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8741 rGPR:$Rm, pred:$p)>; 8742def VST4dWB_register_Asm_32 : 8743 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 8744 (ins VecListFourD:$list, addrmode6align64or128or256:$addr, 8745 rGPR:$Rm, pred:$p)>; 8746def VST4qWB_register_Asm_8 : 8747 NEONDataTypeAsmPseudoInst<"vst4${p}", ".8", "$list, $addr, $Rm", 8748 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8749 rGPR:$Rm, pred:$p)>; 8750def VST4qWB_register_Asm_16 : 8751 NEONDataTypeAsmPseudoInst<"vst4${p}", ".16", "$list, $addr, $Rm", 8752 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8753 rGPR:$Rm, pred:$p)>; 8754def VST4qWB_register_Asm_32 : 8755 NEONDataTypeAsmPseudoInst<"vst4${p}", ".32", "$list, $addr, $Rm", 8756 (ins VecListFourQ:$list, addrmode6align64or128or256:$addr, 8757 rGPR:$Rm, pred:$p)>; 8758 8759// VMOV/VMVN takes an optional datatype suffix 8760defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm", 8761 (VORRd DPR:$Vd, DPR:$Vm, DPR:$Vm, pred:$p)>; 8762defm : NEONDTAnyInstAlias<"vmov${p}", "$Vd, $Vm", 8763 (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>; 8764 8765defm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm", 8766 (VMVNd DPR:$Vd, DPR:$Vm, pred:$p)>; 8767defm : NEONDTAnyInstAlias<"vmvn${p}", "$Vd, $Vm", 8768 (VMVNq QPR:$Vd, QPR:$Vm, pred:$p)>; 8769 8770// VCLT (register) is an assembler alias for VCGT w/ the operands reversed. 8771// D-register versions. 8772def : NEONInstAlias<"vcle${p}.s8 $Dd, $Dn, $Dm", 8773 (VCGEsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8774def : NEONInstAlias<"vcle${p}.s16 $Dd, $Dn, $Dm", 8775 (VCGEsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8776def : NEONInstAlias<"vcle${p}.s32 $Dd, $Dn, $Dm", 8777 (VCGEsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8778def : NEONInstAlias<"vcle${p}.u8 $Dd, $Dn, $Dm", 8779 (VCGEuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8780def : NEONInstAlias<"vcle${p}.u16 $Dd, $Dn, $Dm", 8781 (VCGEuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8782def : NEONInstAlias<"vcle${p}.u32 $Dd, $Dn, $Dm", 8783 (VCGEuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8784def : NEONInstAlias<"vcle${p}.f32 $Dd, $Dn, $Dm", 8785 (VCGEfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8786let Predicates = [HasNEON, HasFullFP16] in 8787def : NEONInstAlias<"vcle${p}.f16 $Dd, $Dn, $Dm", 8788 (VCGEhd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8789// Q-register versions. 8790def : NEONInstAlias<"vcle${p}.s8 $Qd, $Qn, $Qm", 8791 (VCGEsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8792def : NEONInstAlias<"vcle${p}.s16 $Qd, $Qn, $Qm", 8793 (VCGEsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8794def : NEONInstAlias<"vcle${p}.s32 $Qd, $Qn, $Qm", 8795 (VCGEsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8796def : NEONInstAlias<"vcle${p}.u8 $Qd, $Qn, $Qm", 8797 (VCGEuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8798def : NEONInstAlias<"vcle${p}.u16 $Qd, $Qn, $Qm", 8799 (VCGEuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8800def : NEONInstAlias<"vcle${p}.u32 $Qd, $Qn, $Qm", 8801 (VCGEuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8802def : NEONInstAlias<"vcle${p}.f32 $Qd, $Qn, $Qm", 8803 (VCGEfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8804let Predicates = [HasNEON, HasFullFP16] in 8805def : NEONInstAlias<"vcle${p}.f16 $Qd, $Qn, $Qm", 8806 (VCGEhq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8807 8808// VCLT (register) is an assembler alias for VCGT w/ the operands reversed. 8809// D-register versions. 8810def : NEONInstAlias<"vclt${p}.s8 $Dd, $Dn, $Dm", 8811 (VCGTsv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8812def : NEONInstAlias<"vclt${p}.s16 $Dd, $Dn, $Dm", 8813 (VCGTsv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8814def : NEONInstAlias<"vclt${p}.s32 $Dd, $Dn, $Dm", 8815 (VCGTsv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8816def : NEONInstAlias<"vclt${p}.u8 $Dd, $Dn, $Dm", 8817 (VCGTuv8i8 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8818def : NEONInstAlias<"vclt${p}.u16 $Dd, $Dn, $Dm", 8819 (VCGTuv4i16 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8820def : NEONInstAlias<"vclt${p}.u32 $Dd, $Dn, $Dm", 8821 (VCGTuv2i32 DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8822def : NEONInstAlias<"vclt${p}.f32 $Dd, $Dn, $Dm", 8823 (VCGTfd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8824let Predicates = [HasNEON, HasFullFP16] in 8825def : NEONInstAlias<"vclt${p}.f16 $Dd, $Dn, $Dm", 8826 (VCGThd DPR:$Dd, DPR:$Dm, DPR:$Dn, pred:$p)>; 8827// Q-register versions. 8828def : NEONInstAlias<"vclt${p}.s8 $Qd, $Qn, $Qm", 8829 (VCGTsv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8830def : NEONInstAlias<"vclt${p}.s16 $Qd, $Qn, $Qm", 8831 (VCGTsv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8832def : NEONInstAlias<"vclt${p}.s32 $Qd, $Qn, $Qm", 8833 (VCGTsv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8834def : NEONInstAlias<"vclt${p}.u8 $Qd, $Qn, $Qm", 8835 (VCGTuv16i8 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8836def : NEONInstAlias<"vclt${p}.u16 $Qd, $Qn, $Qm", 8837 (VCGTuv8i16 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8838def : NEONInstAlias<"vclt${p}.u32 $Qd, $Qn, $Qm", 8839 (VCGTuv4i32 QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8840def : NEONInstAlias<"vclt${p}.f32 $Qd, $Qn, $Qm", 8841 (VCGTfq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8842let Predicates = [HasNEON, HasFullFP16] in 8843def : NEONInstAlias<"vclt${p}.f16 $Qd, $Qn, $Qm", 8844 (VCGThq QPR:$Qd, QPR:$Qm, QPR:$Qn, pred:$p)>; 8845 8846// VSWP allows, but does not require, a type suffix. 8847defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm", 8848 (VSWPd DPR:$Vd, DPR:$Vm, pred:$p)>; 8849defm : NEONDTAnyInstAlias<"vswp${p}", "$Vd, $Vm", 8850 (VSWPq QPR:$Vd, QPR:$Vm, pred:$p)>; 8851 8852// VBIF, VBIT, and VBSL allow, but do not require, a type suffix. 8853defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm", 8854 (VBIFd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 8855defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm", 8856 (VBITd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 8857defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm", 8858 (VBSLd DPR:$Vd, DPR:$Vn, DPR:$Vm, pred:$p)>; 8859defm : NEONDTAnyInstAlias<"vbif${p}", "$Vd, $Vn, $Vm", 8860 (VBIFq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 8861defm : NEONDTAnyInstAlias<"vbit${p}", "$Vd, $Vn, $Vm", 8862 (VBITq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 8863defm : NEONDTAnyInstAlias<"vbsl${p}", "$Vd, $Vn, $Vm", 8864 (VBSLq QPR:$Vd, QPR:$Vn, QPR:$Vm, pred:$p)>; 8865 8866// "vmov Rd, #-imm" can be handled via "vmvn". 8867def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm", 8868 (VMVNv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 8869def : NEONInstAlias<"vmov${p}.i32 $Vd, $imm", 8870 (VMVNv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 8871def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm", 8872 (VMOVv2i32 DPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 8873def : NEONInstAlias<"vmvn${p}.i32 $Vd, $imm", 8874 (VMOVv4i32 QPR:$Vd, nImmVMOVI32Neg:$imm, pred:$p)>; 8875 8876// 'gas' compatibility aliases for quad-word instructions. Strictly speaking, 8877// these should restrict to just the Q register variants, but the register 8878// classes are enough to match correctly regardless, so we keep it simple 8879// and just use MnemonicAlias. 8880def : NEONMnemonicAlias<"vbicq", "vbic">; 8881def : NEONMnemonicAlias<"vandq", "vand">; 8882def : NEONMnemonicAlias<"veorq", "veor">; 8883def : NEONMnemonicAlias<"vorrq", "vorr">; 8884 8885def : NEONMnemonicAlias<"vmovq", "vmov">; 8886def : NEONMnemonicAlias<"vmvnq", "vmvn">; 8887// Explicit versions for floating point so that the FPImm variants get 8888// handled early. The parser gets confused otherwise. 8889def : NEONMnemonicAlias<"vmovq.f32", "vmov.f32">; 8890def : NEONMnemonicAlias<"vmovq.f64", "vmov.f64">; 8891 8892def : NEONMnemonicAlias<"vaddq", "vadd">; 8893def : NEONMnemonicAlias<"vsubq", "vsub">; 8894 8895def : NEONMnemonicAlias<"vminq", "vmin">; 8896def : NEONMnemonicAlias<"vmaxq", "vmax">; 8897 8898def : NEONMnemonicAlias<"vmulq", "vmul">; 8899 8900def : NEONMnemonicAlias<"vabsq", "vabs">; 8901 8902def : NEONMnemonicAlias<"vshlq", "vshl">; 8903def : NEONMnemonicAlias<"vshrq", "vshr">; 8904 8905def : NEONMnemonicAlias<"vcvtq", "vcvt">; 8906 8907def : NEONMnemonicAlias<"vcleq", "vcle">; 8908def : NEONMnemonicAlias<"vceqq", "vceq">; 8909 8910def : NEONMnemonicAlias<"vzipq", "vzip">; 8911def : NEONMnemonicAlias<"vswpq", "vswp">; 8912 8913def : NEONMnemonicAlias<"vrecpeq.f32", "vrecpe.f32">; 8914def : NEONMnemonicAlias<"vrecpeq.u32", "vrecpe.u32">; 8915 8916 8917// Alias for loading floating point immediates that aren't representable 8918// using the vmov.f32 encoding but the bitpattern is representable using 8919// the .i32 encoding. 8920def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm", 8921 (VMOVv4i32 QPR:$Vd, nImmVMOVI32:$imm, pred:$p)>; 8922def : NEONInstAlias<"vmov${p}.f32 $Vd, $imm", 8923 (VMOVv2i32 DPR:$Vd, nImmVMOVI32:$imm, pred:$p)>; 8924 8925// ARMv8.6a BFloat16 instructions. 8926let Predicates = [HasBF16, HasNEON] in { 8927class BF16VDOT<bits<5> op27_23, bits<2> op21_20, bit op6, 8928 dag oops, dag iops> 8929 : N3Vnp<op27_23, op21_20, 0b1101, op6, 0, oops, iops, 8930 N3RegFrm, IIC_VDOTPROD, "", "", []> { 8931 let hasNoSchedulingInfo = 1; 8932 let DecoderNamespace = "VFPV8"; 8933} 8934 8935class BF16VDOTS<bit Q, RegisterClass RegTy, string opc, ValueType AccumTy, ValueType InputTy> 8936 : BF16VDOT<0b11000, 0b00, Q, (outs RegTy:$dst), 8937 (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm)> { 8938 let Constraints = "$dst = $Vd"; 8939 let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm"); 8940 let DecoderNamespace = "VFPV8"; 8941} 8942 8943multiclass BF16VDOTI<bit Q, RegisterClass RegTy, string opc, ValueType AccumTy, 8944 ValueType InputTy, dag RHS> { 8945 8946 def "" : BF16VDOT<0b11100, 0b00, Q, (outs RegTy:$dst), 8947 (ins RegTy:$Vd, RegTy:$Vn, 8948 DPR_VFP2:$Vm, VectorIndex32:$lane)> { 8949 bit lane; 8950 let Inst{5} = lane; 8951 let Constraints = "$dst = $Vd"; 8952 let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm$lane"); 8953 let DecoderNamespace = "VFPV8"; 8954 } 8955 8956} 8957 8958def BF16VDOTS_VDOTD : BF16VDOTS<0, DPR, "vdot", v2f32, v8i8>; 8959def BF16VDOTS_VDOTQ : BF16VDOTS<1, QPR, "vdot", v4f32, v16i8>; 8960 8961defm BF16VDOTI_VDOTD : BF16VDOTI<0, DPR, "vdot", v2f32, v8i8, (v2f32 DPR_VFP2:$Vm)>; 8962defm BF16VDOTI_VDOTQ : BF16VDOTI<1, QPR, "vdot", v4f32, v16i8, (EXTRACT_SUBREG QPR:$Vm, dsub_0)>; 8963 8964class BF16MM<bit Q, RegisterClass RegTy, 8965 string opc> 8966 : N3Vnp<0b11000, 0b00, 0b1100, Q, 0, 8967 (outs RegTy:$dst), (ins RegTy:$Vd, RegTy:$Vn, RegTy:$Vm), 8968 N3RegFrm, IIC_VDOTPROD, "", "", []> { 8969 let Constraints = "$dst = $Vd"; 8970 let AsmString = !strconcat(opc, ".bf16", "\t$Vd, $Vn, $Vm"); 8971 let DecoderNamespace = "VFPV8"; 8972 let hasNoSchedulingInfo = 1; 8973} 8974 8975def VMMLA : BF16MM<1, QPR, "vmmla">; 8976 8977class VBF16MALQ<bit T, string suffix> 8978 : N3VCP8<0b00, 0b11, T, 1, 8979 (outs QPR:$dst), (ins QPR:$Vd, QPR:$Vn, QPR:$Vm), 8980 NoItinerary, "vfma" # suffix, "bf16", "$Vd, $Vn, $Vm", "", 8981 []> { // TODO: Add intrinsics 8982 let Constraints = "$dst = $Vd"; 8983 let DecoderNamespace = "VFPV8"; 8984 let hasNoSchedulingInfo = 1; 8985} 8986 8987def VBF16MALTQ: VBF16MALQ<1, "t">; 8988def VBF16MALBQ: VBF16MALQ<0, "b">; 8989 8990multiclass VBF16MALQI<bit T, string suffix> { 8991 def "" : N3VLaneCP8<0, 0b11, T, 1, (outs QPR:$dst), 8992 (ins QPR:$Vd, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx), 8993 IIC_VMACD, "vfma" # suffix, "bf16", "$Vd, $Vn, $Vm$idx", "", []> { 8994 bits<2> idx; 8995 let Inst{5} = idx{1}; 8996 let Inst{3} = idx{0}; 8997 let Constraints = "$dst = $Vd"; 8998 let DecoderNamespace = "VFPV8"; 8999 let hasNoSchedulingInfo = 1; 9000 } 9001 9002} 9003 9004defm VBF16MALTQI: VBF16MALQI<1, "t">; 9005defm VBF16MALBQI: VBF16MALQI<0, "b">; 9006 9007let hasNoSchedulingInfo = 1 in { 9008def BF16_VCVT : N2V<0b11, 0b11, 0b01, 0b10, 0b01100, 1, 0, 9009 (outs DPR:$Vd), (ins QPR:$Vm), 9010 NoItinerary, "vcvt", "bf16.f32", "$Vd, $Vm", "", []>; 9011} 9012} 9013// End of BFloat16 instructions 9014